Skip to content

Asynchronous contracts

llms.txtAsk agent

Call authenticated GET /v1/recipes before submitting POST /v1/sign. Each entry returns:

  • the stable recipe_id;
  • its currently enabled immutable version;
  • its customer-visible capabilities, in execution order;
  • its supported_media_types.

c2pa_signing means C2PA manifest creation and signing. The response deliberately leaves out provider identities, algorithms, configuration, storage locations, and the internal recipe graph.

An operation that is not classified in the scope policy is denied by default.

POST /v1/verifications accepts an immutable asset object identifier in object_id, also called the asset_object_id, whose public form starts with aob_. The parent asset_id (ast_…) cannot stand in for it. Unknown request fields are rejected, and validation responses never echo the identifier you sent.

Verification is asynchronous. The create call returns HTTP 202 with a status snapshot. Poll GET /v1/verifications/{verification_id} no more often than every 2 seconds, with bounded exponential backoff for longer runs:

state Terminal Field contract
accepted No result, evidence_id, completed_at, and failure_reason are absent/null.
running No Continue polling. A client timeout does not cancel the durable job.
completed Yes result, evidence_id, and completed_at are present.
failed Yes failure_reason and completed_at are present.

Pick a client-side timeout that suits the calling workflow. If it expires, keep the verification_id and resume polling later. Do not create a second verification just because the caller stopped waiting.

A recovery-only result is not cryptographic validity. It means no C2PA manifest could be read from the asset, and a bounded soft-binding recovery found one unique candidate. Show it as recovery-only provenance and keep the reasons and recovery evidence that come with it.

When a manifest was read, what validation found about it is the status (for example untrusted for an intact manifest from a signer that is not on the trust list), and a recovery match, if any, is reported alongside it in result.recovery as supplementary evidence. Results issued before 2026-09-29 (schema_version op.public-verify-result.v1) keep the status they were issued with: under that version a unique recovery match outranked an expired or untrusted manifest.

A successful authenticated POST /v1/assets/{asset_id}/download response always includes both byte_length and lowercase sha256 for the exact immutable published bytes. Use them to check the downloaded body. The API also ties the download URL to one exact private storage version without revealing its bucket, object key, or version identifier.

If the immutable byte facts are missing or inconsistent, the API fails closed with a reason-coded error and issues no partial download. The same applies to their publication and verification bindings.