Skip to content

Register a signed deployment

POST
/v1/deployments
curl --request POST \
--url https://example.com/v1/deployments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "imageRef": "example", "artifactVersion": "example", "indexHash": "example", "signerKeyId": "example", "signerPublicKey": "example", "signature": "example", "publishedAt": "2026-04-15T12:00:00Z" }'

Atomic transaction: check the signing key against the tenant’s trust list (the signingKeyRegistry binding), verify the Ed25519 signature over the canonical envelope, read the image’s /app/index.json and verify it hashes to the signed indexHash and names the signed artifactVersion (ImageRegistryBinding), validate every tool / guardrail / agent / flow it declares (the image’s index is what registers; the request carries none), upsert into the corresponding registries, then record the deployment. All-or-nothing rollback on any failure. Idempotency: same imageDigest re-submitted returns 200 with the existing record (no new version bump). Idempotency-Key also applies at the HTTP layer.

Idempotency-Key
string
>= 1 characters

Caller-supplied idempotency key. Retries with the same key return the original response byte-identical (per docs/API-ROUTE-CONVENTIONS.md §3.1).

Media typeapplication/json
object
imageRef
required

Full digest-pinned OCI reference: <host>/<repo>@sha256:<hex>.

string
artifactVersion
required

Issuer-generated YYYYMMDD.N — covered by the signature.

string
/^\d{8}\.\d+$/
indexHash
required

Sha256 of the image’s /app/index.json, byte for byte — covered by the signature. The server reads the file from the image, checks it hashes to this, and registers what it declares.

string
/^sha256:[0-9a-f]{64}$/
signerKeyId
required
string
>= 1 characters
signerPublicKey
required

PEM-encoded Ed25519 public key (-----BEGIN PUBLIC KEY-----\n…). Parsed to raw bytes for verification.

string
signature
required

Base64 of the Ed25519 signature over canonicalise({ imageDigest, artifactVersion, indexHash, tenantId, publishedAt }) with sorted keys, no whitespace, UTF-8.

string
publishedAt
required

Issuer-supplied ISO-8601 timestamp — covered by the signature.

string format: date-time
Examplegenerated
{
"imageRef": "example",
"artifactVersion": "example",
"indexHash": "example",
"signerKeyId": "example",
"signerPublicKey": "example",
"signature": "example",
"publishedAt": "2026-04-15T12:00:00Z"
}

Digest replay — same imageDigest already recorded; returns existing record.

Media typeapplication/json
object
deploymentId
required
string
>= 1 characters
tenantId
required
string format: uuid
imageRef
required

Full digest-pinned OCI reference: <host>/<repo>@sha256:<hex>.

string
imageDigest
required

Idempotency key. Extracted from imageRef after the @.

string
/^sha256:[0-9a-f]{64}$/
artifactVersion
required

Issuer-supplied YYYYMMDD.N — matches what was signed.

string
/^\d{8}\.\d+$/
indexHash
required

Sha256 of the canonicalised /app/index.json inside the image.

string
/^sha256:[0-9a-f]{64}$/
signerKeyId
required
string
>= 1 characters
signerPublicKey
required

Base64 of the raw Ed25519 public key bytes (32 bytes → 44 chars).

string
signature
required

Base64 of the raw Ed25519 signature (64 bytes → 88 chars).

string
publishedAt
required

Issuer-supplied timestamp inside the signed envelope.

string format: date-time
activatedAt
required

Server-side ledger timestamp — when the register call succeeded.

string format: date-time
primitives
required
object
tools
required
integer
guardrails
required
integer
agents
required
integer
flows
required
integer
contents
required
object
tools
required
Array<object>
object
id
required
string
version

Absent for guardrails, which have no version.

string
guardrails
required
Array<object>
object
id
required
string
version

Absent for guardrails, which have no version.

string
agents
required
Array<object>
object
id
required
string
version

Absent for guardrails, which have no version.

string
flows
required
Array<object>
object
id
required
string
version

Absent for guardrails, which have no version.

string
Examplegenerated
{
"deploymentId": "example",
"tenantId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"imageRef": "example",
"imageDigest": "example",
"artifactVersion": "example",
"indexHash": "example",
"signerKeyId": "example",
"signerPublicKey": "example",
"signature": "example",
"publishedAt": "2026-04-15T12:00:00Z",
"activatedAt": "2026-04-15T12:00:00Z",
"primitives": {
"tools": 1,
"guardrails": 1,
"agents": 1,
"flows": 1
},
"contents": {
"tools": [
{
"id": "example",
"version": "example"
}
],
"guardrails": [
{
"id": "example",
"version": "example"
}
],
"agents": [
{
"id": "example",
"version": "example"
}
],
"flows": [
{
"id": "example",
"version": "example"
}
]
}
}

Deployment registered.

Media typeapplication/json
object
deploymentId
required
string
>= 1 characters
tenantId
required
string format: uuid
imageRef
required

Full digest-pinned OCI reference: <host>/<repo>@sha256:<hex>.

string
imageDigest
required

Idempotency key. Extracted from imageRef after the @.

string
/^sha256:[0-9a-f]{64}$/
artifactVersion
required

Issuer-supplied YYYYMMDD.N — matches what was signed.

string
/^\d{8}\.\d+$/
indexHash
required

Sha256 of the canonicalised /app/index.json inside the image.

string
/^sha256:[0-9a-f]{64}$/
signerKeyId
required
string
>= 1 characters
signerPublicKey
required

Base64 of the raw Ed25519 public key bytes (32 bytes → 44 chars).

string
signature
required

Base64 of the raw Ed25519 signature (64 bytes → 88 chars).

string
publishedAt
required

Issuer-supplied timestamp inside the signed envelope.

string format: date-time
activatedAt
required

Server-side ledger timestamp — when the register call succeeded.

string format: date-time
primitives
required
object
tools
required
integer
guardrails
required
integer
agents
required
integer
flows
required
integer
contents
required
object
tools
required
Array<object>
object
id
required
string
version

Absent for guardrails, which have no version.

string
guardrails
required
Array<object>
object
id
required
string
version

Absent for guardrails, which have no version.

string
agents
required
Array<object>
object
id
required
string
version

Absent for guardrails, which have no version.

string
flows
required
Array<object>
object
id
required
string
version

Absent for guardrails, which have no version.

string
Examplegenerated
{
"deploymentId": "example",
"tenantId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"imageRef": "example",
"imageDigest": "example",
"artifactVersion": "example",
"indexHash": "example",
"signerKeyId": "example",
"signerPublicKey": "example",
"signature": "example",
"publishedAt": "2026-04-15T12:00:00Z",
"activatedAt": "2026-04-15T12:00:00Z",
"primitives": {
"tools": 1,
"guardrails": 1,
"agents": 1,
"flows": 1
},
"contents": {
"tools": [
{
"id": "example",
"version": "example"
}
],
"guardrails": [
{
"id": "example",
"version": "example"
}
],
"agents": [
{
"id": "example",
"version": "example"
}
],
"flows": [
{
"id": "example",
"version": "example"
}
]
}
}

Signature invalid, image unverifiable, or deployment-validation-failed with per-primitive details[].

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

Missing / malformed / expired / revoked bearer token.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

Signer key not on the tenant’s trust list.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

Idempotency-Key was reused with a different body, or resource-state conflict.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

Server error (unmapped domain code or framework crash).

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}