Create an owner-bound ephemeral deployment from an allowlisted image digest.
Action API
The browser pages are read-only documentation. Compute and artifact mutations use the paid, signature-bound action API. Non-secret config metadata uses a separate free, owner-authenticated API.
Quickstart: sign, prepare, quote, pay, execute, reconcile
Use your own signer and verify the exact network, asset, amount and bound action before authorizing payment. Never place signing keys or payment material in a browser page.
- Sign the server-provided preparation digest with EIP-191.
- Prepare with
POST /v1/actionsand retain its immutable action ID and digest. - For lease actions, obtain and validate the signed quote before approving the amount; for ordinary actions validate the execute payment challenge.
- Approve the exact x402 requirement and provide
PAYMENT-SIGNATUREonly on execute, never on quote or read routes. - Execute with the fresh method/path-bound action signature and the same idempotency key.
- Read the action and receipts; reconcile unknown settlement before retrying, never pay twice for an unresolved action.
Live action prices
Each execution settles separately in native USDC on Base mainnet (eip155:8453).
Invoke an existing deployment owned by the signing account.
Delete an existing deployment owned by the signing account.
Paid action handshake
- Unsigned preparation request: send
POST /v1/actionswith the JSON body and a cryptographically randomIdempotency-Key. The API responds401 UnauthorizedwithCYNDER-ACTION-DIGEST. - Sign that digest using EIP-191. Retry the identical JSON body and Idempotency-Key with
CYNDER-ACTION-SIGNATURE. Preserve the returned immutable action ID and digest. - Compute a fresh execute signing digest binding the actual method/path, control origin, action type, original idempotency key and immutable action digest. EIP-191 personal-sign the 32 decoded digest bytes, not the immutable action digest alone or its hex text; send
POST /v1/actions/{actionID}/executewith an empty body andCYNDER-ACTION-SIGNATURE. The unpaid request responds402 Payment RequiredwithPAYMENT-REQUIRED. - Validate the Base-mainnet USDC requirement, create the x402 payment authorization, and Retry the same execute request with both
CYNDER-ACTION-SIGNATUREandPAYMENT-SIGNATURE. - Read the persisted action state and receipts using the owner signature. Preparation and execution signatures bind the method, normalized path, control origin, idempotency key, and digest shown by the server.
Action types are DEPLOY, DEPLOY_VERSION, ROLLBACK_VERSION, ENROLL_WALLET, INVOKE, DELETE, REGISTER_ARTIFACT, RETAIN_ARTIFACT, ACQUIRE_LEASE, RENEW_LEASE, and RESIZE_LEASE. Lease actions use dynamic quote prices and require configured policy, installed enforcement and fresh request-specific admission. Disabled policy remains fail-closed; query the owner policy endpoint for installed capabilities. Enrollment is an API review workflow and is not shown as public workload activity. DEPLOY_VERSION, ROLLBACK_VERSION, ENROLL_WALLET, REGISTER_ARTIFACT, and RETAIN_ARTIFACT all use the deploy-class price. Prices above come from the same live x402 configuration used to authorize execution.
Free non-secret config versions
The machine API documents 41 operations across 37 paths. Config metadata is owner-private, free and separate from x402. Never submit secrets. There is no update, delete, name, tag, latest or current alias.
Create or replay an immutable version (201): {"env":{"APP_MODE":"production"}}.
List active and revoked owner records in opaque-ID order, without pagination (200). Empty result: {"configs":[]}.
Read the current owner-private record (200).
Irreversibly revoke using {} (200); repeated revocation preserves revoked_at.
Extend or equal the deadline with {"retain_until":"2030-01-01T00:00:00Z"} (200). Shortening conflicts; retention never reactivates revoked content or automatically deletes expired records.
Every config request requires exactly one CYNDER-ACTION-SIGNATURE and matching public CYNDER-CONFIG-ADDRESS. POST additionally requires application/json and one Idempotency-Key; GET has no body or key. Query parameters and encoded paths are rejected. Owner is derived from the signer, not accepted from the body. No signing challenge is returned.
Compute SHA-256 over the concatenated UTF-8 byte-length-prefixed parts (decimal byte length, colon, value): cynder-action-signing-v1, normalized control origin, uppercase method, exact path, CONFIG, idempotency key (empty for GET), and lowercase unprefixed SHA-256 hex of the exact body (empty bytes for GET). EIP-191 personal-sign the 32 decoded digest bytes, not hex text. Origin normalization lowercases scheme/host and removes the root slash.
Limits: 128 keys matching [A-Za-z_][A-Za-z0-9_]*, 128 UTF-8 bytes/key, 8192 bytes/value, 65536 total decoded key-plus-value bytes and 524288 raw body bytes. Values are non-secret strings. Duplicate/unknown fields, nulls, invalid UTF-8, Unicode controls, replacement characters and trailing JSON are rejected. Empty env is valid. Idempotency keys are 1–128 UTF-8 bytes with no surrounding whitespace or controls.
Content digest is sha256: plus SHA-256 of Go compact JSON for env, sorted keys, HTML escaping enabled, no trailing newline. It is distinct from the raw-body signing digest. Config mutations share one owner-scoped idempotency namespace. Replay returns the original snapshot; GET reads current state. ConfigVersion includes id, owner_id, env, digest, active/revoked state, created_at, retain_until, original creation idempotency_key and revoked_at only when revoked. Retain timestamps use RFC3339 with optional nanoseconds, UTC normalization and year 1970–9999.
Create and retain, including replays, require ACTIVE wallet enrollment with x402 activation and deploy scope (403 wallet_enrollment_required otherwise). Reads and owned revocation do not require active enrollment; ownership is checked before mutation replay. Store-wide lifetime ceilings are 256 versions and 1024 ordinary replay results. One active-to-revoked transition per existing version may exceed ordinary capacity, with at most 1280 total results (ConfigMaxReplays+ConfigMaxVersions). New-key no-op revocations cannot use this reserve; exact replays consume no capacity. No automatic reclamation occurs.
Invalid requests return 400, missing/invalid authentication 401 without a digest challenge, unknown/cross-owner IDs identical 404, idempotency/lifecycle conflicts or exhausted capacity (config_capacity) 409, oversized bodies 413, wrong media type 415, and storage errors 500. Responses are private/no-store. Config values, IDs and private ownership never appear in public Explorer/search/SSE.
Creating a config version alone does not change a workload. Bind immutable configs and secrets references in a signed DEPLOY or complete DEPLOY_VERSION inputs snapshot. The runtime resolves those references into exact immutable ConfigMaps and Secrets for the pinned revision, supporting both env and envFrom bindings. Paid action bodies never accept inline config_id, env or secret values. The store resolver rejects revoked/absent IDs; only the explicit internal cfg_legacy_empty_v1 yields immutable empty compatibility data. It is not listed, returns 404 on owner GET and 409 on mutation. Revocation does not stop existing workloads. See OpenAPI for the full contract.
Owner-private workload secrets
Workload-secret create, list, read, rotate, revoke and delete operations are free owner-authenticated metadata/custody operations, not paid actions. Values are write-only and never returned in owner reads or public Explorer. These routes use their own signing contract, not the config signature or an x402 payment. See the workload-secret operations for exact headers, body hashing, lifecycle and error rules. Do not place secrets in config metadata, public descriptions or Explorer search.
Request shapes
DEPLOY {"type":"DEPLOY","image_digest":"repo/image@sha256:<64-lowercase-hex>","resource_class":"mvi-small","timeout_seconds":30,"name":"Example service","description":"Processes one JSON request.","tags":["example"]}
DEPLOY_VERSION {"type":"DEPLOY_VERSION","deployment_id":"dep_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","image_digest":"registry.example/workload@sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","source_tag":"registry.example/workload:v2","timeout_seconds":30,"inputs":{"configs":[],"secrets":[],"policy":{"version":"mvi-v1","digest":"sha256:9938ca40c4513a10290de1c0bc9a8224fbd89720114c29ccab1e9b20043f825f","resource_class":"mvi-small","cpu":"500m","memory":"512Mi","ephemeral_storage":"1Gi","min_scale":0,"max_scale":2,"concurrency":1,"timeout_seconds":300,"runtime_class":""},"http":{"public":false,"port":8080,"public_hostname":""},"routes":[],"health":{"readiness_path":"/health","liveness_path":"/health"}}}
ROLLBACK_VERSION {"type":"ROLLBACK_VERSION","deployment_id":"dep_<32-hex>","version_id":"ver_<32-hex>","timeout_seconds":30}
ENROLL_WALLET {"type":"ENROLL_WALLET","profile_name":"build-agent","terms_accepted":true,"requested_scopes":["deploy","invoke","artifact"]}
INVOKE {"type":"INVOKE","deployment_id":"dep_<32-hex>","input":{"message":"hello"},"timeout_seconds":30}
DELETE {"type":"DELETE","deployment_id":"dep_<32-hex>"}
REGISTER_ARTIFACT {"type":"REGISTER_ARTIFACT","repository":"tenant/workload","reference":"release-2026-09"}
RETAIN_ARTIFACT {"type":"RETAIN_ARTIFACT","repository":"tenant/workload","digest":"sha256:<64-lowercase-hex>","retention_seconds":86400}Product workflows
Implemented code, configured policy, installed enforcement, request eligibility, payment settlement, committed activation and fresh observations are separate states. A green deployment or a listed action does not prove every feature is available for every workload.
- Artifacts
- Upload OCI bytes, then register and retain the immutable digest through signed paid actions. Registration alone does not upload content.
- Deploy and invoke
- Deploy an allowlisted immutable digest with explicit input references. INVOKE is a signed paid action; ordinary requests to an authorized public workload URL are its HTTP data plane, not individually paid INVOKE calls.
- Config and secret material
- Create owner-private immutable configs or write-only encrypted secret versions, then bind their references in a paid deployment. Both env and envFrom are materialized into exact immutable Kubernetes objects. Never put secret values into configs, action bodies, logs or public records.
- Upgrade and rollback
- DEPLOY_VERSION accepts a complete inputs snapshot: configs, secrets, policy, http, routes and health. Retain that original request to verify the commitments in privacy-filtered owner responses; those responses do not reveal an expanded private payload. Rollback reuses a historical version but creates fresh activation and readiness. Candidate readiness alone is not committed success.
- Renewable compute and amendments
- Read owner lease policy, request and review an itemized quote, then prepare and pay the exact operation. Next-period resize can be settled while WAITING_EFFECTIVE_TIME: poll the same action, never pay again. Paid reactivation creates a new lease generation; it does not restore expired entitlement. Mid-period prorated resizing and volume resizing are unsupported.
- Storage and recovery
- Storage requires separately funded custody and serialized writer authority. Recorded funding is not current CSI readiness. Reconcile ambiguous settlement with the original operation; refund-pending is not refunded. Preserve transaction and deployment history.
- Wallet enrollment
- Paid ENROLL_WALLET yields PENDING_REVIEW, not activation. Review and activation require distinct trusted operators; the requested scope and ACTIVE state remain admission prerequisites.
Write-only workload secret versions
These owner-authenticated metadata/custody routes are separate from x402 workload actions. POST creates a new immutable encrypted version; rotation creates a successor. GET returns metadata only, never plaintext. Follow the exact signing and body contract in OpenAPI.
- POST /v1/workload-secrets
- GET /v1/workload-secrets
- GET /v1/workload-secrets/{secretID}
- POST /v1/workload-secrets/{secretID}/rotate
- POST /v1/workload-secrets/{secretID}/revoke
- DELETE /v1/workload-secrets/{secretID}
Rotation alone changes no running workload. Bind the successor through a complete signed deployment-version input snapshot, verify committed activation, then revoke the predecessor when reference guards permit. Historical references can prevent secret deletion; never erase history to bypass those guards. Offline operator root rewrap is a separate maintenance procedure, not external credential revocation or automatic workload cutover.
Reading Explorer evidence
Purchased allocation is a contract, not measured usage. Historical activation receipts remain historical. The current_observation read model is collected by the reconciler, never by an effectful GET. It reports observation time, validity and identity-bound freshness; missing, stale, mismatched or revoked evidence never reports current READY. The browser expires readiness locally even if its stream stops.
Deployment detail history spans public committed acquisition, renewal, reactivation and resize records across lease generations. It is not a complete private attempt/payment ledger. Use history_limit (1–50) and the returned history_next_cursor as history_cursor to navigate bounded pages. An empty page with a continuation is not proof of absent history. Effective intervals, old/new resource digests and public action/version links explain amendments without exposing custody or owner payloads.
Repository fixtures, real-browser fixture rendering, installed routing, ordinary production rollout and live paid acceptance are distinct evidence. No documentation example authorizes spending or operator policy changes.
Service leases — configured capability discovery
Issue #10 remains incomplete. ACQUIRE_LEASE and RENEW_LEASE action models, dynamic quote pricing, paid coordination and a Knative adapter exist. The daemon has opt-in installed node prerequisites, independent compute expiry, paid storage authority and managed-version enforcement. Policy configuration alone cannot enable purchases. Public HTTP lease ingress is available only with configured enforcement and fresh request-specific evidence; absent, stale or mismatched prerequisites fail closed before new payment. Configured availability is not proof of live enablement or a complete phase-evidence producer. Lease config/secret deployment uses immutable resolveInputs/deployInputs custody. Recovery has an opt-in protected-file refund signer; missing authority leaves refunds unresolved. Signed next-period resize quotes and RESIZE_LEASE action preparation are implemented behind runtime prerequisites; ReadyResize permits payment and returns 202 WAITING_EFFECTIVE_TIME with settled payment and a matching waiting receipt. Waiting is nonterminal, not activation or success; mark budget spent and read the same action without paying again. Engine recovery invokes exact-boundary resize and completes only activation, without generic retry consumption while waiting. Missing prerequisites fail before new payment; durable SETTLING/SETTLEMENT_UNKNOWN permits reconciliation only even after adapter loss, never resubmission. Settled failure remains refund-pending, not refunded. Internal resize enforces the signed readiness window and historical incumbent absence. SUSPENDED reactivation uses a fresh paid ACQUIRE internally; it does not restore expired entitlement. Legacy unmanaged workloads remain unchanged; they are not perpetual leases.
- GET /v1/deployments/{deploymentID}/lease — sanitized stored state, resource identity, paid-through/grace Unix seconds, sequence/fence. NOT_OBSERVED is not runtime readiness.
- GET /v1/deployments/{deploymentID}/lease/policy — owner-private capability discovery: admission_enabled and quote_enabled follow coordinator Ready; supported_paid_operations lists ACQUIRE_LEASE/RENEW_LEASE and includes RESIZE_LEASE only with ReadyResize. Ready responses include the actual validated operator pricing_policy snapshot (PascalCase keys) and empty disabled_reason. Disabled responses preserve false flags, null pricing_policy and empty operations when unconfigured. This is not an enable switch, reservation, payment approval or deployment/resource eligibility guarantee. Every quote/payment still enforces preflight, rejecting public HTTP without valid configured ingress enforcement and evidence, unsupported volume shapes or missing storage authority, missing immutable material and stale/unavailable evidence. GET performs no reservation or payment; authenticate the original DEPLOY read and never cache the response.
- GET /v1/deployments/{deploymentID}/resource-spec — owner-private immutable purchased allocation; legacy returns 404 resource_spec_not_found.
- POST /v1/deployments/{deploymentID}/lease/quotes — when coordinator is disabled, authenticates with original deployment read signature, ignores body and returns 503 lease_admission_disabled; no reservation or payment.
- POST /v1/actions — prepare ACQUIRE_LEASE, RENEW_LEASE or RESIZE_LEASE with deployment_id, quote_id, quote_digest. Preparation is not payment or activation.
- POST /v1/actions/{actionID}/execute — existing signature-bound x402 handshake, dynamic exact quote amount, not fixed deploy price. Admission gate must pass before payment. GET /v1/actions/{actionID} reads owner-private state and receipts.
Read signing: CYNDER-ACTION-SIGNATURE binds original deployment action type, key and digest, actual method/path, and configured control origin. Missing/wrong-owner read signatures return 404. All lease responses are private, no-store. No PAYMENT-SIGNATURE belongs on quote/read routes.
Configured-coordinator contract: quote JSON has operation ACQUIRE, RENEW or RESIZE, resource_spec, duration_seconds; Idempotency-Key is required. DecodeResource computes resource_spec_id. Body digest is SHA256 of cynder-lease-quote-request/v1, newline, then sorted-key JSON with PascalCase keys Operation, Resource, Duration. Outer cynder-action-signing-v1 uses action lease_quote; sign its digest using EIP-191. Resource IDs use cynder-resource-spec/v1. Quote responses use exact PascalCase keys (ID, Digest, Amount, ExpiresAt, etc.); new quote digests use cynder-lease-quote/v2 and bind SchemaVersion and Breakdown with Digest empty; historical v1 replay retains its original version and bytes. See typed OpenAPI for every field and endpoint. Invalid body 400, signature 401, owner 404, admission 409, media type 415. Successful 201 reserves capacity but does not pay. Quote issuance is durably idempotent for the same owner, Idempotency-Key and request digest; replay preserves the original quote, including expiry. A changed request with the same key conflicts. Never downgrade signatures.
Explorer exposes numerical CPU millicores, memory/ephemeral bytes and min/max instances as purchased contract allocation, never as observed usage or proof that a pending payment succeeded. Bounded public committed history spans acquisition, renewal, fresh-paid reactivation and resize across generations, with effective intervals, resource digests and available public action/version links. It is not a complete attempt/payment ledger. Empty history is not proof of no operations. Immutable binding digest, original tuple digest and desired runtime revision are separate from live runtime observation. Historical runtime_observation remains NOT_OBSERVED or HISTORICAL_ONLY; current_observation separately requires matching current identity and unexpired freshness. Configured capabilities are not request eligibility. Recorded storage_status is NOT_APPLICABLE without lease volumes, UNKNOWN for absent/stale authority, UNAVAILABLE for revoked/mismatched/unreadable authority, or RECORDED_AUTHORIZED for matching recorded funding; it does not prove CSI readiness. Independently collected storage observations are validated against current custody. Legacy storage remains NOT_EVALUATED. Browser refresh uses public SSE, with local readiness expiry and bounded history navigation; no mutation controls, mount paths, obligation IDs, quotes, owner custody or payment authorizations are exposed.
Versioned lease quote itemization
New quotes use SchemaVersion cynder-lease-quote/v2. Breakdown retains the exact pricing policy and resource snapshots, storage duration and price items. CPU is billed in millicores; memory, ephemeral storage and volumes use bytes. Each resource item is rate in asset atomic units per unit-second times units times seconds times multiplier. Compute uses maximum replicas; the fee is charged once. Compute, Storage and Fee sum exactly to Total and the quote Amount, using integer arithmetic without rounding.
The v2 canonical digest binds the complete itemization and policy digest. Historical v1 quotes omit SchemaVersion and Breakdown and retain their original digest bytes for replay; they are never silently upgraded. The packaged compute-only client requires v2, verifies request/resource binding, policy digest, item arithmetic and quote digest, and rejects missing evidence, unknown versions and legacy downgrade. Hash consistency is not provider authentication, rate approval, payment or activation. Operator rates still need owner review; existing signature, x402 and admission gates remain required.
Failed-service refunds
FAILED alone is not refundable. Confirmed settlement plus definitive platform non-delivery creates a full original-charge refund obligation. Customer application errors are excluded; partial delivery requires review without proration. Unknown outcomes require reconciliation. Original payment remains SETTLED; refund PENDING is not CONFIRMED. Missing evidence remains unknown. Automatic execution is disabled by default and requires operator-enabled funded custody. Browser reads never send money. Synthetic test evidence is not live payout proof.
Public read endpoints
Complete API method/path reference
The machine API documents 41 operations across 37 paths. This reference comes from the same embedded OpenAPI contract served by this process; route presence does not mean a gated capability is enabled. Browser pages and static assets are not API operations.
Actions and payment
POST /v1/actions
Prepare an immutable action
Parameters
Idempotency-Key (header, required): Schema JSON
{
"maxLength": 255,
"minLength": 1,
"type": "string"
}
CYNDER-ACTION-SIGNATURE (header): 65-byte hex EIP-191 personal signature of the server-bound action digest. Omit from a prepare request once to receive the digest challenge in CYNDER-ACTION-DIGEST. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Request body
application/json CreateActionRequestSchema JSON
{
"$ref": "#/components/schemas/CreateActionRequest"
}
Responses
201: Action prepared; payment has not yet been settled. ActionView
application/json ActionViewSchema JSON
{
"$ref": "#/components/schemas/ActionView"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: EIP-191 action signature required. Sign the domain-bound digest in CYNDER-ACTION-DIGEST and retry. Digest Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Request rejected by an action preparation or execution capacity limit. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/actions/{actionID}
Read an owner-authenticated action, state, and receipt stream
Parameters
actionID (path, required): ActionIDSchema JSON
{
"$ref": "#/components/schemas/ActionID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Request body
None specified.
Responses
200: Action view ActionView
application/json ActionViewSchema JSON
{
"$ref": "#/components/schemas/ActionView"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/actions/{actionID}/execute
Settle the action-specific payment and execute the prepared action
RESIZE_LEASE accepts new payment only when ReadyResize prerequisites hold. Settled scheduling returns 202 WAITING_EFFECTIVE_TIME, not activation. Recovery invokes exact-boundary resize and succeeds only after activation; waiting consumes no generic retry attempts. Missing prerequisites fail before new payment. Durable SETTLING/SETTLEMENT_UNKNOWN permits reconciliation only, without resubmission even if the adapter is lost. Settled activation failure remains refund-pending until authoritative refund finality. The node-backed resize adapter is opt-in and requires installed enforcing prerequisites.
Parameters
actionID (path, required): ActionIDSchema JSON
{
"$ref": "#/components/schemas/ActionID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
PAYMENT-SIGNATURE (header): Base64 x402 v2 payment payload. Omit once to receive PAYMENT-REQUIRED. Schema JSON
{
"contentEncoding": "base64",
"maxLength": 65536,
"type": "string"
}
Request body
None specified.
Responses
200: Paid action completed or its persisted result was replayed. ActionView
application/json ActionViewSchema JSON
{
"$ref": "#/components/schemas/ActionView"
}
202: Settled RESIZE_LEASE awaits its signed effective time; not activated or successful. Budget is spent. Read the existing action; never pay again. WaitingResizeView
application/json WaitingResizeViewSchema JSON
{
"$ref": "#/components/schemas/WaitingResizeView"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
402: x402 v2 payment required for this action type. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Request rejected by an action preparation or execution capacity limit. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
502: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/actions/{actionID}/recover-registration
Owner-signed, signature-only recovery of the original settled failed immutable artifact registration
Empty body; no PAYMENT-SIGNATURE, new quote, payment, or new action. Sign POST, this exact path, register_artifact, the original idempotency key and original action digest. Only a settled FAILED REGISTER_ARTIFACT with a canonical digest reference is eligible. The server verifies original payment binding, owner/tenant admission, complete current manifest and blob hashes, the exact artifact effect and all canonical refund operations/reservations before atomically admitting recovery. OWED or CONFIRMED refund blocks. Ordinary execute stays terminal on FAILED. A successful replay returns the same artifact and original payment; older receipts remain unchanged, with an appended recovery receipt referencing the failed receipt digest. Missing or ambiguous state fails closed. A 503 after admission may be nonterminal; read the original action before any further request.
Parameters
actionID (path, required): ActionIDSchema JSON
{
"$ref": "#/components/schemas/ActionID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Request body
None specified.
Responses
200: Original registration recovered or its persisted success replayed; state, refund, output and receipt chain are returned. ActionView
application/json ActionViewSchema JSON
{
"$ref": "#/components/schemas/ActionView"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Request rejected by an action preparation or execution capacity limit. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
Configuration
GET /v1/configs
List all of the signer's config versions, including revoked versions
Signer-owned reads do not require active enrollment. No pagination, query parameters, body, or Idempotency-Key. Ordered by opaque ID, not creation time. Bounded by the store-wide 256-version limit. The system legacy version is excluded.
Parameters
CYNDER-ACTION-SIGNATURE (header, required): Exactly one EIP-191 signature over the decoded 32-byte config signing digest described at /v1/configs. Invalid or missing authentication returns 401 without a digest challenge, unlike paid action preparation. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
CYNDER-CONFIG-ADDRESS (header, required): Exactly one public EVM address matching the recovered signer (case-insensitive). This is an authentication hint, not an owner override; owner_id is derived from authenticated identity. Schema JSON
{
"pattern": "^(0[xX])?[0-9a-fA-F]{40}$",
"type": "string"
}
Request body
None specified.
Responses
200: Owner-private config list; empty list is configs []. ConfigList
application/json ConfigListSchema JSON
{
"$ref": "#/components/schemas/ConfigList"
}
400: invalid_config_request: invalid config request (including malformed JSON, limits on decoded data, forbidden body/key/query/path, or invalid timestamp). Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: signature_required: valid domain-bound config signature and address required. No CYNDER-ACTION-DIGEST challenge is returned. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
413: request_too_large: config request too large. Raw body exceeds 524288 bytes. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: store_error: config store unavailable. Internal integrity/storage details are not exposed. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/configs
Create an immutable owner-private non-secret environment version
Returns 201 for both creation and replay. Equivalent decoded maps have the same digest, but new keys create distinct opaque IDs. All config mutations share one owner-scoped idempotency namespace. Replay returns the original result snapshot, not current lifecycle state; GET reads current state. Requires ACTIVE enrollment with x402 activation and deploy scope, including replay (403 otherwise). New writes at the version or ordinary replay limit return 409 config_capacity; an admitted exact replay still succeeds.
Parameters
CYNDER-ACTION-SIGNATURE (header, required): Exactly one EIP-191 signature over the decoded 32-byte config signing digest described at /v1/configs. Invalid or missing authentication returns 401 without a digest challenge, unlike paid action preparation. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
CYNDER-CONFIG-ADDRESS (header, required): Exactly one public EVM address matching the recovered signer (case-insensitive). This is an authentication hint, not an owner override; owner_id is derived from authenticated identity. Schema JSON
{
"pattern": "^(0[xX])?[0-9a-fA-F]{40}$",
"type": "string"
}
Idempotency-Key (header, required): Exactly one nonempty UTF-8 value, at most 128 bytes, with no surrounding whitespace, Unicode controls or replacement characters. Shared across all config mutations for this signer. No key is sent on GET. Schema JSON
{
"maxLength": 128,
"minLength": 1,
"type": "string"
}
Request body
application/json CreateConfigRequestSchema JSON
{
"$ref": "#/components/schemas/CreateConfigRequest"
}
Responses
201: Owner-private immutable content and lifecycle snapshot. idempotency_key is the original creation key. Replay returns the original mutation result, without Location or Idempotency-Replayed headers. ConfigVersion
application/json ConfigVersionSchema JSON
{
"$ref": "#/components/schemas/ConfigVersion"
}
400: invalid_config_request: invalid config request (including malformed JSON, limits on decoded data, forbidden body/key/query/path, or invalid timestamp). Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: signature_required: valid domain-bound config signature and address required. No CYNDER-ACTION-DIGEST challenge is returned. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
403: wallet_enrollment_required: active deploy wallet enrollment required. Create and retain (including replays) require ACTIVE enrollment, x402 activation and deploy scope. Owned revoke and reads are exempt. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: idempotency_conflict for a key reused with another operation/ID/content; lifecycle_conflict for shortening retention or mutating the system legacy version; config_capacity for exhausted store-wide lifetime capacity (256 versions, 1024 ordinary replay results, plus one reserved active-to-revoked transition per existing version, at most 1280 total results). Exact replay consumes no capacity; new-key no-op revocations cannot use the reserve. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
413: request_too_large: config request too large. Raw body exceeds 524288 bytes. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: unsupported_media_type: application/json required for POST. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: store_error: config store unavailable. Internal integrity/storage details are not exposed. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/configs/{configID}
Inspect the current owner-private config record
Same signing contract as /v1/configs with this exact path. Signer-owned reads do not require active enrollment. No body, query parameters, encoded path, or Idempotency-Key. Cross-owner, invalid and unknown IDs return identical 404 envelopes. The system legacy version is not exposed by this route.
Parameters
configID (path, required): ConfigIDSchema JSON
{
"$ref": "#/components/schemas/ConfigID"
}
CYNDER-ACTION-SIGNATURE (header, required): Exactly one EIP-191 signature over the decoded 32-byte config signing digest described at /v1/configs. Invalid or missing authentication returns 401 without a digest challenge, unlike paid action preparation. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
CYNDER-CONFIG-ADDRESS (header, required): Exactly one public EVM address matching the recovered signer (case-insensitive). This is an authentication hint, not an owner override; owner_id is derived from authenticated identity. Schema JSON
{
"pattern": "^(0[xX])?[0-9a-fA-F]{40}$",
"type": "string"
}
Request body
None specified.
Responses
200: Owner-private immutable content and lifecycle snapshot. idempotency_key is the original creation key. Replay returns the original mutation result, without Location or Idempotency-Replayed headers. ConfigVersion
application/json ConfigVersionSchema JSON
{
"$ref": "#/components/schemas/ConfigVersion"
}
400: invalid_config_request: invalid config request (including malformed JSON, limits on decoded data, forbidden body/key/query/path, or invalid timestamp). Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: signature_required: valid domain-bound config signature and address required. No CYNDER-ACTION-DIGEST challenge is returned. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: not_found: config not found. Identical for cross-owner, invalid and unknown IDs. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
413: request_too_large: config request too large. Raw body exceeds 524288 bytes. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: store_error: config store unavailable. Internal integrity/storage details are not exposed. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/configs/{configID}/retain
Extend a config retention deadline monotonically
Same signing and strict request contract as /v1/configs with this exact path. Equal deadlines are allowed; shortening returns lifecycle_conflict. Retention can extend a revoked record but never reactivates it. Initial retain_until equals created_at. No expiry or automatic deletion is performed. Equivalent timestamp instants replay the same result for the same key. The reserved system legacy ID cannot be mutated (409). Requires ACTIVE enrollment with x402 activation and deploy scope, including exact replays (403 otherwise), after ownership is checked. New writes at the ordinary 1024-result limit return 409 config_capacity; admitted exact replays consume no capacity and still succeed.
Parameters
configID (path, required): ConfigIDSchema JSON
{
"$ref": "#/components/schemas/ConfigID"
}
CYNDER-ACTION-SIGNATURE (header, required): Exactly one EIP-191 signature over the decoded 32-byte config signing digest described at /v1/configs. Invalid or missing authentication returns 401 without a digest challenge, unlike paid action preparation. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
CYNDER-CONFIG-ADDRESS (header, required): Exactly one public EVM address matching the recovered signer (case-insensitive). This is an authentication hint, not an owner override; owner_id is derived from authenticated identity. Schema JSON
{
"pattern": "^(0[xX])?[0-9a-fA-F]{40}$",
"type": "string"
}
Idempotency-Key (header, required): Exactly one nonempty UTF-8 value, at most 128 bytes, with no surrounding whitespace, Unicode controls or replacement characters. Shared across all config mutations for this signer. No key is sent on GET. Schema JSON
{
"maxLength": 128,
"minLength": 1,
"type": "string"
}
Request body
application/json RetainConfigRequestSchema JSON
{
"$ref": "#/components/schemas/RetainConfigRequest"
}
Responses
200: Owner-private immutable content and lifecycle snapshot. idempotency_key is the original creation key. Replay returns the original mutation result, without Location or Idempotency-Replayed headers. ConfigVersion
application/json ConfigVersionSchema JSON
{
"$ref": "#/components/schemas/ConfigVersion"
}
400: invalid_config_request: invalid config request (including malformed JSON, limits on decoded data, forbidden body/key/query/path, or invalid timestamp). Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: signature_required: valid domain-bound config signature and address required. No CYNDER-ACTION-DIGEST challenge is returned. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
403: wallet_enrollment_required: active deploy wallet enrollment required. Create and retain (including replays) require ACTIVE enrollment, x402 activation and deploy scope. Owned revoke and reads are exempt. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: not_found: config not found. Identical for cross-owner, invalid and unknown IDs. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: idempotency_conflict for a key reused with another operation/ID/content; lifecycle_conflict for shortening retention or mutating the system legacy version; config_capacity for exhausted store-wide lifetime capacity (256 versions, 1024 ordinary replay results, plus one reserved active-to-revoked transition per existing version, at most 1280 total results). Exact replay consumes no capacity; new-key no-op revocations cannot use the reserve. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
413: request_too_large: config request too large. Raw body exceeds 524288 bytes. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: unsupported_media_type: application/json required for POST. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: store_error: config store unavailable. Internal integrity/storage details are not exposed. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/configs/{configID}/revoke
Irreversibly revoke a config version without deleting its content
Same signing and strict request contract as /v1/configs with this exact path. Body must be {}. Repeated revocation preserves revoked_at, even with a fresh key. Replay returns the original result snapshot. Revocation blocks the store's ResolveConfig integration gate; it does not stop existing workloads. The reserved system legacy ID cannot be mutated (409). Owned revocation and its exact replay remain available without active wallet enrollment. ACL is checked first. An active-to-revoked transition can exceed the ordinary 1024-result limit once per existing version, with a hard total bound of 1280. New-key no-op revocations at capacity return 409 config_capacity; exact replay preserves the original snapshot and consumes no capacity.
Parameters
configID (path, required): ConfigIDSchema JSON
{
"$ref": "#/components/schemas/ConfigID"
}
CYNDER-ACTION-SIGNATURE (header, required): Exactly one EIP-191 signature over the decoded 32-byte config signing digest described at /v1/configs. Invalid or missing authentication returns 401 without a digest challenge, unlike paid action preparation. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
CYNDER-CONFIG-ADDRESS (header, required): Exactly one public EVM address matching the recovered signer (case-insensitive). This is an authentication hint, not an owner override; owner_id is derived from authenticated identity. Schema JSON
{
"pattern": "^(0[xX])?[0-9a-fA-F]{40}$",
"type": "string"
}
Idempotency-Key (header, required): Exactly one nonempty UTF-8 value, at most 128 bytes, with no surrounding whitespace, Unicode controls or replacement characters. Shared across all config mutations for this signer. No key is sent on GET. Schema JSON
{
"maxLength": 128,
"minLength": 1,
"type": "string"
}
Request body
application/jsonSchema JSON
{
"additionalProperties": false,
"maxProperties": 0,
"type": "object"
}
Responses
200: Owner-private immutable content and lifecycle snapshot. idempotency_key is the original creation key. Replay returns the original mutation result, without Location or Idempotency-Replayed headers. ConfigVersion
application/json ConfigVersionSchema JSON
{
"$ref": "#/components/schemas/ConfigVersion"
}
400: invalid_config_request: invalid config request (including malformed JSON, limits on decoded data, forbidden body/key/query/path, or invalid timestamp). Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: signature_required: valid domain-bound config signature and address required. No CYNDER-ACTION-DIGEST challenge is returned. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: not_found: config not found. Identical for cross-owner, invalid and unknown IDs. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: idempotency_conflict for a key reused with another operation/ID/content; lifecycle_conflict for shortening retention or mutating the system legacy version; config_capacity for exhausted store-wide lifetime capacity (256 versions, 1024 ordinary replay results, plus one reserved active-to-revoked transition per existing version, at most 1280 total results). Exact replay consumes no capacity; new-key no-op revocations cannot use the reserve. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
413: request_too_large: config request too large. Raw body exceeds 524288 bytes. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: unsupported_media_type: application/json required for POST. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: store_error: config store unavailable. Internal integrity/storage details are not exposed. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
Deployments and leases
GET /v1/deployments/{deploymentID}
Read the owner-authenticated durable deployment projection or tombstone
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Request body
None specified.
Responses
200: Deployment projection Deployment
application/json DeploymentSchema JSON
{
"$ref": "#/components/schemas/Deployment"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/deployments/{deploymentID}/lease
ServiceLeaseProjection
Owner read signature uses original DEPLOY action payment name deploy, original idempotency key and immutable digest, actual HTTP method/path and configured control origin. Missing/wrong owner returns 404. Cache-Control private, no-store; Vary CYNDER-ACTION-SIGNATURE. Never send PAYMENT-SIGNATURE. History is a bounded action-ID scan, not a complete payment ledger.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
history_cursor (query): Opaque action-ID continuation from service_lease.history_next_cursor. Schema JSON
{
"pattern": "^act_[0-9a-f]{32}$",
"type": "string"
}
history_limit (query): Schema JSON
{
"default": 20,
"maximum": 50,
"minimum": 1,
"type": "integer"
}
Request body
None specified.
Responses
200: ServiceLeaseProjection ServiceLeaseProjection
application/json ServiceLeaseProjectionSchema JSON
{
"$ref": "#/components/schemas/ServiceLeaseProjection"
}
400: invalid_history_page for an invalid cursor or limit Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: not_found for ownership or missing deployment; resource_spec_not_found for legacy resource read Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: lease_admission_disabled for disabled quotes; lease_store_unavailable for unavailable reads Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/deployments/{deploymentID}/lease/policy
LeasePolicy
Owner read signature uses original DEPLOY action payment name deploy, original idempotency key and immutable digest, actual HTTP method/path and configured control origin. Missing/wrong owner returns 404 before readiness evaluation. Cache-Control private, no-store; Vary CYNDER-ACTION-SIGNATURE. Never send PAYMENT-SIGNATURE. Owner-private capability discovery, not an enable switch, reservation, price quote or deployment/resource eligibility guarantee. Both enabled flags and ACQUIRE_LEASE/RENEW_LEASE follow LeaseCoordinator.Ready; RESIZE_LEASE additionally requires ReadyResize. A ready response has disabled_reason empty and pricing_policy equal to the actual validated operator snapshot (PascalCase keys). Disabled responses retain both flags false, disabled_reason lease_admission_not_configured_or_integrated, pricing_policy null and supported_paid_operations []. No defaults or prices are synthesized. Readiness is rechecked on each request; runtime readiness errors disable discovery without exposing private details. Per-request preflight rejects public HTTP combined with volumes, unsupported volume shapes, missing material or storage authority and stale/unavailable evidence before payment. A supported single volume requires installed paid-storage enforcement; resize does not accept volumes. Policy GET does not run preflight or reserve capacity. Daemon prerequisites are opt-in and require verified installed enforcement. Legacy policy remains LEAVE_UNCHANGED. Never automatically downgrade signing or pay from this response.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Request body
None specified.
Responses
200: LeasePolicy LeasePolicy
application/json LeasePolicySchema JSON
{
"$ref": "#/components/schemas/LeasePolicy"
}
404: not_found for ownership or missing deployment; resource_spec_not_found for legacy resource read Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: lease_admission_disabled for disabled quotes; lease_store_unavailable for unavailable reads Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/deployments/{deploymentID}/lease/quotes
LeaseQuote
Every readiness state requires strict JSON and Idempotency-Key; computes ResourceSpec ID first, then SHA256(cynder-lease-quote-request/v1 + newline + sorted-key JSON {Operation,Resource,Duration}), where Resource includes computed resource_spec_id. Outer cynder-action-signing-v1 uses action lease_quote, actual POST method/path, configured control origin, idempotency key and that body digest; EIP-191 signs outer digest. Missing/wrong owner returns 404. Invalid signature returns 401 with CYNDER-ACTION-DIGEST; no fallback to original DEPLOY read signing. Cache-Control private, no-store; Vary CYNDER-ACTION-SIGNATURE. Never send PAYMENT-SIGNATURE. After valid owner/body signature, unavailable admission returns 503 lease_admission_disabled without reservation/payment. A successful ready quote reserves capacity, but never submits payment. Policy read projects coordinator readiness; it is not a guarantee that this resource request passes preflight.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Idempotency-Key (header, required): Schema JSON
{
"maxLength": 255,
"minLength": 1,
"type": "string"
}
Request body
application/json LeaseQuoteRequestSchema JSON
{
"$ref": "#/components/schemas/LeaseQuoteRequest"
}
Responses
201: LeaseQuote (ready coordinator only; unavailable in current daemon) LeaseQuote
application/json LeaseQuoteSchema JSON
{
"$ref": "#/components/schemas/LeaseQuote"
}
400: invalid_resource_spec, idempotency_key_required, invalid_quote or strict JSON failure Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: action_signature_required; CYNDER-ACTION-DIGEST contains locally reproducible signing digest Digest Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: not_found for ownership or missing deployment; resource_spec_not_found for legacy resource read Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: lease_admission_rejected Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: unsupported_media_type Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: lease_admission_disabled for disabled quotes; lease_store_unavailable for unavailable reads Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/deployments/{deploymentID}/resource-spec
ResourceSpec
Owner read signature uses original DEPLOY action payment name deploy, original idempotency key and immutable digest, actual HTTP method/path and configured control origin. Missing/wrong owner returns 404. Cache-Control private, no-store; Vary CYNDER-ACTION-SIGNATURE. Never send PAYMENT-SIGNATURE.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Request body
None specified.
Responses
200: ResourceSpec ResourceSpec
application/json ResourceSpecSchema JSON
{
"$ref": "#/components/schemas/ResourceSpec"
}
404: not_found for ownership or missing deployment; resource_spec_not_found for legacy resource read Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: lease_admission_disabled for disabled quotes; lease_store_unavailable for unavailable reads Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/deployments/{deploymentID}/storage-authorities/{obligationID}
Read recorded storage funding authority
Owner-private recorded funding readback only, not a purchase, provisioning, live CSI readiness, or retained-access claim. Sign the original DEPLOY action digest and idempotency key with action deploy, actual GET method and full request path, and configured control origin. Missing, foreign and unauthenticated resources return 404. No PAYMENT-SIGNATURE is required. Responses exclude custody identities, signatures and settlement evidence. Cache-Control is private, no-store; Vary CYNDER-ACTION-SIGNATURE.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
obligationID (path, required): Schema JSON
{
"type": "string"
}
Request body
None specified.
Responses
200: Explicit owner-safe recorded authority projection
application/jsonSchema JSON
{
"additionalProperties": false,
"properties": {
"deployment_id": {
"type": "string"
},
"funding_state": {
"enum": [
"FUNDED",
"EXPIRED",
"REVOKED"
],
"type": "string"
},
"obligation_id": {
"type": "string"
},
"paid_through": {
"format": "uint64",
"type": "integer"
},
"retention": {
"type": "string"
},
"retention_deadline": {
"format": "uint64",
"type": "integer"
},
"size_bytes": {
"format": "uint64",
"type": "integer"
},
"status": {
"enum": [
"RECORDED_AUTHORIZED",
"UNKNOWN",
"UNAVAILABLE"
],
"type": "string"
},
"tier": {
"type": "string"
},
"volume_id": {
"type": "string"
}
},
"required": [
"obligation_id",
"deployment_id",
"volume_id",
"size_bytes",
"tier",
"retention",
"paid_through",
"retention_deadline",
"funding_state",
"status"
],
"type": "object"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/deployments/{deploymentID}/storage-authorities/{obligationID}/export
Export a bounded retained storage archive to the owner
Owner-private, unpaid, signed retained export. No PAYMENT-SIGNATURE or Idempotency-Key. Require application/json with exactly one expected_epoch unsigned uint64 greater than zero; reject duplicate or unknown fields, query parameters, and request bodies above 1 MiB. Compute lowercase SHA-256 hex of the exact raw body bytes prefixed by "cynder-retained-export/v1\n"; sign with ActionSigningDigest action storage-export, POST, exact request path, configured control origin, empty idempotency key, and that digest. The EIP-191 CYNDER-ACTION-SIGNATURE must recover the deployment and obligation owner. Missing or foreign resources and invalid signatures return 404; malformed requests return 400. The explicitly configured immutable digest reader image and retained epoch CAS gate the effect; unavailable, canceled, failed, empty or oversized archives return 503 without any archive bytes. Success returns at most 1 MiB of application/x-tar bytes. Never cache or print the archive; Cache-Control is private, no-store and Vary is CYNDER-ACTION-SIGNATURE. No tar extraction is performed by this endpoint.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
obligationID (path, required): Schema JSON
{
"type": "string"
}
Request body
application/jsonSchema JSON
{
"additionalProperties": false,
"properties": {
"expected_epoch": {
"format": "uint64",
"minimum": 1,
"type": "integer"
}
},
"required": [
"expected_epoch"
],
"type": "object"
}
Responses
200: Binary retained archive, no more than 1048576 bytes
application/x-tarSchema JSON
{
"format": "binary",
"maxLength": 1048576,
"type": "string"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/deployments/{deploymentID}/storage-authorities/{obligationID}/funding
Read an owner-private purchase funding commitment
Sign the original DEPLOY action digest and idempotency key for this exact GET path and configured origin. The purchase_key query selects the original confirmed purchase. The server rechecks retained finality and current CSI custody. This response is a digest commitment only, not signing bytes: StorageFundingBytes includes private CSI identifiers, so a separately trusted owner-signing integration must review the full retained statement before signing. No raw binding, payment signature or settlement proof is returned. Cache-Control private, no-store; Vary CYNDER-ACTION-SIGNATURE.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
obligationID (path, required): Schema JSON
{
"type": "string"
}
purchase_key (query, required): Schema JSON
{
"type": "string"
}
Request body
None specified.
Responses
200: Safe commitment, not a signable statement
application/jsonSchema JSON
{
"additionalProperties": false,
"properties": {
"expires_at": {
"format": "uint64",
"type": "integer"
},
"obligation_id": {
"type": "string"
},
"purchase_key": {
"type": "string"
},
"sequence": {
"format": "uint64",
"type": "integer"
},
"signing_domain": {
"enum": [
"cynder/storage/final-settlement/v1"
],
"type": "string"
},
"statement_digest": {
"description": "Lowercase SHA-256 hex of StorageFundingBytes",
"type": "string"
}
},
"required": [
"purchase_key",
"obligation_id",
"sequence",
"statement_digest",
"expires_at",
"signing_domain"
],
"type": "object"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/deployments/{deploymentID}/storage-authorities/{obligationID}/funding
Admit independently settled storage funding
Owner-private admission of an already FINAL independently verified storage payment, not purchase, settlement, provisioning or live CSI readiness. With purchase_key, body contains only owner_signature and operator_signature (base64 byte arrays); the server reloads the original purchase-bound exact derived statement and checks current custody and finality. Without purchase_key, the general funding route accepts the Go JSON representation of SignedStorageFunding including Statement. Both Ed25519 signatures cover StorageFundingBytes(Statement) in the storage final-settlement domain. The separate EIP-191 deploy action signature binds POST, the exact path and configured origin, the original deployment action idempotency key, and the lowercase SHA-256 hex of the JSON-marshaled decoded request body. The purchase selector is not part of the EIP-191 path signature; the server binds it to the original action and exact dual-signed statement. Trust keys and independent FINAL settlement evidence come only from server-side configured custody; request-supplied keys or compute receipts cannot establish finality. Production requires separately provisioned pinned keys and a trusted owner signer able to review private custody. Replaying identical finalized signed funding is idempotent; other conflicts are rejected. Missing or foreign ownership is concealed as 404. Cache-Control private, no-store; Vary CYNDER-ACTION-SIGNATURE. Never send PAYMENT-SIGNATURE.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
obligationID (path, required): Schema JSON
{
"type": "string"
}
purchase_key (query): Schema JSON
{
"type": "string"
}
Request body
application/jsonSchema JSON
{
"oneOf": [
{
"additionalProperties": false,
"properties": {
"operator_signature": {
"format": "byte",
"type": "string"
},
"owner_signature": {
"format": "byte",
"type": "string"
}
},
"required": [
"owner_signature",
"operator_signature"
],
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"OperatorSignature": {
"format": "byte",
"type": "string"
},
"OwnerSignature": {
"format": "byte",
"type": "string"
},
"Statement": {
"description": "Go StorageFunding statement with obligation and immutable CSI binding",
"type": "object"
}
},
"required": [
"Statement",
"OwnerSignature",
"OperatorSignature"
],
"type": "object"
}
]
}
Responses
200: Safe recorded funding projection (including exact replay)
application/jsonSchema JSON
{
"additionalProperties": false,
"properties": {
"funding_state": {
"enum": [
"FUNDED"
],
"type": "string"
},
"obligation_id": {
"type": "string"
},
"sequence": {
"format": "uint64",
"type": "integer"
}
},
"required": [
"obligation_id",
"sequence",
"funding_state"
],
"type": "object"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
422: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/deployments/{deploymentID}/storage-authorities/{obligationID}/purchases/{purchaseKey}/signing-material
Read purpose-scoped private storage purchase signing material
Sensitive owner-only signing operation. The exact path includes the purchase identity; no query selector is accepted. EIP-191 signs the original DEPLOY digest and idempotency key bound to GET, this exact path and configured control origin. Foreign owners and missing/changed finality or CSI custody receive 404. The response contains the exact retained typed StorageFunding statement (including private CSI identifiers), its StorageFundingBytes SHA-256 commitment and purchase key, but no signatures, payment authorization, finality proof or workload secrets. Never log or display it in general owner or public views. A trusted local signer must parse the statement, compare original approved quote, owner, payment, coverage, sequence and CSI custody commitment, recompute its domain digest, then sign StorageFundingBytes; no blind signing. Cache-Control private, no-store; Vary CYNDER-ACTION-SIGNATURE.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
obligationID (path, required): Schema JSON
{
"type": "string"
}
purchaseKey (path, required): Schema JSON
{
"type": "string"
}
Request body
None specified.
Responses
200: Purpose-scoped private typed signing statement
application/jsonSchema JSON
{
"additionalProperties": false,
"properties": {
"purchase_key": {
"type": "string"
},
"statement": {
"additionalProperties": false,
"description": "Exact Go StorageFunding; includes Obligation, Binding, Sequence, Nonce, SettlementID, Network, Asset, Amount, Payee and ExpiresAt.",
"properties": {
"Amount": {
"type": "string"
},
"Asset": {
"type": "string"
},
"Binding": {
"description": "Private immutable CSI custody identifiers and resource versions",
"type": "object"
},
"ExpiresAt": {
"format": "uint64",
"type": "integer"
},
"Network": {
"type": "string"
},
"Nonce": {
"type": "string"
},
"Obligation": {
"description": "Exact owner/deployment/coverage storage obligation",
"type": "object"
},
"Payee": {
"type": "string"
},
"Sequence": {
"format": "uint64",
"type": "integer"
},
"SettlementID": {
"type": "string"
}
},
"required": [
"Obligation",
"Binding",
"Sequence",
"Nonce",
"SettlementID",
"Network",
"Asset",
"Amount",
"Payee",
"ExpiresAt"
],
"type": "object"
},
"statement_digest": {
"description": "Lowercase SHA-256 hex of StorageFundingBytes(statement)",
"type": "string"
}
},
"required": [
"purchase_key",
"statement",
"statement_digest"
],
"type": "object"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/deployments/{deploymentID}/storage/purchases
Prepare an independently priced storage purchase (unpaid)
Strict JSON and Idempotency-Key are required. The EIP-191 action storage_purchase_quote binds POST, exact path, configured origin, key, and Digest(cynder-storage-purchase-prepare/v1, decoded request fields). A valid owner of the deployment is required. Policy and immutable CSI custody are resolved only from an explicitly installed server provider; cynderd installs one only with protected operator configuration and paid-storage enforcement, otherwise returning 503 for new requests. Exact authenticated replay returns the original durable intent even after quote expiry or policy removal. No payment, hold, storage grant, or paid operation is executed by this preparation route. Never send PAYMENT-SIGNATURE.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Idempotency-Key (header, required): Schema JSON
{
"maxLength": 255,
"minLength": 1,
"type": "string"
}
Request body
application/jsonSchema JSON
{
"additionalProperties": false,
"properties": {
"coverage_ends": {
"format": "uint64",
"type": "integer"
},
"coverage_starts": {
"format": "uint64",
"type": "integer"
},
"expected_sequence": {
"format": "uint64",
"type": "integer"
},
"obligation_id": {
"type": "string"
},
"retention_policy": {
"type": "string"
},
"size_bytes": {
"format": "uint64",
"type": "integer"
},
"tier": {
"type": "string"
},
"volume_id": {
"type": "string"
}
},
"required": [
"obligation_id",
"volume_id",
"tier",
"retention_policy",
"size_bytes",
"expected_sequence",
"coverage_starts",
"coverage_ends"
],
"type": "object"
}
Responses
201: Durable NOT_SUBMITTED owner-only storage quote projection StoragePurchaseView
application/json StoragePurchaseViewSchema JSON
{
"$ref": "#/components/schemas/StoragePurchaseView"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/deployments/{deploymentID}/storage/purchases/{purchaseKey}
Read an owner's durable storage purchase intent
Owner read signature binds the original DEPLOY action identity and digest to GET, exact path and configured origin. Foreign deployment, missing key or another deployment's intent returns 404. Returns only itemized pricing, the typed quote with its authenticated request and reviewed policy (for offline digest validation), and public obligation details. Request.CustodyDigest is only a commitment; the private CSI binding, trusted keys, signatures and payment evidence are never returned.
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
purchaseKey (path, required): Schema JSON
{
"type": "string"
}
Request body
None specified.
Responses
200: Owner-only storage purchase projection StoragePurchaseView
application/json StoragePurchaseViewSchema JSON
{
"$ref": "#/components/schemas/StoragePurchaseView"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/deployments/{deploymentID}/versions
List immutable versions and the active version for an owned deployment
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Request body
None specified.
Responses
200: Deployment versions DeploymentVersionList
application/json DeploymentVersionListSchema JSON
{
"$ref": "#/components/schemas/DeploymentVersionList"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: store_error when deployment versions cannot be read Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/deployments/{deploymentID}/versions/{versionID}
Read one immutable deployment version
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
versionID (path, required): VersionIDSchema JSON
{
"$ref": "#/components/schemas/VersionID"
}
CYNDER-ACTION-SIGNATURE (header, required): 65-byte hex EIP-191 personal signature of the server-bound action digest. Missing, invalid, or non-owner signatures on owner-authenticated execute and read routes return the same 404 response as an unknown resource. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Request body
None specified.
Responses
200: Deployment version DeploymentVersionView
application/json DeploymentVersionViewSchema JSON
{
"$ref": "#/components/schemas/DeploymentVersionView"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
Other API operations
GET /healthz
Process liveness
Parameters
None.
Request body
None specified.
Responses
200: Process is alive Health
application/json HealthSchema JSON
{
"$ref": "#/components/schemas/Health"
}
GET /openapi.json
Read the canonical machine-readable OpenAPI contract
Parameters
None.
Request body
None specified.
Responses
200: Canonical OpenAPI JSON
application/jsonSchema JSON
{
"type": "object"
}
GET /readyz
Badger, recovery, and Kubernetes capability readiness
Parameters
None.
Request body
None specified.
Responses
200: Process can accept actions Ready
application/json ReadySchema JSON
{
"$ref": "#/components/schemas/Ready"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/artifacts
Prepare an immutable paid artifact registration or retention action
Accepts only REGISTER_ARTIFACT and RETAIN_ARTIFACT. Owner authentication, digest challenge, and idempotency semantics are identical to POST /v1/actions.
Parameters
Idempotency-Key (header, required): Schema JSON
{
"maxLength": 255,
"minLength": 1,
"type": "string"
}
CYNDER-ACTION-SIGNATURE (header): 65-byte hex EIP-191 personal signature of the server-bound action digest. Omit from a prepare request once to receive the digest challenge in CYNDER-ACTION-DIGEST. Schema JSON
{
"pattern": "^(0x)?[0-9a-fA-F]{130}$",
"type": "string"
}
Request body
application/json ArtifactActionRequestSchema JSON
{
"$ref": "#/components/schemas/ArtifactActionRequest"
}
Responses
201: Artifact action prepared; payment has not yet been settled. ActionView
application/json ActionViewSchema JSON
{
"$ref": "#/components/schemas/ActionView"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: EIP-191 action signature required. Sign the domain-bound digest in CYNDER-ACTION-DIGEST and retry. Digest Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Request rejected by an action preparation or execution capacity limit. Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
Public Explorer
GET /v1/explorer/actions
List recent sanitized public Cynder transaction summaries
Public read-only projection. Public transaction, deployment, artifact, receipt, and settlement identifiers may be returned. Owner wallet addresses, tenant mappings, idempotency keys, raw payloads, payment authorization material, invocation input/output, private runtime details, and internal errors are never returned.
Parameters
limit (query): Schema JSON
{
"default": 20,
"maximum": 50,
"minimum": 1,
"type": "integer"
}
Request body
None specified.
Responses
200: Recent public action summaries PublicActionList
application/json PublicActionListSchema JSON
{
"$ref": "#/components/schemas/PublicActionList"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/explorer/actions/{actionID}
Read one redacted public action and timeline
Public read-only projection; this route intentionally does not use owner authentication.
Parameters
actionID (path, required): ActionIDSchema JSON
{
"$ref": "#/components/schemas/ActionID"
}
Request body
None specified.
Responses
200: Redacted public action detail PublicActionDetail
application/json PublicActionDetailSchema JSON
{
"$ref": "#/components/schemas/PublicActionDetail"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/explorer/artifacts
List recent public artifact activity from settled terminal artifact lifecycle actions
Ordered by latest public REGISTER_ARTIFACT or RETAIN_ARTIFACT lifecycle activity, not artifact creation time. Never returns tenant, repository or tag, config or layer digests, registry endpoints, node IDs, locations, pin counts, or retention internals.
Parameters
limit (query): Schema JSON
{
"default": 20,
"maximum": 50,
"minimum": 1,
"type": "integer"
}
Request body
None specified.
Responses
200: Privacy-safe public artifact list PublicArtifactList
application/json PublicArtifactListSchema JSON
{
"$ref": "#/components/schemas/PublicArtifactList"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/explorer/artifacts/{artifactID}
Read one privacy-safe public artifact
Malformed, private, and missing identifiers produce the same 404 response.
Parameters
artifactID (path, required): ArtifactIDSchema JSON
{
"$ref": "#/components/schemas/ArtifactID"
}
Request body
None specified.
Responses
200: Privacy-safe public artifact PublicArtifactSummary
application/json PublicArtifactSummarySchema JSON
{
"$ref": "#/components/schemas/PublicArtifactSummary"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/explorer/deployments
List recent sanitized public deployments
Parameters
limit (query): Schema JSON
{
"default": 20,
"maximum": 50,
"minimum": 1,
"type": "integer"
}
Request body
None specified.
Responses
200: Recent public deployments PublicDeploymentList
application/json PublicDeploymentListSchema JSON
{
"$ref": "#/components/schemas/PublicDeploymentList"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/explorer/deployments/{deploymentID}
Read one sanitized public deployment with its changelog, versions, and transactions
Parameters
deploymentID (path, required): DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
history_cursor (query): Opaque continuation from service_lease.history_next_cursor. History is a bounded scan in canonical action-ID order, not a complete payment ledger. Schema JSON
{
"pattern": "^act_[0-9a-f]{32}$",
"type": "string"
}
history_limit (query): Schema JSON
{
"default": 20,
"maximum": 50,
"minimum": 1,
"type": "integer"
}
Request body
None specified.
Responses
200: Public deployment detail PublicDeploymentDetail
application/json PublicDeploymentDetailSchema JSON
{
"$ref": "#/components/schemas/PublicDeploymentDetail"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/explorer/search
Resolve an exact public Cynder explorer identifier
Resolves a Cynder transaction ID, Base settlement transaction hash, deployment ID, artifact ID, or receipt ID. Wallet lookup is disabled, including historical wallet indexes. The response includes only public identifiers and related Cynder transaction IDs.
Parameters
q (query, required): Schema JSON
{
"maxLength": 128,
"minLength": 1,
"type": "string"
}
Request body
None specified.
Responses
200: Exact explorer result ExplorerSearchResult
application/json ExplorerSearchResultSchema JSON
{
"$ref": "#/components/schemas/ExplorerSearchResult"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/explorer/stream
Stream authoritative public explorer snapshots
Same-origin SSE stream. Every connection receives a complete authoritative snapshot immediately and after committed explorer-visible state changes. Reconnection converges by receiving a fresh snapshot; this endpoint does not claim durable event replay.
Parameters
transaction_id (query): When set, stream the sanitized transaction detail and receipt timeline instead of the recent transaction list. ActionIDSchema JSON
{
"$ref": "#/components/schemas/ActionID"
}
deployment_id (query): When set, stream sanitized deployment detail instead of the complete explorer snapshot. Mutually exclusive with transaction_id. DeploymentIDSchema JSON
{
"$ref": "#/components/schemas/DeploymentID"
}
Request body
None specified.
Responses
200: Server-sent snapshot events with heartbeat comments
text/event-streamSchema JSON
{
"type": "string"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
Workload secrets
GET /v1/workload-secrets
List only the signer's safe lifecycle metadata
Sign workload-secret:list with an empty body and canonical sorted URL-encoded query. No Idempotency-Key. Raw query is at most 256 bytes. No plaintext read endpoint exists.
Parameters
CYNDER-ACTION-SIGNATURE (header, required): EIP-191 signature bound to owner, operation, HTTP method, path, origin, idempotency key, exact body and raw query. Schema JSON
{
"type": "string"
}
after (query): Schema JSON
{
"pattern": "^sec_[a-f0-9]{48}$",
"type": "string"
}
limit (query): Schema JSON
{
"default": 100,
"maximum": 100,
"minimum": 1,
"type": "integer"
}
Request body
None specified.
Responses
200: Owner-scoped metadata page; empty next_after ends pagination. Cache-Control is private, no-store. WorkloadSecretMetadata
application/json WorkloadSecretMetadataSchema JSON
{
"additionalProperties": false,
"properties": {
"next_after": {
"type": "string"
},
"secrets": {
"items": {
"$ref": "#/components/schemas/WorkloadSecretMetadata"
},
"type": "array"
}
},
"required": [
"secrets",
"next_after"
],
"type": "object"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/workload-secrets
Create an encrypted write-only workload-secret version
Owner-signed private custody API, not a paid action. Never send values through /v1/actions. Responses contain metadata only; no key names, values, ciphertext, nonces, wrapped keys, or plaintext hashes. Sign exact body bytes and canonical raw query using WorkloadSecretRequestDigest and ActionSigningDigest with action workload-secret:create. No digest challenge is returned. See docs/workload-secrets.md for the signing contract.
Parameters
CYNDER-ACTION-SIGNATURE (header, required): EIP-191 signature bound to owner, operation, HTTP method, path, origin, idempotency key, exact body and raw query. Schema JSON
{
"type": "string"
}
Idempotency-Key (header, required): Schema JSON
{
"pattern": "^[A-Za-z0-9._-]{1,128}$",
"type": "string"
}
Request body
application/json WorkloadSecretWriteSchema JSON
{
"$ref": "#/components/schemas/WorkloadSecretWrite"
}
Responses
200: Metadata only; mutation replay returns the original result, not a fresh lifecycle read. Use GET for current state. Cache-Control is private, no-store. WorkloadSecretMetadata
application/json WorkloadSecretMetadataSchema JSON
{
"$ref": "#/components/schemas/WorkloadSecretMetadata"
}
201: New immutable version; metadata only. WorkloadSecretMetadata
application/json WorkloadSecretMetadataSchema JSON
{
"$ref": "#/components/schemas/WorkloadSecretMetadata"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
413: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
DELETE /v1/workload-secrets/{secretID}
Remove live encrypted material and preserve an audit tombstone
Sign workload-secret:delete. Requires the exact empty JSON object body and an empty query. Historical backups may still contain encrypted material; deletion is not physical erasure of old snapshots.
Parameters
secretID (path, required): Schema JSON
{
"pattern": "^sec_[a-f0-9]{48}$",
"type": "string"
}
CYNDER-ACTION-SIGNATURE (header, required): EIP-191 signature bound to owner, operation, HTTP method, path, origin, idempotency key, exact body and raw query. Schema JSON
{
"type": "string"
}
Idempotency-Key (header, required): Schema JSON
{
"pattern": "^[A-Za-z0-9._-]{1,128}$",
"type": "string"
}
Request body
application/jsonSchema JSON
{
"additionalProperties": false,
"maxProperties": 0,
"type": "object"
}
Responses
200: Metadata only; mutation replay returns the original result, not a fresh lifecycle read. Use GET for current state. Cache-Control is private, no-store. WorkloadSecretMetadata
application/json WorkloadSecretMetadataSchema JSON
{
"$ref": "#/components/schemas/WorkloadSecretMetadata"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
413: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
GET /v1/workload-secrets/{secretID}
Read current metadata only, never secret material
Sign workload-secret:get with empty body and query and no Idempotency-Key. Cross-owner and unknown IDs return 404.
Parameters
secretID (path, required): Schema JSON
{
"pattern": "^sec_[a-f0-9]{48}$",
"type": "string"
}
CYNDER-ACTION-SIGNATURE (header, required): EIP-191 signature bound to owner, operation, HTTP method, path, origin, idempotency key, exact body and raw query. Schema JSON
{
"type": "string"
}
Request body
None specified.
Responses
200: Metadata only; mutation replay returns the original result, not a fresh lifecycle read. Use GET for current state. Cache-Control is private, no-store. WorkloadSecretMetadata
application/json WorkloadSecretMetadataSchema JSON
{
"$ref": "#/components/schemas/WorkloadSecretMetadata"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/workload-secrets/{secretID}/revoke
Irreversibly revoke use of a version while retaining encrypted audit state
Sign workload-secret:revoke with empty JSON object body and empty query. Does not revoke the upstream credential or erase old backups.
Parameters
secretID (path, required): Schema JSON
{
"pattern": "^sec_[a-f0-9]{48}$",
"type": "string"
}
CYNDER-ACTION-SIGNATURE (header, required): EIP-191 signature bound to owner, operation, HTTP method, path, origin, idempotency key, exact body and raw query. Schema JSON
{
"type": "string"
}
Idempotency-Key (header, required): Schema JSON
{
"pattern": "^[A-Za-z0-9._-]{1,128}$",
"type": "string"
}
Request body
application/jsonSchema JSON
{
"additionalProperties": false,
"maxProperties": 0,
"type": "object"
}
Responses
200: Metadata only; mutation replay returns the original result, not a fresh lifecycle read. Use GET for current state. Cache-Control is private, no-store. WorkloadSecretMetadata
application/json WorkloadSecretMetadataSchema JSON
{
"$ref": "#/components/schemas/WorkloadSecretMetadata"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
413: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
POST /v1/workload-secrets/{secretID}/rotate
Create a successor without rewriting or revoking the predecessor
Sign workload-secret:rotate. Empty query. New random ID, data key and nonce; supersedes references the predecessor. Revoked, expired, deleted or tampered predecessors fail closed. Revoke the old version separately when safe. This does not rotate the operator root or materialize Kubernetes Secrets.
Parameters
secretID (path, required): Schema JSON
{
"pattern": "^sec_[a-f0-9]{48}$",
"type": "string"
}
CYNDER-ACTION-SIGNATURE (header, required): EIP-191 signature bound to owner, operation, HTTP method, path, origin, idempotency key, exact body and raw query. Schema JSON
{
"type": "string"
}
Idempotency-Key (header, required): Schema JSON
{
"pattern": "^[A-Za-z0-9._-]{1,128}$",
"type": "string"
}
Request body
application/json WorkloadSecretWriteSchema JSON
{
"$ref": "#/components/schemas/WorkloadSecretWrite"
}
Responses
200: Metadata only; mutation replay returns the original result, not a fresh lifecycle read. Use GET for current state. Cache-Control is private, no-store. WorkloadSecretMetadata
application/json WorkloadSecretMetadataSchema JSON
{
"$ref": "#/components/schemas/WorkloadSecretMetadata"
}
201: New immutable version; metadata only. WorkloadSecretMetadata
application/json WorkloadSecretMetadataSchema JSON
{
"$ref": "#/components/schemas/WorkloadSecretMetadata"
}
400: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
401: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
404: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
409: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
413: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
415: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
429: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
500: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
503: Error envelope Error
application/json ErrorSchema JSON
{
"$ref": "#/components/schemas/Error"
}
Schema components
Definitions from the embedded OpenAPI contract. References above link here.
Action
Signed-owner allowlist; raw action payload is never returned. ActionID Digest TimestampSchema JSON
{
"additionalProperties": false,
"description": "Signed-owner allowlist; raw action payload is never returned.",
"properties": {
"action_id": {
"$ref": "#/components/schemas/ActionID"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"digest": {
"$ref": "#/components/schemas/Digest"
},
"idempotency_key": {
"type": "string"
},
"owner_id": {
"description": "CAIP-2 network plus lower-case EVM payer identity",
"type": "string"
},
"payload_digest": {
"$ref": "#/components/schemas/Digest"
},
"type": {
"enum": [
"DEPLOY",
"DEPLOY_VERSION",
"ROLLBACK_VERSION",
"ENROLL_WALLET",
"INVOKE",
"DELETE",
"REGISTER_ARTIFACT",
"RETAIN_ARTIFACT",
"ACQUIRE_LEASE",
"RENEW_LEASE",
"RESIZE_LEASE"
],
"type": "string"
}
},
"required": [
"action_id",
"type",
"owner_id",
"idempotency_key",
"payload_digest",
"digest",
"created_at"
],
"type": "object"
}ActionID
Schema JSON
{
"pattern": "^act_[0-9a-f]{32}$",
"type": "string"
}ActionState
ActionID ActionStatus Digest PublicFailureCode RefundStatus TimestampSchema JSON
{
"additionalProperties": false,
"properties": {
"action_id": {
"$ref": "#/components/schemas/ActionID"
},
"attempt": {
"minimum": 0,
"type": "integer"
},
"failure_code": {
"$ref": "#/components/schemas/PublicFailureCode"
},
"original_failure_code": {
"$ref": "#/components/schemas/PublicFailureCode"
},
"original_failure_receipt_digest": {
"$ref": "#/components/schemas/Digest"
},
"original_refund": {
"$ref": "#/components/schemas/RefundStatus"
},
"payment_amount": {
"pattern": "^[0-9]+$",
"type": "string"
},
"payment_asset": {
"type": "string"
},
"payment_pay_to": {
"type": "string"
},
"payment_status": {
"enum": [
"UNPAID",
"SETTLING",
"SETTLED",
"SETTLEMENT_UNKNOWN"
],
"type": "string"
},
"receipt_sequence": {
"minimum": 0,
"type": "integer"
},
"refund": {
"$ref": "#/components/schemas/RefundStatus"
},
"refund_policy_version": {
"description": "Immutable server-captured policy; not part of action signing.",
"type": "string"
},
"status": {
"$ref": "#/components/schemas/ActionStatus"
},
"updated_at": {
"$ref": "#/components/schemas/Timestamp"
}
},
"required": [
"action_id",
"status",
"attempt",
"payment_status",
"receipt_sequence",
"updated_at"
],
"type": "object"
}ActionStatus
WAITING_EFFECTIVE_TIME is nonterminal settled resize scheduling, never activation or success.Schema JSON
{
"description": "WAITING_EFFECTIVE_TIME is nonterminal settled resize scheduling, never activation or success.",
"enum": [
"PENDING",
"EXECUTING",
"WAITING_EFFECTIVE_TIME",
"SUCCEEDED",
"FAILED",
"UNKNOWN"
],
"type": "string"
}ActionView
Output is supplied only on execution. INVOKE returns owner workload JSON on successful execute and authenticated same-action settled replay without a fresh key/payment; GET omits INVOKE output. UNKNOWN requires reconciliation, not payment retry. Other actions return allowlisted identifiers/status. Reads never return legacy raw receipt output or stored tuples. Action ActionState JSONValue ReceiptSchema JSON
{
"additionalProperties": false,
"description": "Output is supplied only on execution. INVOKE returns owner workload JSON on successful execute and authenticated same-action settled replay without a fresh key/payment; GET omits INVOKE output. UNKNOWN requires reconciliation, not payment retry. Other actions return allowlisted identifiers/status. Reads never return legacy raw receipt output or stored tuples.",
"properties": {
"action": {
"$ref": "#/components/schemas/Action"
},
"output": {
"$ref": "#/components/schemas/JSONValue",
"description": "Owner-private execution output. Version activation output is filtered to safe identifiers/status; fresh readiness belongs to committed receipt deployment_evidence, not output. Never publish this field through Explorer."
},
"receipts": {
"items": {
"$ref": "#/components/schemas/Receipt"
},
"type": "array"
},
"state": {
"$ref": "#/components/schemas/ActionState"
}
},
"required": [
"action",
"state",
"receipts"
],
"type": "object"
}ArtifactActionRequest
CreateActionRequestSchema JSON
{
"allOf": [
{
"$ref": "#/components/schemas/CreateActionRequest"
},
{
"properties": {
"type": {
"enum": [
"REGISTER_ARTIFACT",
"RETAIN_ARTIFACT"
],
"type": "string"
}
},
"type": "object"
}
]
}ArtifactID
Schema JSON
{
"pattern": "^art_[0-9a-f]{32}$",
"type": "string"
}ConfigEnvironment
Non-secret values only; {} is valid. Limits are UTF-8 byte limits, not Unicode character counts: 128 keys, 128 bytes/key, 8192 bytes/value, 65536 total decoded key-plus-value bytes. Reject Unicode control characters (including NUL, newline and tab), U+FFFD, invalid UTF-8, duplicate keys (including escaped equivalents), and non-string or null values. The full HTTP request body is limited to 524288 bytes.Schema JSON
{
"additionalProperties": {
"maxLength": 8192,
"type": "string"
},
"description": "Non-secret values only; {} is valid. Limits are UTF-8 byte limits, not Unicode character counts: 128 keys, 128 bytes/key, 8192 bytes/value, 65536 total decoded key-plus-value bytes. Reject Unicode control characters (including NUL, newline and tab), U+FFFD, invalid UTF-8, duplicate keys (including escaped equivalents), and non-string or null values. The full HTTP request body is limited to 524288 bytes.",
"maxProperties": 128,
"propertyNames": {
"maxLength": 128,
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
"type": "string"
},
"type": "object"
}ConfigID
Opaque random owner version ID; cfg_legacy_empty_v1 is a reserved internal compatibility identity, not an owner record.Schema JSON
{
"description": "Opaque random owner version ID; cfg_legacy_empty_v1 is a reserved internal compatibility identity, not an owner record.",
"pattern": "^cfg_([0-9a-f]{32}|legacy_empty_v1)$",
"type": "string"
}ConfigList
ConfigVersionSchema JSON
{
"additionalProperties": false,
"properties": {
"configs": {
"items": {
"$ref": "#/components/schemas/ConfigVersion"
},
"type": "array"
}
},
"required": [
"configs"
],
"type": "object"
}ConfigVersion
ConfigEnvironment TimestampSchema JSON
{
"additionalProperties": false,
"properties": {
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"digest": {
"description": "SHA-256 of Go encoding/json compact map encoding, ASCII keys sorted lexically, HTML escaping enabled (including \u0026, \u003c, \u003e and U+2028/U+2029), no trailing newline. Only env participates, not owner/ID/lifecycle. Distinct from the raw-body signing digest.",
"pattern": "^sha256:[0-9a-f]{64}$",
"type": "string"
},
"env": {
"$ref": "#/components/schemas/ConfigEnvironment"
},
"id": {
"pattern": "^cfg_[0-9a-f]{32}$",
"type": "string"
},
"idempotency_key": {
"description": "Immutable original creation key, not the most recent lifecycle operation key.",
"type": "string"
},
"owner_id": {
"description": "Private owner identity derived from authenticated signer; never accepted from the request body.",
"type": "string"
},
"retain_until": {
"$ref": "#/components/schemas/Timestamp"
},
"revoked_at": {
"$ref": "#/components/schemas/Timestamp",
"description": "Present only when revoked; not null."
},
"state": {
"enum": [
"active",
"revoked"
],
"type": "string"
}
},
"required": [
"id",
"owner_id",
"env",
"digest",
"state",
"created_at",
"retain_until",
"idempotency_key"
],
"type": "object"
}CreateActionRequest
DeploymentHTTP DeploymentHealth DeploymentID DeploymentInputs Digest JSONValue PublicRoute TupleConfigBinding TupleSecretBinding VersionIDSchema JSON
{
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": {
"type": {
"const": "DEPLOY"
}
}
},
"then": {
"required": [
"image_digest",
"resource_class",
"timeout_seconds"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "DEPLOY_VERSION"
}
}
},
"then": {
"required": [
"deployment_id",
"image_digest",
"source_tag",
"timeout_seconds"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "ROLLBACK_VERSION"
}
}
},
"then": {
"required": [
"deployment_id",
"version_id",
"timeout_seconds"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "ENROLL_WALLET"
}
}
},
"then": {
"required": [
"profile_name",
"terms_accepted",
"requested_scopes"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "INVOKE"
}
}
},
"then": {
"required": [
"deployment_id",
"input",
"timeout_seconds"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "DELETE"
}
}
},
"then": {
"required": [
"deployment_id"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "REGISTER_ARTIFACT"
}
}
},
"then": {
"required": [
"repository",
"reference"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "RETAIN_ARTIFACT"
}
}
},
"then": {
"required": [
"repository",
"digest",
"retention_seconds"
]
}
},
{
"if": {
"properties": {
"type": {
"not": {
"const": "DEPLOY"
}
}
},
"required": [
"type"
]
},
"then": {
"not": {
"anyOf": [
{
"required": [
"http"
]
},
{
"required": [
"health"
]
},
{
"required": [
"routes"
]
},
{
"required": [
"configs"
]
},
{
"required": [
"secrets"
]
}
]
}
}
},
{
"if": {
"properties": {
"type": {
"enum": [
"ACQUIRE_LEASE",
"RENEW_LEASE",
"RESIZE_LEASE"
]
}
}
},
"then": {
"required": [
"deployment_id",
"quote_id",
"quote_digest"
]
}
},
{
"if": {
"properties": {
"type": {
"not": {
"const": "DEPLOY_VERSION"
}
}
},
"required": [
"type"
]
},
"then": {
"not": {
"required": [
"inputs"
]
}
}
}
],
"properties": {
"configs": {
"description": "DEPLOY-only immutable non-secret references, strictly ascending by version_id. Omission means empty; null is invalid. Owner, lifecycle, digest and collision-free destinations are validated before Kubernetes mutation. Valid bindings materialize deterministic immutable ConfigMaps for the pinned revision. No inline env values are accepted in actions.",
"items": {
"$ref": "#/components/schemas/TupleConfigBinding"
},
"type": "array",
"uniqueItems": true
},
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"description": {
"description": "Optional public description of what the service does and when to invoke it",
"maxLength": 500,
"type": "string"
},
"digest": {
"pattern": "^sha256:[0-9a-f]{64}$",
"type": "string"
},
"health": {
"$ref": "#/components/schemas/DeploymentHealth"
},
"http": {
"$ref": "#/components/schemas/DeploymentHTTP"
},
"image_digest": {
"pattern": "^[^@]+@sha256:[0-9a-f]{64}$",
"type": "string"
},
"input": {
"$ref": "#/components/schemas/JSONValue"
},
"inputs": {
"$ref": "#/components/schemas/DeploymentInputs",
"description": "DEPLOY_VERSION only. Omission expands committed inputs after creation signing of the original request. Owner response omits the expanded payload. Supply and retain complete explicit inputs for locally reviewable commitments and verify returned digests. Legacy prepared actions without signed inputs require reprepare; execution never inherits mutable current inputs."
},
"name": {
"description": "Optional public service name; Cynder generates a stable name from the deployment ID when omitted",
"maxLength": 80,
"minLength": 1,
"type": "string"
},
"profile_name": {
"maxLength": 80,
"minLength": 1,
"type": "string"
},
"quote_digest": {
"$ref": "#/components/schemas/Digest"
},
"quote_id": {
"$ref": "#/components/schemas/Digest"
},
"reference": {
"description": "Canonical immutable OCI manifest digest; the fetched manifest bytes must hash to this exact digest",
"pattern": "^sha256:[0-9a-f]{64}$",
"type": "string"
},
"repository": {
"minLength": 1,
"type": "string"
},
"requested_scopes": {
"items": {
"enum": [
"deploy",
"invoke",
"artifact"
],
"type": "string"
},
"maxItems": 3,
"minItems": 1,
"type": "array",
"uniqueItems": true
},
"resource_class": {
"enum": [
"mvi-small"
],
"type": "string"
},
"retention_seconds": {
"maximum": 31536000,
"minimum": 60,
"type": "integer"
},
"routes": {
"description": "Bounded public workload operation manifest shown by the deployment explorer",
"items": {
"$ref": "#/components/schemas/PublicRoute"
},
"maxItems": 32,
"type": "array",
"uniqueItems": true
},
"secrets": {
"description": "DEPLOY-only opaque secret-version references, strictly ascending by version_id. Omission means empty; null is invalid. No secret contents or content hashes. Owner, lifecycle, expiry, integrity and collision-free destinations are validated before Kubernetes mutation. Valid bindings materialize deterministic immutable Secrets for the pinned revision. Custody rotation does not automatically roll out deployments.",
"items": {
"$ref": "#/components/schemas/TupleSecretBinding"
},
"type": "array",
"uniqueItems": true
},
"source_tag": {
"description": "Complete mutable OCI tag reference in the same repository as image_digest; Cynder resolves it and verifies the digest before version deployment",
"example": "registry.example/workload:v2",
"maxLength": 128,
"minLength": 1,
"pattern": "^[^@]+:[A-Za-z0-9_][A-Za-z0-9._-]{0,127}$",
"type": "string"
},
"tags": {
"items": {
"pattern": "^[a-z0-9][a-z0-9-]{0,31}$",
"type": "string"
},
"maxItems": 8,
"type": "array",
"uniqueItems": true
},
"terms_accepted": {
"const": true,
"type": "boolean"
},
"timeout_seconds": {
"maximum": 300,
"minimum": 1,
"type": "integer"
},
"type": {
"enum": [
"DEPLOY",
"DEPLOY_VERSION",
"ROLLBACK_VERSION",
"ENROLL_WALLET",
"INVOKE",
"DELETE",
"REGISTER_ARTIFACT",
"RETAIN_ARTIFACT",
"ACQUIRE_LEASE",
"RENEW_LEASE",
"RESIZE_LEASE"
],
"type": "string"
},
"version_id": {
"$ref": "#/components/schemas/VersionID"
}
},
"required": [
"type"
],
"type": "object"
}CreateConfigRequest
ConfigEnvironmentSchema JSON
{
"additionalProperties": false,
"properties": {
"env": {
"$ref": "#/components/schemas/ConfigEnvironment"
}
},
"required": [
"env"
],
"type": "object"
}DedicatedActivationReadiness
Exact lease-authorized activation target, bound by store commit to the durable candidate and previous binding; does not replace immutable source tuple identities. ActionID TupleDigestSchema JSON
{
"additionalProperties": false,
"description": "Exact lease-authorized activation target, bound by store commit to the durable candidate and previous binding; does not replace immutable source tuple identities.",
"properties": {
"activation_id": {
"$ref": "#/components/schemas/ActionID"
},
"fence": {
"minimum": 1,
"type": "integer"
},
"lease_id": {
"minLength": 1,
"type": "string"
},
"namespace": {
"minLength": 1,
"type": "string"
},
"previous_binding_digest": {
"$ref": "#/components/schemas/TupleDigest"
},
"service": {
"minLength": 1,
"type": "string"
}
},
"required": [
"lease_id",
"activation_id",
"previous_binding_digest",
"fence",
"namespace",
"service"
],
"type": "object"
}Deployment
Signed-owner deployment allowlist. Internal routing, bindings and runtime output are excluded. ActionID DeploymentID Timestamp VersionIDSchema JSON
{
"additionalProperties": false,
"description": "Signed-owner deployment allowlist. Internal routing, bindings and runtime output are excluded.",
"properties": {
"active_activation_id": {
"$ref": "#/components/schemas/ActionID",
"description": "Committed activation identity (the activating action ID), distinct from historical version and runtime revision. Rollback creates a new activation and runtime revision while reusing the historical version unchanged."
},
"active_version_id": {
"$ref": "#/components/schemas/VersionID"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"delete_pending": {
"type": "boolean"
},
"deleted": {
"type": "boolean"
},
"deploy_action_id": {
"$ref": "#/components/schemas/ActionID"
},
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"description": {
"maxLength": 500,
"type": "string"
},
"image_digest": {
"type": "string"
},
"name": {
"maxLength": 80,
"minLength": 1,
"type": "string"
},
"public_http": {
"type": "boolean"
},
"public_url": {
"format": "uri",
"type": "string"
},
"resource_class": {
"type": "string"
},
"status": {
"enum": [
"DEPLOYMENT_PENDING",
"DEPLOYING",
"READY",
"DELETE_PENDING",
"DELETING",
"DELETED",
"DEPLOYMENT_FAILED",
"DELETE_FAILED"
],
"type": "string"
},
"tags": {
"items": {
"pattern": "^[a-z0-9][a-z0-9-]{0,31}$",
"type": "string"
},
"maxItems": 8,
"type": "array",
"uniqueItems": true
},
"updated_at": {
"$ref": "#/components/schemas/Timestamp"
}
},
"required": [
"deployment_id",
"deploy_action_id",
"image_digest",
"resource_class",
"status",
"delete_pending",
"deleted",
"created_at",
"updated_at"
],
"type": "object"
}DeploymentEvidence
DeploymentID TupleDigest VersionIDSchema JSON
{
"additionalProperties": false,
"properties": {
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"previous_active_version_id": {
"$ref": "#/components/schemas/VersionID"
},
"readiness": {
"const": "ready",
"type": "string"
},
"tuple_digest": {
"$ref": "#/components/schemas/TupleDigest"
},
"version_id": {
"$ref": "#/components/schemas/VersionID"
}
},
"required": [
"deployment_id",
"version_id",
"tuple_digest",
"readiness"
],
"type": "object"
}DeploymentHTTP
Schema JSON
{
"additionalProperties": false,
"properties": {
"port": {
"default": 8080,
"description": "Workload container HTTP port",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"public": {
"const": true,
"description": "Requests ordinary public HTTPS traffic at a Cynder-generated stable hostname",
"type": "boolean"
}
},
"required": [
"public"
],
"type": "object"
}DeploymentHealth
Schema JSON
{
"additionalProperties": false,
"properties": {
"liveness_path": {
"maxLength": 256,
"pattern": "^/[^?#\\r\\n]*$",
"type": "string"
},
"readiness_path": {
"default": "/health",
"maxLength": 256,
"pattern": "^/[^?#\\r\\n]*$",
"type": "string"
}
},
"type": "object"
}DeploymentID
Schema JSON
{
"pattern": "^dep_[0-9a-f]{32}$",
"type": "string"
}DeploymentInputs
Complete signed desired-input snapshot for DEPLOY_VERSION, not a merge patch. Every nested member is required with exact case; null, unknown and duplicate members are rejected. Empty arrays and empty runtime_class are explicit. Config and secret bindings must be strictly ascending by version_id and resolve to owned, usable immutable versions. No secret values, key names or secret hashes. Policy digest must match the complete supported policy. Public/private mode and the stable public hostname cannot change; port, health and routes are pinned inputs. Each changed input participates in the action digest; execution uses this snapshot rather than process defaults or the then-current active version. PublicRoute TupleConfigBinding TupleHTTP TupleHealth TuplePolicy TupleSecretBindingSchema JSON
{
"additionalProperties": false,
"description": "Complete signed desired-input snapshot for DEPLOY_VERSION, not a merge patch. Every nested member is required with exact case; null, unknown and duplicate members are rejected. Empty arrays and empty runtime_class are explicit. Config and secret bindings must be strictly ascending by version_id and resolve to owned, usable immutable versions. No secret values, key names or secret hashes. Policy digest must match the complete supported policy. Public/private mode and the stable public hostname cannot change; port, health and routes are pinned inputs. Each changed input participates in the action digest; execution uses this snapshot rather than process defaults or the then-current active version.",
"properties": {
"configs": {
"items": {
"$ref": "#/components/schemas/TupleConfigBinding"
},
"type": "array",
"uniqueItems": true
},
"health": {
"$ref": "#/components/schemas/TupleHealth"
},
"http": {
"$ref": "#/components/schemas/TupleHTTP"
},
"policy": {
"$ref": "#/components/schemas/TuplePolicy"
},
"routes": {
"items": {
"$ref": "#/components/schemas/PublicRoute"
},
"maxItems": 32,
"type": "array",
"uniqueItems": true
},
"secrets": {
"items": {
"$ref": "#/components/schemas/TupleSecretBinding"
},
"type": "array",
"uniqueItems": true
}
},
"required": [
"configs",
"secrets",
"policy",
"http",
"routes",
"health"
],
"type": "object"
}DeploymentTuple
Complete immutable owner-private tuple, schema version 1. New successful DEPLOY stores exact configs/secrets and pinned object identity arrays; omitted bindings produce empty arrays, never placeholder references or implied defaults. Valid nonempty bindings materialize immutable ConfigMaps and Secrets for the exact revision. Badger plus the matching authorized external root remains canonical; Kubernetes objects are recoverable materializations. Namespace RBAC is not a per-owner ACL; owner isolation is enforced by the resolver. Active reconciliation uses this tuple, never mutable deployment projections. Missing legacy tuple evidence fails closed per deployment with explicit pinned-input redeploy guidance; no silent synthesis. Digest is sha256 plus colon and lowercase hex over compact Go encoding/json typed JSON (HTML escaping enabled, no trailing newline), with digest present as an empty string, UTC timestamps, and every other required field included. Optional readiness.traffic_pending is omitted when false; when true it follows runtime_revision before route_ready in typed JSON. It denotes candidate-only evidence. Object key order is the order of names in each schema's required array (including nested tuple schemas and PublicRoute), not displayed property order or lexicographic map order. Config and secret references must already be strictly ascending by version_id; reject duplicates or ambiguous ordering. Identity arrays remain index-aligned, never sorted independently. Routes sort by method then path. Policy digest uses its required-array order with its own digest empty. No secret contents or hashes derived from secret contents enter this digest. ActionID DeploymentID Digest PublicRoute Timestamp TupleConfigBinding TupleDigest TupleHTTP TupleHealth TupleIdentities TuplePolicy TupleReadiness TupleSecretBinding VersionIDSchema JSON
{
"additionalProperties": false,
"description": "Complete immutable owner-private tuple, schema version 1. New successful DEPLOY stores exact configs/secrets and pinned object identity arrays; omitted bindings produce empty arrays, never placeholder references or implied defaults. Valid nonempty bindings materialize immutable ConfigMaps and Secrets for the exact revision. Badger plus the matching authorized external root remains canonical; Kubernetes objects are recoverable materializations. Namespace RBAC is not a per-owner ACL; owner isolation is enforced by the resolver. Active reconciliation uses this tuple, never mutable deployment projections. Missing legacy tuple evidence fails closed per deployment with explicit pinned-input redeploy guidance; no silent synthesis. Digest is sha256 plus colon and lowercase hex over compact Go encoding/json typed JSON (HTML escaping enabled, no trailing newline), with digest present as an empty string, UTC timestamps, and every other required field included. Optional readiness.traffic_pending is omitted when false; when true it follows runtime_revision before route_ready in typed JSON. It denotes candidate-only evidence. Object key order is the order of names in each schema's required array (including nested tuple schemas and PublicRoute), not displayed property order or lexicographic map order. Config and secret references must already be strictly ascending by version_id; reject duplicates or ambiguous ordering. Identity arrays remain index-aligned, never sorted independently. Routes sort by method then path. Policy digest uses its required-array order with its own digest empty. No secret contents or hashes derived from secret contents enter this digest.",
"properties": {
"action_digest": {
"$ref": "#/components/schemas/Digest"
},
"action_id": {
"$ref": "#/components/schemas/ActionID"
},
"configs": {
"items": {
"$ref": "#/components/schemas/TupleConfigBinding"
},
"type": "array",
"uniqueItems": true
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"digest": {
"$ref": "#/components/schemas/TupleDigest"
},
"health": {
"$ref": "#/components/schemas/TupleHealth"
},
"http": {
"$ref": "#/components/schemas/TupleHTTP"
},
"identities": {
"$ref": "#/components/schemas/TupleIdentities"
},
"image_digest": {
"pattern": "^[^@]+@sha256:[0-9a-f]{64}$",
"type": "string"
},
"owner": {
"minLength": 1,
"type": "string"
},
"policy": {
"$ref": "#/components/schemas/TuplePolicy"
},
"readiness": {
"$ref": "#/components/schemas/TupleReadiness"
},
"routes": {
"items": {
"$ref": "#/components/schemas/PublicRoute"
},
"maxItems": 32,
"type": "array",
"uniqueItems": true
},
"schema_version": {
"const": 1,
"type": "integer"
},
"secrets": {
"items": {
"$ref": "#/components/schemas/TupleSecretBinding"
},
"type": "array",
"uniqueItems": true
},
"source_tag": {
"description": "Provenance only; empty on initial DEPLOY",
"never desired image authority": null,
"type": "string"
},
"version_id": {
"$ref": "#/components/schemas/VersionID"
}
},
"required": [
"schema_version",
"digest",
"version_id",
"deployment_id",
"owner",
"action_id",
"action_digest",
"created_at",
"image_digest",
"source_tag",
"configs",
"secrets",
"policy",
"http",
"routes",
"health",
"identities",
"readiness"
],
"type": "object"
}DeploymentVersion
Owner-only immutable historical version summary. Only the tuple digest is returned; the complete tuple and its original readiness stay in persistence. Rollback retains this version unchanged while creating a fresh activation and runtime revision. Retained versions pin config and secret references but do not override revocation, expiry or integrity checks at use. Legacy image-only versions may omit tuple_digest and fail closed without complete evidence. ActionID DeploymentID ServiceLeaseSummary Timestamp TupleDigest VersionIDSchema JSON
{
"additionalProperties": false,
"description": "Owner-only immutable historical version summary. Only the tuple digest is returned; the complete tuple and its original readiness stay in persistence. Rollback retains this version unchanged while creating a fresh activation and runtime revision. Retained versions pin config and secret references but do not override revocation, expiry or integrity checks at use. Legacy image-only versions may omit tuple_digest and fail closed without complete evidence.",
"properties": {
"action_id": {
"$ref": "#/components/schemas/ActionID"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"image_digest": {
"pattern": "^[^@]+@sha256:[0-9a-f]{64}$",
"type": "string"
},
"service_lease": {
"$ref": "#/components/schemas/ServiceLeaseSummary"
},
"tuple_digest": {
"$ref": "#/components/schemas/TupleDigest"
},
"version_id": {
"$ref": "#/components/schemas/VersionID"
}
},
"required": [
"version_id",
"deployment_id",
"action_id",
"image_digest",
"created_at"
],
"type": "object"
}DeploymentVersionList
DeploymentID DeploymentVersion VersionIDSchema JSON
{
"properties": {
"active_version_id": {
"$ref": "#/components/schemas/VersionID"
},
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"versions": {
"items": {
"$ref": "#/components/schemas/DeploymentVersion"
},
"type": "array"
}
},
"required": [
"deployment_id",
"active_version_id",
"versions"
],
"type": "object"
}DeploymentVersionView
DeploymentVersionSchema JSON
{
"properties": {
"active": {
"type": "boolean"
},
"version": {
"$ref": "#/components/schemas/DeploymentVersion"
}
},
"required": [
"active",
"version"
],
"type": "object"
}Digest
Schema JSON
{
"pattern": "^[0-9a-f]{64}$",
"type": "string"
}Error
Schema JSON
{
"additionalProperties": false,
"properties": {
"error": {
"additionalProperties": false,
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
}
},
"required": [
"error"
],
"type": "object"
}ExplorerSearchResult
ActionIDSchema JSON
{
"additionalProperties": false,
"properties": {
"action_ids": {
"items": {
"$ref": "#/components/schemas/ActionID"
},
"type": "array"
},
"id": {
"maxLength": 128,
"minLength": 1,
"type": "string"
},
"kind": {
"enum": [
"transaction",
"settlement",
"deployment",
"artifact",
"receipt"
],
"type": "string"
}
},
"required": [
"kind",
"id",
"action_ids"
],
"type": "object"
}Health
Schema JSON
{
"additionalProperties": false,
"properties": {
"roles": {
"description": "Comma-separated active cynderd roles; present on registry-only processes.",
"type": "string"
},
"status": {
"const": "ok",
"type": "string"
}
},
"required": [
"status"
],
"type": "object"
}JSONValue
Schema JSON
{}LeaseActionRequest
Prepared through POST /v1/actions; execute only through existing signed, budget-approved x402 handshake. Signing action names acquire_lease / renew_lease / resize_lease; dynamic quote amount, never legacy deploy price. RESIZE_LEASE payment requires ReadyResize prerequisites; settled scheduling returns 202 WAITING_EFFECTIVE_TIME and recovery completes only activation. Missing prerequisites fail before new payment. Existing uncertain settlement uses reconciliation only, never resubmission. The node-backed resize adapter is opt-in and requires installed enforcing prerequisites. DeploymentID DigestSchema JSON
{
"additionalProperties": false,
"description": "Prepared through POST /v1/actions; execute only through existing signed, budget-approved x402 handshake. Signing action names acquire_lease / renew_lease / resize_lease; dynamic quote amount, never legacy deploy price. RESIZE_LEASE payment requires ReadyResize prerequisites; settled scheduling returns 202 WAITING_EFFECTIVE_TIME and recovery completes only activation. Missing prerequisites fail before new payment. Existing uncertain settlement uses reconciliation only, never resubmission. The node-backed resize adapter is opt-in and requires installed enforcing prerequisites.",
"properties": {
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"quote_digest": {
"$ref": "#/components/schemas/Digest"
},
"quote_id": {
"$ref": "#/components/schemas/Digest"
},
"type": {
"enum": [
"ACQUIRE_LEASE",
"RENEW_LEASE",
"RESIZE_LEASE"
],
"type": "string"
}
},
"required": [
"type",
"deployment_id",
"quote_id",
"quote_digest"
],
"type": "object"
}LeaseAmendment
Server-derived signed next-period amendment. EffectiveAt equals incumbent paid-through; EndsAt equals EffectiveAt plus quoted duration.Schema JSON
{
"additionalProperties": false,
"description": "Server-derived signed next-period amendment. EffectiveAt equals incumbent paid-through; EndsAt equals EffectiveAt plus quoted duration.",
"properties": {
"EffectiveAt": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"EndsAt": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"ID": {
"type": "string"
},
"PreviousResourceID": {
"type": "string"
}
},
"required": [
"ID",
"PreviousResourceID",
"EffectiveAt",
"EndsAt"
],
"type": "object"
}LeaseAtomicAmount
Canonical unsigned decimal asset atomic units; no floats or rounding.Schema JSON
{
"description": "Canonical unsigned decimal asset atomic units; no floats or rounding.",
"pattern": "^(0|[1-9][0-9]*)$",
"type": "string"
}LeaseItemizedPrice
Deterministic order is CPU, MEMORY, EPHEMERAL, STORAGE sorted by VolumeID, then FEE (including explicit zero fee). Compute sums the first three items; Storage sums only STORAGE items; Total = Compute + Storage + Fee = quote Amount. No omitted, duplicated, reordered or extra items are accepted. LeaseAtomicAmount LeasePriceItemSchema JSON
{
"additionalProperties": false,
"description": "Deterministic order is CPU, MEMORY, EPHEMERAL, STORAGE sorted by VolumeID, then FEE (including explicit zero fee). Compute sums the first three items; Storage sums only STORAGE items; Total = Compute + Storage + Fee = quote Amount. No omitted, duplicated, reordered or extra items are accepted.",
"properties": {
"Compute": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"Fee": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"Items": {
"items": {
"$ref": "#/components/schemas/LeasePriceItem"
},
"minItems": 4,
"type": "array"
},
"PolicyDigest": {
"type": "string"
},
"Storage": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"Total": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
}
},
"required": [
"Compute",
"Storage",
"Fee",
"Total",
"PolicyDigest",
"Items"
],
"type": "object"
}LeasePolicy
Owner-private capability discovery, not an enable switch, reservation, price quote or deployment/resource eligibility guarantee. Both enabled flags and ACQUIRE_LEASE/RENEW_LEASE follow LeaseCoordinator.Ready; RESIZE_LEASE additionally requires ReadyResize. A ready response has disabled_reason empty and pricing_policy equal to the actual validated operator snapshot (PascalCase keys). Disabled responses retain both flags false, disabled_reason lease_admission_not_configured_or_integrated, pricing_policy null and supported_paid_operations []. No defaults or prices are synthesized. Readiness is rechecked on each request; runtime readiness errors disable discovery without exposing private details. Per-request preflight still rejects public HTTP, unsupported volume shapes, missing material or storage authority and stale/unavailable evidence before payment. Policy GET does not run preflight or reserve capacity. Daemon prerequisites are opt-in and require verified installed enforcement. Legacy policy remains LEAVE_UNCHANGED. Never automatically downgrade signing or pay from this response. LeasePricingPolicySnapshotSchema JSON
{
"additionalProperties": false,
"description": "Owner-private capability discovery, not an enable switch, reservation, price quote or deployment/resource eligibility guarantee. Both enabled flags and ACQUIRE_LEASE/RENEW_LEASE follow LeaseCoordinator.Ready; RESIZE_LEASE additionally requires ReadyResize. A ready response has disabled_reason empty and pricing_policy equal to the actual validated operator snapshot (PascalCase keys). Disabled responses retain both flags false, disabled_reason lease_admission_not_configured_or_integrated, pricing_policy null and supported_paid_operations []. No defaults or prices are synthesized. Readiness is rechecked on each request; runtime readiness errors disable discovery without exposing private details. Per-request preflight still rejects public HTTP, unsupported volume shapes, missing material or storage authority and stale/unavailable evidence before payment. Policy GET does not run preflight or reserve capacity. Daemon prerequisites are opt-in and require verified installed enforcement. Legacy policy remains LEAVE_UNCHANGED. Never automatically downgrade signing or pay from this response.",
"properties": {
"admission_enabled": {
"type": "boolean"
},
"disabled_reason": {
"type": "string"
},
"legacy_policy": {
"enum": [
"LEAVE_UNCHANGED"
],
"type": "string"
},
"pricing_policy": {
"oneOf": [
{
"$ref": "#/components/schemas/LeasePricingPolicySnapshot"
},
{
"type": "null"
}
]
},
"quote_enabled": {
"type": "boolean"
},
"schema_version": {
"type": "string"
},
"supported_paid_operations": {
"items": {
"enum": [
"ACQUIRE_LEASE",
"RENEW_LEASE",
"RESIZE_LEASE"
],
"type": "string"
},
"type": "array",
"uniqueItems": true
}
},
"required": [
"schema_version",
"admission_enabled",
"quote_enabled",
"disabled_reason",
"legacy_policy",
"pricing_policy",
"supported_paid_operations"
],
"type": "object"
}LeasePriceItem
Amount = Rate * Units * Seconds * Multiplier with arbitrary-precision integer arithmetic. Compute Units are per-replica requests, Seconds is quote Duration and Multiplier is max_instances, never min_instances or limits. STORAGE Units is declared volume size, Seconds is StorageDuration and Multiplier is one. FEE Rate is the explicit flat fee; all three factors are one. VolumeID/Tier are empty except for STORAGE, where both must match the sorted resource volume and policy tier. No usage overages or refunds are implied by this price evidence. LeaseAtomicAmountSchema JSON
{
"additionalProperties": false,
"description": "Amount = Rate * Units * Seconds * Multiplier with arbitrary-precision integer arithmetic. Compute Units are per-replica requests, Seconds is quote Duration and Multiplier is max_instances, never min_instances or limits. STORAGE Units is declared volume size, Seconds is StorageDuration and Multiplier is one. FEE Rate is the explicit flat fee; all three factors are one. VolumeID/Tier are empty except for STORAGE, where both must match the sorted resource volume and policy tier. No usage overages or refunds are implied by this price evidence.",
"properties": {
"Amount": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"Kind": {
"enum": [
"CPU",
"MEMORY",
"EPHEMERAL",
"STORAGE",
"FEE"
],
"type": "string"
},
"Multiplier": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Rate": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"Seconds": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Tier": {
"type": "string"
},
"Units": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"VolumeID": {
"type": "string"
}
},
"required": [
"Kind",
"VolumeID",
"Tier",
"Rate",
"Units",
"Seconds",
"Multiplier",
"Amount"
],
"type": "object"
}LeasePricingPolicySnapshot
Exact existing cynder-pricing-policy/v1 data; no implicit defaults. CPU rate is atomic units per millicore-second; memory, ephemeral and storage rates are per byte-second. Fee is one explicit flat atomic-unit charge. LeaseAtomicAmountSchema JSON
{
"additionalProperties": false,
"description": "Exact existing cynder-pricing-policy/v1 data; no implicit defaults. CPU rate is atomic units per millicore-second; memory, ephemeral and storage rates are per byte-second. Fee is one explicit flat atomic-unit charge.",
"properties": {
"ActivationWindow": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Asset": {
"type": "string"
},
"CPU": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"CapacityPolicy": {
"type": "string"
},
"Ephemeral": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"Fee": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"Grace": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"ID": {
"type": "string"
},
"MaxDuration": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Memory": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"MinDuration": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Network": {
"type": "string"
},
"Payee": {
"type": "string"
},
"Provider": {
"type": "string"
},
"RefundPolicy": {
"type": "string"
},
"Storage": {
"additionalProperties": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"description": "Tier to rate map; null and empty map retain distinct existing policy digest bytes. Every attached volume requires an explicit tier rate.",
"type": [
"object",
"null"
]
},
"TrafficPolicy": {
"type": "string"
},
"Version": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
}
},
"required": [
"ID",
"Provider",
"Network",
"Asset",
"Payee",
"RefundPolicy",
"TrafficPolicy",
"CapacityPolicy",
"Version",
"MinDuration",
"MaxDuration",
"Grace",
"ActivationWindow",
"CPU",
"Memory",
"Ephemeral",
"Fee",
"Storage"
],
"type": "object"
}LeaseQuote
New issuance returns itemized v2. Durable idempotent replay may return the exact historical unversioned v1 quote, never an upgraded digest. LeaseQuoteLegacy LeaseQuoteV2Schema JSON
{
"description": "New issuance returns itemized v2. Durable idempotent replay may return the exact historical unversioned v1 quote, never an upgraded digest.",
"oneOf": [
{
"$ref": "#/components/schemas/LeaseQuoteV2"
},
{
"$ref": "#/components/schemas/LeaseQuoteLegacy"
}
]
}LeaseQuoteBreakdown
Immutable non-secret snapshots are persisted with the quote. Recompute policy digest from Policy using cynder-pricing-policy/v1 plus newline and sorted-key JSON; recompute Resource identity as documented by ResourceSpec. Policy and resource identity, totals, duration, currency, provider, payee, grace, traffic/refund policies and activation window must match the quote. StorageDuration is zero for compute-only issuance. For exactly one already independently funded volume, IndependentStorage is true, Resource retains the volume and storage obligation identity, and Price.Storage remains zero with no STORAGE item. IndependentStorage is absent for empty-volume quotes; absence with a volume is invalid. This quote never purchases or extends storage funding. Public HTTP with volumes remains unsupported. LeaseItemizedPrice LeasePricingPolicySnapshot ResourceSpecSchema JSON
{
"additionalProperties": false,
"description": "Immutable non-secret snapshots are persisted with the quote. Recompute policy digest from Policy using cynder-pricing-policy/v1 plus newline and sorted-key JSON; recompute Resource identity as documented by ResourceSpec. Policy and resource identity, totals, duration, currency, provider, payee, grace, traffic/refund policies and activation window must match the quote. StorageDuration is zero for compute-only issuance. For exactly one already independently funded volume, IndependentStorage is true, Resource retains the volume and storage obligation identity, and Price.Storage remains zero with no STORAGE item. IndependentStorage is absent for empty-volume quotes; absence with a volume is invalid. This quote never purchases or extends storage funding. Public HTTP with volumes remains unsupported.",
"properties": {
"IndependentStorage": {
"const": true,
"description": "Present only for an independently funded single-volume compute quote.",
"type": "boolean"
},
"Policy": {
"$ref": "#/components/schemas/LeasePricingPolicySnapshot"
},
"Price": {
"$ref": "#/components/schemas/LeaseItemizedPrice"
},
"Resource": {
"$ref": "#/components/schemas/ResourceSpec"
},
"StorageDuration": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
}
},
"required": [
"Policy",
"Resource",
"StorageDuration",
"Price"
],
"type": "object"
}LeaseQuoteLegacy
Exact Go wire keys are PascalCase. Amount is decimal atomic units. Digest = SHA256(cynder-lease-quote/v1 + newline + sorted-key JSON of all fields with Digest set to empty string). Quote is a capacity reservation, NOT settlement or activation. Historical quotes omit SchemaVersion and Breakdown; their signed bytes are preserved. Identical idempotency replay retains the original quote and TTL, including expired quotes. Changed request bodies conflict.Schema JSON
{
"additionalProperties": false,
"description": "Exact Go wire keys are PascalCase. Amount is decimal atomic units. Digest = SHA256(cynder-lease-quote/v1 + newline + sorted-key JSON of all fields with Digest set to empty string). Quote is a capacity reservation, NOT settlement or activation. Historical quotes omit SchemaVersion and Breakdown; their signed bytes are preserved. Identical idempotency replay retains the original quote and TTL, including expired quotes. Changed request bodies conflict.",
"properties": {
"ActivationDeadline": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Amount": {
"type": "string"
},
"Asset": {
"type": "string"
},
"Deployment": {
"type": "string"
},
"Digest": {
"type": "string"
},
"Duration": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"ExpectedSeq": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"ExpiresAt": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Grace": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"HoldID": {
"type": "string"
},
"ID": {
"type": "string"
},
"LeaseID": {
"type": "string"
},
"Network": {
"type": "string"
},
"Operation": {
"type": "string"
},
"Owner": {
"type": "string"
},
"Payee": {
"type": "string"
},
"PolicyDigest": {
"type": "string"
},
"PredecessorPaidThrough": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Provider": {
"type": "string"
},
"RefundPolicy": {
"type": "string"
},
"ResourceID": {
"type": "string"
},
"TrafficPolicy": {
"type": "string"
}
},
"required": [
"ID",
"Digest",
"Owner",
"Deployment",
"ResourceID",
"Provider",
"HoldID",
"LeaseID",
"Operation",
"PolicyDigest",
"Network",
"Asset",
"Payee",
"Amount",
"RefundPolicy",
"TrafficPolicy",
"ExpectedSeq",
"Duration",
"Grace",
"ExpiresAt",
"ActivationDeadline",
"PredecessorPaidThrough"
],
"type": "object"
}LeaseQuoteRequest
ResourceSpecSchema JSON
{
"additionalProperties": false,
"properties": {
"duration_seconds": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"operation": {
"enum": [
"ACQUIRE",
"RENEW",
"RESIZE"
],
"type": "string"
},
"resource_spec": {
"$ref": "#/components/schemas/ResourceSpec"
}
},
"required": [
"operation",
"resource_spec",
"duration_seconds"
],
"type": "object"
}LeaseQuoteV2
PascalCase wire fields. SHA256 of cynder-lease-quote/v2 plus newline plus sorted-key canonical JSON of ALL fields with Digest set to empty string, including SchemaVersion and the complete Breakdown. Same constrained printable-ASCII, safe-integer canonicalization as v1. No signatures in this object; the authenticated control origin and owner action signature remain required. Hash consistency does not authorize rates or payment. LeaseAmendment LeaseAtomicAmount LeaseQuoteBreakdownSchema JSON
{
"additionalProperties": false,
"allOf": [
{
"else": {
"not": {
"required": [
"Amendment"
]
}
},
"if": {
"properties": {
"Operation": {
"const": "RESIZE"
}
},
"required": [
"Operation"
]
},
"then": {
"required": [
"Amendment"
]
}
}
],
"description": "PascalCase wire fields. SHA256 of cynder-lease-quote/v2 plus newline plus sorted-key canonical JSON of ALL fields with Digest set to empty string, including SchemaVersion and the complete Breakdown. Same constrained printable-ASCII, safe-integer canonicalization as v1. No signatures in this object; the authenticated control origin and owner action signature remain required. Hash consistency does not authorize rates or payment.",
"properties": {
"ActivationDeadline": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Amendment": {
"$ref": "#/components/schemas/LeaseAmendment"
},
"Amount": {
"$ref": "#/components/schemas/LeaseAtomicAmount"
},
"Asset": {
"type": "string"
},
"Breakdown": {
"$ref": "#/components/schemas/LeaseQuoteBreakdown"
},
"Deployment": {
"type": "string"
},
"Digest": {
"type": "string"
},
"Duration": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"ExpectedSeq": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"ExpiresAt": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Grace": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"HoldID": {
"type": "string"
},
"ID": {
"type": "string"
},
"LeaseID": {
"type": "string"
},
"Network": {
"type": "string"
},
"Operation": {
"enum": [
"ACQUIRE",
"RENEW",
"RESIZE"
],
"type": "string"
},
"Owner": {
"type": "string"
},
"Payee": {
"type": "string"
},
"PolicyDigest": {
"type": "string"
},
"PredecessorPaidThrough": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"Provider": {
"type": "string"
},
"RefundPolicy": {
"type": "string"
},
"ResourceID": {
"type": "string"
},
"SchemaVersion": {
"enum": [
"cynder-lease-quote/v2"
],
"type": "string"
},
"TrafficPolicy": {
"type": "string"
}
},
"required": [
"SchemaVersion",
"Breakdown",
"ID",
"Digest",
"Owner",
"Deployment",
"ResourceID",
"Provider",
"HoldID",
"LeaseID",
"Operation",
"PolicyDigest",
"Network",
"Asset",
"Payee",
"Amount",
"RefundPolicy",
"TrafficPolicy",
"ExpectedSeq",
"Duration",
"Grace",
"ExpiresAt",
"ActivationDeadline",
"PredecessorPaidThrough"
],
"type": "object"
}LeaseReplica
Schema JSON
{
"additionalProperties": false,
"properties": {
"cpu_limit_millicores": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"cpu_request_millicores": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"ephemeral_limit_bytes": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"ephemeral_request_bytes": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"memory_limit_bytes": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"memory_request_bytes": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
}
},
"required": [
"cpu_request_millicores",
"cpu_limit_millicores",
"memory_request_bytes",
"memory_limit_bytes",
"ephemeral_request_bytes",
"ephemeral_limit_bytes"
],
"type": "object"
}LeaseVolume
Schema JSON
{
"additionalProperties": false,
"properties": {
"access_mode": {
"type": "string"
},
"mount_path": {
"type": "string"
},
"retention_policy_id": {
"type": "string"
},
"size_bytes": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"storage_obligation_id": {
"type": "string"
},
"tier_id": {
"type": "string"
},
"volume_id": {
"type": "string"
}
},
"required": [
"volume_id",
"tier_id",
"mount_path",
"access_mode",
"retention_policy_id",
"storage_obligation_id",
"size_bytes"
],
"type": "object"
}PublicActionDetail
PublicActionSummary PublicReceiptEventSchema JSON
{
"additionalProperties": false,
"properties": {
"action": {
"$ref": "#/components/schemas/PublicActionSummary"
},
"timeline": {
"items": {
"$ref": "#/components/schemas/PublicReceiptEvent"
},
"type": "array"
}
},
"required": [
"action",
"timeline"
],
"type": "object"
}PublicActionList
PublicActionSummarySchema JSON
{
"additionalProperties": false,
"properties": {
"actions": {
"items": {
"$ref": "#/components/schemas/PublicActionSummary"
},
"type": "array"
},
"limit": {
"maximum": 50,
"minimum": 1,
"type": "integer"
}
},
"required": [
"actions",
"limit"
],
"type": "object"
}PublicActionSummary
ActionID ArtifactID DeploymentID PublicFailureCode PublicFailureMessage RefundStatus ServiceLeaseSummary TimestampSchema JSON
{
"additionalProperties": false,
"properties": {
"action_id": {
"$ref": "#/components/schemas/ActionID"
},
"amount_atomic": {
"pattern": "^[0-9]*$",
"type": "string"
},
"artifact_id": {
"$ref": "#/components/schemas/ArtifactID"
},
"asset": {
"type": "string"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"failure_code": {
"$ref": "#/components/schemas/PublicFailureCode"
},
"failure_message": {
"$ref": "#/components/schemas/PublicFailureMessage"
},
"network": {
"type": "string"
},
"payment_status": {
"enum": [
"SETTLED"
],
"type": "string"
},
"refund": {
"$ref": "#/components/schemas/RefundStatus"
},
"service_lease": {
"$ref": "#/components/schemas/ServiceLeaseSummary"
},
"settlement_tx_hash": {
"pattern": "^0x[0-9a-fA-F]{64}$",
"type": "string"
},
"status": {
"enum": [
"SUCCEEDED",
"FAILED"
],
"type": "string"
},
"type": {
"enum": [
"DEPLOY",
"DEPLOY_VERSION",
"ROLLBACK_VERSION",
"INVOKE",
"DELETE",
"REGISTER_ARTIFACT",
"RETAIN_ARTIFACT",
"ACQUIRE_LEASE",
"RENEW_LEASE",
"RESIZE_LEASE"
],
"type": "string"
},
"updated_at": {
"$ref": "#/components/schemas/Timestamp"
}
},
"required": [
"action_id",
"type",
"status",
"payment_status",
"amount_atomic",
"network",
"asset",
"created_at",
"updated_at"
],
"type": "object"
}PublicArtifactList
PublicArtifactSummarySchema JSON
{
"additionalProperties": false,
"properties": {
"artifacts": {
"items": {
"$ref": "#/components/schemas/PublicArtifactSummary"
},
"type": "array"
},
"limit": {
"maximum": 50,
"minimum": 1,
"type": "integer"
}
},
"required": [
"artifacts",
"limit"
],
"type": "object"
}PublicArtifactSummary
ArtifactID TimestampSchema JSON
{
"additionalProperties": false,
"properties": {
"artifact_id": {
"$ref": "#/components/schemas/ArtifactID"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"signature_status": {
"type": "string"
},
"size_bytes": {
"minimum": 0,
"type": "integer"
},
"status": {
"type": "string"
},
"updated_at": {
"$ref": "#/components/schemas/Timestamp"
},
"vulnerability_status": {
"type": "string"
}
},
"required": [
"artifact_id",
"status",
"size_bytes",
"created_at",
"updated_at"
],
"type": "object"
}PublicDeploymentChange
ActionID Timestamp VersionIDSchema JSON
{
"additionalProperties": false,
"properties": {
"action_id": {
"$ref": "#/components/schemas/ActionID"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"kind": {
"enum": [
"INITIAL",
"DEPLOY_VERSION",
"ROLLBACK_VERSION"
],
"type": "string"
},
"previous_version_id": {
"$ref": "#/components/schemas/VersionID"
},
"summary": {
"type": "string"
},
"title": {
"type": "string"
},
"version_id": {
"$ref": "#/components/schemas/VersionID"
}
},
"required": [
"kind",
"title",
"summary",
"action_id",
"version_id",
"created_at"
],
"type": "object"
}PublicDeploymentDetail
PublicActionSummary PublicDeploymentChange PublicDeploymentSummary PublicDeploymentVersion ServiceLeaseProjectionSchema JSON
{
"additionalProperties": false,
"properties": {
"changelog": {
"items": {
"$ref": "#/components/schemas/PublicDeploymentChange"
},
"type": "array"
},
"deployment": {
"$ref": "#/components/schemas/PublicDeploymentSummary"
},
"description": {
"maxLength": 500,
"type": "string"
},
"service_lease": {
"$ref": "#/components/schemas/ServiceLeaseProjection"
},
"tags": {
"items": {
"pattern": "^[a-z0-9][a-z0-9-]{0,31}$",
"type": "string"
},
"maxItems": 8,
"type": "array",
"uniqueItems": true
},
"transactions": {
"items": {
"$ref": "#/components/schemas/PublicActionSummary"
},
"type": "array"
},
"versions": {
"items": {
"$ref": "#/components/schemas/PublicDeploymentVersion"
},
"type": "array"
}
},
"required": [
"deployment",
"changelog",
"versions",
"transactions"
],
"type": "object"
}PublicDeploymentList
PublicDeploymentSummarySchema JSON
{
"additionalProperties": false,
"properties": {
"deployments": {
"items": {
"$ref": "#/components/schemas/PublicDeploymentSummary"
},
"type": "array"
},
"limit": {
"maximum": 50,
"minimum": 1,
"type": "integer"
}
},
"required": [
"deployments",
"limit"
],
"type": "object"
}PublicDeploymentSummary
ActionID DeploymentID PublicRoute ServiceLeaseSummary Timestamp VersionIDSchema JSON
{
"additionalProperties": false,
"properties": {
"active_version_id": {
"$ref": "#/components/schemas/VersionID"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"deleted_at": {
"$ref": "#/components/schemas/Timestamp"
},
"deploy_action_id": {
"$ref": "#/components/schemas/ActionID"
},
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"liveness_path": {
"pattern": "^/",
"type": "string"
},
"name": {
"maxLength": 80,
"minLength": 1,
"type": "string"
},
"public_http": {
"type": "boolean"
},
"public_url": {
"format": "uri",
"pattern": "^https://",
"type": "string"
},
"readiness_path": {
"pattern": "^/",
"type": "string"
},
"route_status": {
"type": "string"
},
"routes": {
"items": {
"$ref": "#/components/schemas/PublicRoute"
},
"maxItems": 32,
"type": "array",
"uniqueItems": true
},
"service_lease": {
"$ref": "#/components/schemas/ServiceLeaseSummary"
},
"status": {
"type": "string"
},
"updated_at": {
"$ref": "#/components/schemas/Timestamp"
}
},
"required": [
"deployment_id",
"name",
"status",
"deploy_action_id",
"created_at",
"updated_at"
],
"type": "object"
}PublicDeploymentVersion
ActionID ServiceLeaseSummary Timestamp VersionIDSchema JSON
{
"additionalProperties": false,
"properties": {
"action_id": {
"$ref": "#/components/schemas/ActionID"
},
"active": {
"type": "boolean"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"service_lease": {
"$ref": "#/components/schemas/ServiceLeaseSummary"
},
"version_id": {
"$ref": "#/components/schemas/VersionID"
}
},
"required": [
"version_id",
"action_id",
"active",
"created_at"
],
"type": "object"
}PublicFailureCode
Schema JSON
{
"enum": [
"ACTION_FAILED",
"RUNTIME_REJECTED",
"READINESS_REJECTED",
"RECOVERY_EXHAUSTED",
"REGISTRATION_MANIFEST_UNAVAILABLE",
"REGISTRATION_BLOB_UNAVAILABLE",
"REGISTRATION_DIGEST_MISMATCH",
"REGISTRATION_VALIDATION_FAILED"
],
"type": "string"
}PublicFailureMessage
Schema JSON
{
"enum": [
"The action failed after payment settlement.",
"The runtime rejected this deployment.",
"The deployment did not pass its readiness check.",
"The deployment outcome could not be confirmed.",
"The immutable manifest could not be read.",
"A required artifact blob could not be verified.",
"The requested immutable digest did not match the manifest.",
"The artifact failed validation."
],
"type": "string"
}PublicReceiptEvent
PublicFailureCode PublicFailureMessage ReceiptID ReceiptKind TimestampSchema JSON
{
"additionalProperties": false,
"properties": {
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"failure_code": {
"$ref": "#/components/schemas/PublicFailureCode"
},
"failure_message": {
"$ref": "#/components/schemas/PublicFailureMessage"
},
"kind": {
"$ref": "#/components/schemas/ReceiptKind"
},
"receipt_id": {
"$ref": "#/components/schemas/ReceiptID"
},
"status": {
"enum": [
"PENDING",
"EXECUTING",
"WAITING_EFFECTIVE_TIME",
"SUCCEEDED",
"FAILED",
"UNKNOWN"
],
"type": "string"
}
},
"required": [
"receipt_id",
"kind",
"status",
"created_at"
],
"type": "object"
}PublicRoute
Schema JSON
{
"additionalProperties": false,
"properties": {
"method": {
"enum": [
"GET",
"HEAD",
"POST",
"PUT",
"PATCH",
"DELETE",
"OPTIONS"
],
"type": "string"
},
"path": {
"maxLength": 256,
"pattern": "^/[^?#\\r\\n]*$",
"type": "string"
}
},
"required": [
"method",
"path"
],
"type": "object"
}Ready
Schema JSON
{
"additionalProperties": false,
"properties": {
"roles": {
"description": "Comma-separated active cynderd roles; present on registry-only processes.",
"type": "string"
},
"status": {
"const": "ready",
"type": "string"
}
},
"required": [
"status"
],
"type": "object"
}Receipt
Owner receipt allowlist includes safe version 3 digest inputs and output commitments, not raw replay output. Legacy receipts omit private preimages and require internal custody for verification. See docs/private-operations.md. ActionID ActionStatus ArtifactID DeploymentEvidence Digest ReceiptID ReceiptKind ReceiptType TimestampSchema JSON
{
"additionalProperties": false,
"description": "Owner receipt allowlist includes safe version 3 digest inputs and output commitments, not raw replay output. Legacy receipts omit private preimages and require internal custody for verification. See docs/private-operations.md.",
"properties": {
"action_digest": {
"$ref": "#/components/schemas/Digest"
},
"action_evidence": {
"additionalProperties": false,
"properties": {
"output_sha256": {
"pattern": "^[0-9a-f]{64}$",
"type": "string"
}
},
"required": [
"output_sha256"
],
"type": "object"
},
"action_id": {
"$ref": "#/components/schemas/ActionID"
},
"completed_at": {
"$ref": "#/components/schemas/Timestamp"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"deployment_evidence": {
"$ref": "#/components/schemas/DeploymentEvidence"
},
"deployment_id": {
"type": "string"
},
"digest": {
"$ref": "#/components/schemas/Digest"
},
"error": {
"enum": [
"action transition failed",
"REGISTRATION_MANIFEST_UNAVAILABLE",
"REGISTRATION_BLOB_UNAVAILABLE",
"REGISTRATION_DIGEST_MISMATCH",
"REGISTRATION_VALIDATION_FAILED"
],
"type": "string"
},
"final_status": {
"type": "string"
},
"kind": {
"$ref": "#/components/schemas/ReceiptKind"
},
"node_id": {
"type": "string"
},
"output": {
"additionalProperties": false,
"properties": {
"artifact_id": {
"$ref": "#/components/schemas/ArtifactID"
}
},
"required": [
"artifact_id"
],
"type": "object"
},
"payee": {
"type": "string"
},
"payer": {
"type": "string"
},
"payment_id": {
"type": "string"
},
"payment_status": {
"enum": [
"UNPAID",
"SETTLING",
"SETTLED",
"SETTLEMENT_UNKNOWN"
],
"type": "string"
},
"previous_receipt_digest": {
"$ref": "#/components/schemas/Digest"
},
"receipt_id": {
"$ref": "#/components/schemas/ReceiptID"
},
"receipt_type": {
"$ref": "#/components/schemas/ReceiptType"
},
"receipt_version": {
"enum": [
"1",
"2",
"3"
],
"type": "string"
},
"recovery_evidence": {
"additionalProperties": false,
"properties": {
"previous_failed_receipt_digest": {
"$ref": "#/components/schemas/Digest"
},
"previous_failed_sequence": {
"minimum": 1,
"type": "integer"
},
"recovery": {
"const": "OWNER_AUTHORIZED_REGISTRATION",
"type": "string"
}
},
"required": [
"recovery",
"previous_failed_sequence",
"previous_failed_receipt_digest"
],
"type": "object"
},
"sequence": {
"minimum": 1,
"type": "integer"
},
"settlement_hash": {
"type": "string"
},
"started_at": {
"$ref": "#/components/schemas/Timestamp"
},
"status": {
"$ref": "#/components/schemas/ActionStatus"
},
"usdc_amount": {
"type": "string"
}
},
"required": [
"receipt_version",
"receipt_type",
"receipt_id",
"action_id",
"action_digest",
"sequence",
"kind",
"status",
"digest",
"created_at",
"final_status"
],
"type": "object"
}ReceiptID
Schema JSON
{
"pattern": "^rcpt_[0-9a-f]{32}$",
"type": "string"
}ReceiptKind
Schema JSON
{
"enum": [
"ACCEPTED",
"EXECUTING",
"WAITING_EFFECTIVE_TIME",
"DISPATCHED",
"COMPLETED",
"FAILED",
"UNKNOWN",
"PAYMENT_SETTLING",
"PAYMENT_SETTLEMENT_UNKNOWN",
"PAYMENT_SETTLED"
],
"type": "string"
}ReceiptType
Schema JSON
{
"enum": [
"ACCEPTED",
"EXECUTING",
"WAITING_EFFECTIVE_TIME",
"DISPATCHED",
"COMPLETED",
"FAILED",
"UNKNOWN",
"PAYMENT_SETTLING",
"PAYMENT_SETTLEMENT_UNKNOWN",
"PAYMENT_SETTLED",
"DEPLOYMENT_RECEIPT",
"INVOCATION_RECEIPT",
"DELETION_RECEIPT"
],
"type": "string"
}RefundStatus
Read-only refund obligation and transfer projection; never changes original SETTLED payment or action signing. Missing historical evidence is not confirmation. Policy is captured immutably at creation. No GET sends money. TimestampSchema JSON
{
"additionalProperties": false,
"description": "Read-only refund obligation and transfer projection; never changes original SETTLED payment or action signing. Missing historical evidence is not confirmation. Policy is captured immutably at creation. No GET sends money.",
"properties": {
"amount": {
"description": "Original service charge in atomic units; gas is separate.",
"pattern": "^[0-9]+$",
"type": "string"
},
"asset": {
"type": "string"
},
"blocker": {
"enum": [
"EXECUTION_DISABLED_OR_UNCONFIGURED",
"TRANSFER_RECONCILIATION_REQUIRED",
"CANONICAL_TRANSFER_REVERTED"
],
"type": "string"
},
"confirmation_state": {
"type": "string"
},
"created_at": {
"$ref": "#/components/schemas/Timestamp"
},
"network": {
"type": "string"
},
"original_payment_reference": {
"type": "string"
},
"policy_version": {
"type": "string"
},
"reason": {
"type": "string"
},
"status": {
"enum": [
"NOT_APPLICABLE",
"RECONCILIATION_REQUIRED",
"REVIEW_REQUIRED",
"OWED",
"PENDING",
"CONFIRMED"
],
"type": "string"
},
"transaction_hash": {
"pattern": "^0x[0-9a-fA-F]{64}$",
"type": "string"
},
"updated_at": {
"$ref": "#/components/schemas/Timestamp"
}
},
"required": [
"policy_version",
"status",
"reason",
"created_at",
"updated_at"
],
"type": "object"
}ResourceSpec
Strict constrained canonical JSON: no duplicate/unknown/null fields; printable ASCII excluding quotes, backslash, <, >, &; integers only. Positive requests <= limits; limit * max_instances <= safe integer maximum. Resource ID is SHA256(schema + newline + sorted-key canonical JSON excluding resource_spec_id, sorting volumes by volume_id). A supported single independently funded volume may be quoted for compute only after owner-bound storage authority, coverage, capacity and installed enforcing runtime preflight. Unsupported shapes, RESIZE with volumes and public HTTP with volumes remain rejected. Capability discovery is not per-request preflight or proof of live enablement. Digest LeaseReplica LeaseVolumeSchema JSON
{
"additionalProperties": false,
"description": "Strict constrained canonical JSON: no duplicate/unknown/null fields; printable ASCII excluding quotes, backslash, \u003c, \u003e, \u0026; integers only. Positive requests \u003c= limits; limit * max_instances \u003c= safe integer maximum. Resource ID is SHA256(schema + newline + sorted-key canonical JSON excluding resource_spec_id, sorting volumes by volume_id). A supported single independently funded volume may be quoted for compute only after owner-bound storage authority, coverage, capacity and installed enforcing runtime preflight. Unsupported shapes, RESIZE with volumes and public HTTP with volumes remain rejected. Capability discovery is not per-request preflight or proof of live enablement.",
"properties": {
"max_instances": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"min_instances": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"per_replica": {
"$ref": "#/components/schemas/LeaseReplica"
},
"resource_spec_id": {
"$ref": "#/components/schemas/Digest"
},
"schema_version": {
"enum": [
"cynder-resource-spec/v1"
],
"type": "string"
},
"traffic_policy_id": {
"type": "string"
},
"volumes": {
"items": {
"$ref": "#/components/schemas/LeaseVolume"
},
"type": "array"
}
},
"required": [
"schema_version",
"per_replica",
"min_instances",
"max_instances",
"traffic_policy_id",
"volumes"
],
"type": "object"
}RetainConfigRequest
Schema JSON
{
"additionalProperties": false,
"properties": {
"retain_until": {
"description": "RFC3339 timestamp with optional nanoseconds, normalized to UTC; year 1970 through 9999 and no earlier than the current retention deadline.",
"format": "date-time",
"type": "string"
}
},
"required": [
"retain_until"
],
"type": "object"
}ServiceLeaseActivationObservation
Historical activation evidence at Unix seconds observed_at, never live readiness. Revision digest uses the same domain as ServiceLeaseBinding. ServiceLeaseRuntimeDigestSchema JSON
{
"additionalProperties": false,
"description": "Historical activation evidence at Unix seconds observed_at, never live readiness. Revision digest uses the same domain as ServiceLeaseBinding.",
"properties": {
"binding_digest": {
"$ref": "#/components/schemas/ServiceLeaseRuntimeDigest"
},
"observed_at": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"runtime_revision_digest": {
"$ref": "#/components/schemas/ServiceLeaseRuntimeDigest"
}
},
"required": [
"binding_digest",
"runtime_revision_digest",
"observed_at"
],
"type": "object"
}ServiceLeaseAllocation
LeaseReplicaSchema JSON
{
"additionalProperties": false,
"nullable": true,
"properties": {
"max_instances": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"min_instances": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"per_replica": {
"$ref": "#/components/schemas/LeaseReplica"
}
},
"required": [
"per_replica",
"min_instances",
"max_instances"
],
"type": "object"
}ServiceLeaseBinding
Immutable desired-state authority, not readiness. Revision digest is SHA256 of cynder-public-lease-revision/v1 followed by newline and the private runtime revision name. Raw service/revision names are never public. Digest ServiceLeaseRuntimeDigestSchema JSON
{
"additionalProperties": false,
"description": "Immutable desired-state authority, not readiness. Revision digest is SHA256 of cynder-public-lease-revision/v1 followed by newline and the private runtime revision name. Raw service/revision names are never public.",
"nullable": true,
"properties": {
"desired_runtime_revision_digest": {
"$ref": "#/components/schemas/ServiceLeaseRuntimeDigest"
},
"digest": {
"$ref": "#/components/schemas/ServiceLeaseRuntimeDigest"
},
"fence": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"resource_spec_digest": {
"$ref": "#/components/schemas/Digest"
},
"tuple_digest": {
"$ref": "#/components/schemas/ServiceLeaseRuntimeDigest"
},
"version_id": {
"type": "string"
}
},
"required": [
"digest",
"tuple_digest",
"version_id",
"resource_spec_digest",
"fence",
"desired_runtime_revision_digest"
],
"type": "object"
}ServiceLeaseCapabilities
Configured acquire, renew and fresh-ACQUIRE reactivation follow Ready; resize additionally follows ReadyResize. Volumes require installed paid-storage wiring, not storage preflight or live evidence. Browser mutation controls are never enabled.Schema JSON
{
"additionalProperties": false,
"description": "Configured acquire, renew and fresh-ACQUIRE reactivation follow Ready; resize additionally follows ReadyResize. Volumes require installed paid-storage wiring, not storage preflight or live evidence. Browser mutation controls are never enabled.",
"properties": {
"acquisition": {
"type": "boolean"
},
"browser_mutations": {
"enum": [
false
],
"type": "boolean"
},
"renewal": {
"type": "boolean"
},
"resize": {
"type": "boolean"
},
"suspended_reactivation": {
"type": "boolean"
},
"volumes": {
"type": "boolean"
}
},
"required": [
"acquisition",
"renewal",
"resize",
"volumes",
"suspended_reactivation",
"browser_mutations"
],
"type": "object"
}ServiceLeaseHistoryEntry
ActionID Digest ServiceLeaseActivationObservation ServiceLeaseRuntimeDigestSchema JSON
{
"additionalProperties": false,
"properties": {
"action_id": {
"$ref": "#/components/schemas/ActionID"
},
"activation_observation": {
"$ref": "#/components/schemas/ServiceLeaseActivationObservation"
},
"effective_from": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"effective_until": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"fence": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"grace_ends": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"lease_generation": {
"$ref": "#/components/schemas/ServiceLeaseRuntimeDigest"
},
"new_resource_spec_digest": {
"$ref": "#/components/schemas/Digest"
},
"old_resource_spec_digest": {
"$ref": "#/components/schemas/Digest"
},
"operation": {
"enum": [
"ACQUIRE",
"RENEW",
"RESIZE"
],
"type": "string"
},
"paid_through": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"sequence": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"version_id": {
"type": "string"
}
},
"required": [
"action_id",
"operation",
"paid_through",
"grace_ends",
"sequence",
"fence",
"lease_generation",
"new_resource_spec_digest",
"effective_from",
"effective_until"
],
"type": "object"
}ServiceLeaseLiveObservation
Independently collected, sanitized current observation. GET only reads records. FRESH requires current lease/binding identity and bounded age; READY additionally requires unexpired entitlement and matching runtime evidence. Storage READY additionally rechecks recorded authority identity. Missing, stale or mismatched evidence never implies readiness. Unix-second validity bounds require local browser expiry even if SSE stops. ServiceLeaseRuntimeDigestSchema JSON
{
"additionalProperties": false,
"description": "Independently collected, sanitized current observation. GET only reads records. FRESH requires current lease/binding identity and bounded age; READY additionally requires unexpired entitlement and matching runtime evidence. Storage READY additionally rechecks recorded authority identity. Missing, stale or mismatched evidence never implies readiness. Unix-second validity bounds require local browser expiry even if SSE stops.",
"properties": {
"binding_digest": {
"$ref": "#/components/schemas/ServiceLeaseRuntimeDigest"
},
"fence": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"freshness": {
"enum": [
"MISSING",
"UNAVAILABLE",
"MISMATCHED",
"STALE",
"FRESH"
],
"type": "string"
},
"observed_at": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"runtime": {
"enum": [
"UNKNOWN",
"READY",
"NOT_READY",
"SUSPENDED",
"UNAVAILABLE"
],
"type": "string"
},
"storage": {
"enum": [
"UNKNOWN",
"READY",
"UNAVAILABLE",
"NOT_APPLICABLE"
],
"type": "string"
},
"valid_until": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
}
},
"required": [
"runtime",
"storage",
"freshness"
],
"type": "object"
}ServiceLeaseProjection
Read-only stored entitlement snapshot, not live runtime usage or readiness. Zero-valued optional counters are omitted. Allocation is null until a paid-through entitlement exists, and remains historical after expiry. Binding is null when absent; revision digests hide private service names. History contains bounded public indexed committed acquisitions, renewals, reactivations and resizes across lease generations, not all attempts or payments. An empty list does not prove no operations. Current observations are collected independently of GET and accepted only for matching current identity and freshness. Admission and capabilities report configured coordinator gates, not live readiness or eligibility of this deployment. Reads do not preflight or pay. Digest ServiceLeaseAllocation ServiceLeaseBinding ServiceLeaseCapabilities ServiceLeaseHistoryEntry ServiceLeaseLiveObservationSchema JSON
{
"additionalProperties": false,
"description": "Read-only stored entitlement snapshot, not live runtime usage or readiness. Zero-valued optional counters are omitted. Allocation is null until a paid-through entitlement exists, and remains historical after expiry. Binding is null when absent; revision digests hide private service names. History contains bounded public indexed committed acquisitions, renewals, reactivations and resizes across lease generations, not all attempts or payments. An empty list does not prove no operations. Current observations are collected independently of GET and accepted only for matching current identity and freshness. Admission and capabilities report configured coordinator gates, not live readiness or eligibility of this deployment. Reads do not preflight or pay.",
"properties": {
"admission_enabled": {
"type": "boolean"
},
"capabilities": {
"$ref": "#/components/schemas/ServiceLeaseCapabilities"
},
"classification": {
"enum": [
"LEGACY_UNMANAGED",
"SERVICE_LEASE"
],
"type": "string"
},
"current_observation": {
"$ref": "#/components/schemas/ServiceLeaseLiveObservation"
},
"disabled_reason": {
"type": "string"
},
"fence": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"grace_ends": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"history_limit": {
"description": "Selected history page limit; zero for legacy deployments without a lease.",
"maximum": 50,
"minimum": 0,
"type": "integer"
},
"history_next_cursor": {
"description": "Opaque continuation for the bounded public history scan. An empty page can have a continuation; follow it rather than assuming history is absent.",
"type": "string"
},
"history_scope": {
"enum": [
"PUBLIC_INDEXED_COMMITTED_ACTIVATIONS_ONLY"
],
"type": "string"
},
"immutable_binding": {
"$ref": "#/components/schemas/ServiceLeaseBinding"
},
"paid_through": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"purchased_allocation": {
"$ref": "#/components/schemas/ServiceLeaseAllocation"
},
"renewal_history": {
"items": {
"$ref": "#/components/schemas/ServiceLeaseHistoryEntry"
},
"type": "array"
},
"resource_spec_id": {
"$ref": "#/components/schemas/Digest"
},
"runtime_observation": {
"description": "Current readiness is unknown. Historical activation receipts never establish current READY.",
"enum": [
"NOT_OBSERVED",
"HISTORICAL_ONLY"
],
"type": "string"
},
"sequence": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"state": {
"enum": [
"PENDING_PAYMENT",
"SETTLEMENT_UNKNOWN",
"PAID_PENDING_ACTIVATION",
"ACTIVE",
"GRACE",
"SUSPENDING",
"SUSPENDED",
"PROVISION_FAILED"
],
"type": "string"
},
"storage_status": {
"description": "Legacy storage is NOT_EVALUATED; no lease volumes is NOT_APPLICABLE. Missing or stale recorded authority is UNKNOWN; revoked, mismatched or unreadable authority is UNAVAILABLE. RECORDED_AUTHORIZED means matching unexpired recorded funding only, never live CSI or writer readiness.",
"enum": [
"NOT_EVALUATED",
"NOT_APPLICABLE",
"UNKNOWN",
"UNAVAILABLE",
"RECORDED_AUTHORIZED"
],
"type": "string"
}
},
"required": [
"classification",
"admission_enabled",
"disabled_reason",
"runtime_observation",
"storage_status",
"purchased_allocation",
"immutable_binding",
"renewal_history",
"history_scope",
"capabilities"
],
"type": "object"
}ServiceLeaseRuntimeDigest
Schema JSON
{
"pattern": "^sha256:[0-9a-f]{64}$",
"type": "string"
}ServiceLeaseSummary
Constant-size identity-scoped summary without history traversal. CURRENT_DEPLOYMENT describes current recorded authority; CURRENT_VERSION_BINDING requires an exact version binding. COMMITTED_ACTION describes only that historical action's activation, never today's entitlement or observation. Missing or unmatched evidence never fabricates readiness. Digest ServiceLeaseActivationObservation ServiceLeaseAllocation ServiceLeaseLiveObservationSchema JSON
{
"additionalProperties": false,
"description": "Constant-size identity-scoped summary without history traversal. CURRENT_DEPLOYMENT describes current recorded authority; CURRENT_VERSION_BINDING requires an exact version binding. COMMITTED_ACTION describes only that historical action's activation, never today's entitlement or observation. Missing or unmatched evidence never fabricates readiness.",
"properties": {
"activation_observation": {
"$ref": "#/components/schemas/ServiceLeaseActivationObservation"
},
"classification": {
"enum": [
"LEGACY_UNMANAGED",
"SERVICE_LEASE",
"UNAVAILABLE",
"NO_MATCHING_CURRENT_LEASE"
],
"type": "string"
},
"current_observation": {
"$ref": "#/components/schemas/ServiceLeaseLiveObservation"
},
"grace_ends": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"paid_through": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"purchased_allocation": {
"$ref": "#/components/schemas/ServiceLeaseAllocation"
},
"resource_spec_id": {
"$ref": "#/components/schemas/Digest"
},
"scope": {
"enum": [
"CURRENT_DEPLOYMENT",
"VERSION",
"CURRENT_VERSION_BINDING",
"COMMITTED_ACTION"
],
"type": "string"
},
"state": {
"type": "string"
}
},
"required": [
"scope",
"classification"
],
"type": "object"
}StoragePurchaseTypedItem
Schema JSON
{
"additionalProperties": false,
"properties": {
"Amount": {
"type": "string"
},
"Kind": {
"enum": [
"STORAGE"
],
"type": "string"
},
"Multiplier": {
"format": "uint64",
"type": "integer"
},
"Rate": {
"type": "string"
},
"Seconds": {
"format": "uint64",
"type": "integer"
},
"Tier": {
"type": "string"
},
"Units": {
"format": "uint64",
"type": "integer"
},
"VolumeID": {
"type": "string"
}
},
"required": [
"Kind",
"VolumeID",
"Tier",
"Rate",
"Units",
"Seconds",
"Multiplier",
"Amount"
],
"type": "object"
}StoragePurchaseTypedPolicy
Schema JSON
{
"additionalProperties": false,
"properties": {
"Asset": {
"type": "string"
},
"Digest": {
"pattern": "^[a-f0-9]{64}$",
"type": "string"
},
"Fee": {
"type": "string"
},
"ID": {
"type": "string"
},
"MaxSeconds": {
"format": "uint64",
"type": "integer"
},
"MinSeconds": {
"format": "uint64",
"type": "integer"
},
"Network": {
"type": "string"
},
"Payee": {
"type": "string"
},
"Provider": {
"type": "string"
},
"QuoteSeconds": {
"format": "uint64",
"type": "integer"
},
"Rate": {
"type": "string"
},
"RetentionPolicy": {
"type": "string"
},
"RetentionSeconds": {
"format": "uint64",
"type": "integer"
},
"Tier": {
"type": "string"
},
"Version": {
"format": "uint64",
"type": "integer"
}
},
"required": [
"ID",
"Version",
"Provider",
"Network",
"Asset",
"Payee",
"Tier",
"RetentionPolicy",
"Rate",
"Fee",
"MinSeconds",
"MaxSeconds",
"RetentionSeconds",
"QuoteSeconds",
"Digest"
],
"type": "object"
}StoragePurchaseTypedQuote
StoragePurchaseTypedItem StoragePurchaseTypedPolicy StoragePurchaseTypedRequestSchema JSON
{
"additionalProperties": false,
"properties": {
"Asset": {
"type": "string"
},
"Digest": {
"pattern": "^[a-f0-9]{64}$",
"type": "string"
},
"ExpiresAt": {
"format": "uint64",
"type": "integer"
},
"Fee": {
"type": "string"
},
"ID": {
"pattern": "^[a-f0-9]{64}$",
"type": "string"
},
"Item": {
"$ref": "#/components/schemas/StoragePurchaseTypedItem"
},
"Network": {
"type": "string"
},
"Payee": {
"type": "string"
},
"Policy": {
"$ref": "#/components/schemas/StoragePurchaseTypedPolicy"
},
"Request": {
"$ref": "#/components/schemas/StoragePurchaseTypedRequest"
},
"Schema": {
"const": "cynder-storage-purchase/v1",
"type": "string"
},
"Total": {
"type": "string"
}
},
"required": [
"Schema",
"ID",
"Digest",
"Request",
"Policy",
"Item",
"Fee",
"Total",
"Network",
"Asset",
"Payee",
"ExpiresAt"
],
"type": "object"
}StoragePurchaseTypedRequest
Authenticated owner request, including only the immutable custody commitment; no CSI binding fields.Schema JSON
{
"additionalProperties": false,
"description": "Authenticated owner request, including only the immutable custody commitment; no CSI binding fields.",
"properties": {
"CoverageEnds": {
"format": "uint64",
"type": "integer"
},
"CoverageStarts": {
"format": "uint64",
"type": "integer"
},
"CustodyDigest": {
"pattern": "^[a-f0-9]{64}$",
"type": "string"
},
"Deployment": {
"type": "string"
},
"ExpectedSequence": {
"format": "uint64",
"type": "integer"
},
"IdempotencyKey": {
"type": "string"
},
"Obligation": {
"type": "string"
},
"Owner": {
"type": "string"
},
"RetentionDeadline": {
"format": "uint64",
"type": "integer"
},
"RetentionPolicy": {
"type": "string"
},
"Size": {
"format": "uint64",
"type": "integer"
},
"Tier": {
"type": "string"
},
"Volume": {
"type": "string"
}
},
"required": [
"Owner",
"Deployment",
"Obligation",
"Volume",
"Tier",
"RetentionPolicy",
"CustodyDigest",
"Size",
"ExpectedSequence",
"CoverageStarts",
"CoverageEnds",
"RetentionDeadline",
"IdempotencyKey"
],
"type": "object"
}StoragePurchaseView
Owner-authenticated projection; typed_quote has only price, policy and the custody digest, never the private CSI binding or stored payment/intent record. StoragePurchaseTypedQuoteSchema JSON
{
"additionalProperties": false,
"description": "Owner-authenticated projection; typed_quote has only price, policy and the custody digest, never the private CSI binding or stored payment/intent record.",
"properties": {
"asset": {
"type": "string"
},
"coverage_ends": {
"format": "uint64",
"type": "integer"
},
"coverage_starts": {
"format": "uint64",
"type": "integer"
},
"deployment_id": {
"type": "string"
},
"expected_sequence": {
"format": "uint64",
"type": "integer"
},
"expires_at": {
"format": "uint64",
"type": "integer"
},
"fee": {
"type": "string"
},
"network": {
"type": "string"
},
"obligation_id": {
"type": "string"
},
"payee": {
"type": "string"
},
"policy_digest": {
"type": "string"
},
"policy_id": {
"type": "string"
},
"policy_version": {
"format": "uint64",
"type": "integer"
},
"quote_digest": {
"type": "string"
},
"quote_id": {
"type": "string"
},
"rate": {
"type": "string"
},
"retention_deadline": {
"format": "uint64",
"type": "integer"
},
"retention_policy": {
"type": "string"
},
"seconds": {
"format": "uint64",
"type": "integer"
},
"size_bytes": {
"format": "uint64",
"type": "integer"
},
"status": {
"enum": [
"NOT_SUBMITTED"
],
"type": "string"
},
"storage_amount": {
"type": "string"
},
"tier": {
"type": "string"
},
"total": {
"type": "string"
},
"typed_quote": {
"$ref": "#/components/schemas/StoragePurchaseTypedQuote"
},
"units": {
"format": "uint64",
"type": "integer"
},
"volume_id": {
"type": "string"
}
},
"required": [
"typed_quote",
"quote_id",
"quote_digest",
"obligation_id",
"deployment_id",
"volume_id",
"tier",
"retention_policy",
"size_bytes",
"expected_sequence",
"coverage_starts",
"coverage_ends",
"retention_deadline",
"policy_id",
"policy_version",
"policy_digest",
"rate",
"units",
"seconds",
"storage_amount",
"fee",
"total",
"network",
"asset",
"payee",
"expires_at",
"status"
],
"type": "object"
}Timestamp
Schema JSON
{
"format": "date-time",
"type": "string"
}TupleConfigBinding
ConfigID TupleDigestSchema JSON
{
"additionalProperties": false,
"properties": {
"digest": {
"$ref": "#/components/schemas/TupleDigest"
},
"mode": {
"description": "env injects literal non-secret container values; envFrom uses envFrom.configMapRef to the immutable pinned ConfigMap.",
"enum": [
"env",
"envFrom"
],
"type": "string"
},
"version_id": {
"$ref": "#/components/schemas/ConfigID"
}
},
"required": [
"version_id",
"digest",
"mode"
],
"type": "object"
}TupleDigest
Schema JSON
{
"pattern": "^sha256:[0-9a-f]{64}$",
"type": "string"
}TupleHTTP
Schema JSON
{
"additionalProperties": false,
"properties": {
"port": {
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"public": {
"type": "boolean"
},
"public_hostname": {
"description": "Empty for private HTTP; otherwise pinned generated hostname",
"type": "string"
}
},
"required": [
"public",
"port",
"public_hostname"
],
"type": "object"
}TupleHealth
Schema JSON
{
"additionalProperties": false,
"properties": {
"liveness_path": {
"pattern": "^(/[^?#\\r\\n]*)?$",
"type": "string"
},
"readiness_path": {
"pattern": "^(/[^?#\\r\\n]*)?$",
"type": "string"
}
},
"required": [
"readiness_path",
"liveness_path"
],
"type": "object"
}TupleIdentities
Schema JSON
{
"additionalProperties": false,
"properties": {
"cluster": {
"minLength": 1,
"type": "string"
},
"configs": {
"description": "Identity at each index corresponds to the config binding at that index; explicit empty array in issue 5",
"items": {
"minLength": 1,
"type": "string"
},
"type": "array",
"uniqueItems": true
},
"namespace": {
"minLength": 1,
"type": "string"
},
"registry_tenant": {
"type": "string"
},
"revision_id": {
"minLength": 1,
"type": "string"
},
"runtime_revision": {
"minLength": 1,
"type": "string"
},
"secrets": {
"description": "Identity at each index corresponds to the secret binding at that index; explicit empty array in issue 5",
"items": {
"minLength": 1,
"type": "string"
},
"type": "array",
"uniqueItems": true
},
"service": {
"minLength": 1,
"type": "string"
},
"service_account": {
"minLength": 1,
"type": "string"
}
},
"required": [
"cluster",
"namespace",
"service",
"service_account",
"registry_tenant",
"revision_id",
"runtime_revision",
"configs",
"secrets"
],
"type": "object"
}TuplePolicy
Fully resolved immutable policy. mvi-v1 resolves mvi-small to CPU 500m, memory 512Mi, ephemeral storage 1Gi, min/max scale 0/2, concurrency 1 and workload timeout 300 seconds. RuntimeClass is captured at creation, including explicit empty string; never reread process defaults on reconciliation. The action execution deadline is separate. TupleDigestSchema JSON
{
"additionalProperties": false,
"description": "Fully resolved immutable policy. mvi-v1 resolves mvi-small to CPU 500m, memory 512Mi, ephemeral storage 1Gi, min/max scale 0/2, concurrency 1 and workload timeout 300 seconds. RuntimeClass is captured at creation, including explicit empty string; never reread process defaults on reconciliation. The action execution deadline is separate.",
"properties": {
"concurrency": {
"minimum": 1,
"type": "integer"
},
"cpu": {
"minLength": 1,
"type": "string"
},
"digest": {
"$ref": "#/components/schemas/TupleDigest"
},
"ephemeral_storage": {
"minLength": 1,
"type": "string"
},
"max_scale": {
"minimum": 0,
"type": "integer"
},
"memory": {
"minLength": 1,
"type": "string"
},
"min_scale": {
"minimum": 0,
"type": "integer"
},
"resource_class": {
"minLength": 1,
"type": "string"
},
"runtime_class": {
"type": "string"
},
"timeout_seconds": {
"minimum": 1,
"type": "integer"
},
"version": {
"minLength": 1,
"type": "string"
}
},
"required": [
"version",
"digest",
"resource_class",
"cpu",
"memory",
"ephemeral_storage",
"min_scale",
"max_scale",
"concurrency",
"timeout_seconds",
"runtime_class"
],
"type": "object"
}TupleReadiness
Exact-revision internal tuple evidence. For a committed new version, revision identifiers match tuple identities and observed_at does not precede created_at. On rollback fresh activation readiness is represented in committed receipt deployment_evidence, not the owner output or historical tuple. Ordinary public HTTP requires route_ready after promotion and public_url equal to https:// plus the pinned hostname; lease-only private_endpoint evidence instead requires route_ready false and an empty public_url, and does not attest public delivery. Private HTTP has an empty public_url. Candidate-only traffic_pending permits pre-promotion readiness without route_ready and is not successful activation evidence. DedicatedActivationReadiness TimestampSchema JSON
{
"additionalProperties": false,
"description": "Exact-revision internal tuple evidence. For a committed new version, revision identifiers match tuple identities and observed_at does not precede created_at. On rollback fresh activation readiness is represented in committed receipt deployment_evidence, not the owner output or historical tuple. Ordinary public HTTP requires route_ready after promotion and public_url equal to https:// plus the pinned hostname; lease-only private_endpoint evidence instead requires route_ready false and an empty public_url, and does not attest public delivery. Private HTTP has an empty public_url. Candidate-only traffic_pending permits pre-promotion readiness without route_ready and is not successful activation evidence.",
"properties": {
"dedicated_activation": {
"$ref": "#/components/schemas/DedicatedActivationReadiness"
},
"observed_at": {
"$ref": "#/components/schemas/Timestamp"
},
"private_endpoint": {
"description": "Lease-only private endpoint observation; not public delivery or authority. Requires route_ready false and empty public_url; accepted only with a canonical lease candidate.",
"type": "boolean"
},
"public_url": {
"type": "string"
},
"ready": {
"const": true,
"type": "boolean"
},
"revision_id": {
"minLength": 1,
"type": "string"
},
"route_ready": {
"type": "boolean"
},
"runtime_revision": {
"minLength": 1,
"type": "string"
},
"traffic_pending": {
"type": "boolean"
}
},
"required": [
"ready",
"revision_id",
"runtime_revision",
"route_ready",
"public_url",
"observed_at"
],
"type": "object"
}TupleSecretBinding
Opaque reference only; never secret values, key names, ciphertext, nonce, wrapped keys or hashes derived from secret contents.Schema JSON
{
"additionalProperties": false,
"description": "Opaque reference only; never secret values, key names, ciphertext, nonce, wrapped keys or hashes derived from secret contents.",
"properties": {
"mode": {
"description": "env uses env[].valueFrom.secretKeyRef; envFrom uses envFrom.secretRef to the immutable pinned Secret. Secret values are never container env literals.",
"enum": [
"env",
"envFrom"
],
"type": "string"
},
"version_id": {
"pattern": "^sec_[a-f0-9]{48}$",
"type": "string"
}
},
"required": [
"version_id",
"mode"
],
"type": "object"
}VersionActivationOutput
Owner-private DEPLOY_VERSION/ROLLBACK_VERSION execution output variant, not a public Explorer DTO. Only safe identifiers/status survive the owner projection; neither tuple nor activation_readiness is returned. Owner version reads expose tuple_digest; receipt deployment_evidence binds fresh committed readiness. A durable candidate is intent only, not a version, readiness or active pointer. Staging fences the expected committed activation and keeps incumbent traffic. The candidate is checked ready, then promoted and route/endpoint-verified before the atomic Badger version/activation/pointer commit. This allows bounded precommit route exposure, not distributed atomicity. Failure attempts compensation to the committed target under a fresh bounded context; compensation failure is ambiguous. Restart restores only the durable committed target, never an uncommitted candidate or mutable latest revision. Missing complete evidence fails closed. DeploymentIDSchema JSON
{
"additionalProperties": false,
"description": "Owner-private DEPLOY_VERSION/ROLLBACK_VERSION execution output variant, not a public Explorer DTO. Only safe identifiers/status survive the owner projection; neither tuple nor activation_readiness is returned. Owner version reads expose tuple_digest; receipt deployment_evidence binds fresh committed readiness. A durable candidate is intent only, not a version, readiness or active pointer. Staging fences the expected committed activation and keeps incumbent traffic. The candidate is checked ready, then promoted and route/endpoint-verified before the atomic Badger version/activation/pointer commit. This allows bounded precommit route exposure, not distributed atomicity. Failure attempts compensation to the committed target under a fresh bounded context; compensation failure is ambiguous. Restart restores only the durable committed target, never an uncommitted candidate or mutable latest revision. Missing complete evidence fails closed.",
"properties": {
"deployment_id": {
"$ref": "#/components/schemas/DeploymentID"
},
"public_url": {
"format": "uri",
"type": "string"
},
"ready": {
"type": "boolean"
},
"status": {
"type": "string"
}
},
"type": "object"
}VersionID
Schema JSON
{
"pattern": "^ver_[0-9a-f]{32}$",
"type": "string"
}WaitingResizeView
Action identity and digest must match the approved resize. State proves SETTLED with exact approved amount, asset and payee; a matching action-bound waiting receipt proves scheduling only. Missing or mismatched receipts are not valid waiting evidence. ActionViewSchema JSON
{
"allOf": [
{
"$ref": "#/components/schemas/ActionView"
},
{
"properties": {
"action": {
"properties": {
"type": {
"const": "RESIZE_LEASE"
}
}
},
"receipts": {
"contains": {
"properties": {
"final_status": {
"const": "WAITING_EFFECTIVE_TIME"
},
"kind": {
"const": "WAITING_EFFECTIVE_TIME"
},
"payment_status": {
"const": "SETTLED"
},
"status": {
"const": "WAITING_EFFECTIVE_TIME"
}
},
"required": [
"kind",
"status",
"final_status",
"payment_status",
"action_digest",
"usdc_amount",
"payee"
]
}
},
"state": {
"properties": {
"payment_status": {
"const": "SETTLED"
},
"status": {
"const": "WAITING_EFFECTIVE_TIME"
}
},
"required": [
"payment_amount",
"payment_asset",
"payment_pay_to"
]
}
},
"type": "object"
}
],
"description": "Action identity and digest must match the approved resize. State proves SETTLED with exact approved amount, asset and payee; a matching action-bound waiting receipt proves scheduling only. Missing or mismatched receipts are not valid waiting evidence."
}WorkloadSecretMetadata
Sole private response projection. No values, key names, ciphertext, nonces, wrapped keys, serialized Kubernetes Secret data or deterministic plaintext hashes. Expired, revoked, deleted and tampered versions cannot be resolved for use. Root custody is external to Badger and its PVC backup.Schema JSON
{
"additionalProperties": false,
"description": "Sole private response projection. No values, key names, ciphertext, nonces, wrapped keys, serialized Kubernetes Secret data or deterministic plaintext hashes. Expired, revoked, deleted and tampered versions cannot be resolved for use. Root custody is external to Badger and its PVC backup.",
"properties": {
"algorithm": {
"enum": [
"AES-256-GCM/v1"
],
"type": "string"
},
"created_at": {
"format": "date-time",
"type": "string"
},
"deleted_at": {
"format": "date-time",
"type": "string"
},
"expires_at": {
"format": "date-time",
"type": "string"
},
"id": {
"pattern": "^sec_[a-f0-9]{48}$",
"type": "string"
},
"key_count": {
"maximum": 64,
"minimum": 0,
"type": "integer"
},
"owner_id": {
"pattern": "^eip155:8453:0x[a-f0-9]{40}$",
"type": "string"
},
"revoked_at": {
"format": "date-time",
"type": "string"
},
"root_key_id": {
"description": "Non-secret operator root identifier.",
"type": "string"
},
"state": {
"enum": [
"active",
"expired",
"revoked",
"deleted"
],
"type": "string"
},
"supersedes": {
"pattern": "^sec_[a-f0-9]{48}$",
"type": "string"
}
},
"required": [
"id",
"owner_id",
"state",
"algorithm",
"root_key_id",
"key_count",
"created_at",
"expires_at"
],
"type": "object"
}WorkloadSecretWrite
Write-only input. Maximum JSON body 524288 bytes; 1-64 keys; each UTF-8 value at most 16384 bytes; combined key and value bytes at most 65536. Duplicate and unknown fields are rejected. At most 8 concurrent requests globally and 2 per owner, 30-second deadline; 1000 lifetime versions per owner including tombstones.Schema JSON
{
"additionalProperties": false,
"description": "Write-only input. Maximum JSON body 524288 bytes; 1-64 keys; each UTF-8 value at most 16384 bytes; combined key and value bytes at most 65536. Duplicate and unknown fields are rejected. At most 8 concurrent requests globally and 2 per owner, 30-second deadline; 1000 lifetime versions per owner including tombstones.",
"properties": {
"expires_at": {
"description": "Required RFC3339 timestamp strictly in the future and no more than 365 days ahead.",
"format": "date-time",
"type": "string"
},
"values": {
"additionalProperties": {
"maxLength": 16384,
"type": "string",
"writeOnly": true
},
"maxProperties": 64,
"minProperties": 1,
"propertyNames": {
"pattern": "^[A-Za-z_][A-Za-z0-9_]{0,63}$"
},
"type": "object",
"writeOnly": true
}
},
"required": [
"values",
"expires_at"
],
"type": "object"
}