API Reference¶
This page covers behavior the OpenAPI spec doesn't capture: sync/async pairing, per-endpoint input constraints, custom assertions, parent provenance, and output placement. openapi.json is the source of truth for exact request/response schemas, field types, and status/error codes. It's generated from the private service implementation and never edited by hand here; browse it via the Swagger Editor link on the docs homepage. Use cURL Examples for runnable requests.
Health And Jobs¶
GET /v2/health¶
Liveness and readiness probe. Returns 200 OK with an empty body.
GET /v2/jobs/{id}¶
Retrieves the current snapshot of a batch job, async or sync: job_id, top-level status, results, and timing. 404 JOB_NOT_FOUND if the ID doesn't exist.
C2PA Video¶
POST /v2/c2pa/video (async) and POST /v2/sync/c2pa/video (sync — polls until the job reaches a terminal state or server.sync_timeout_ms elapses, then 408 REQUEST_TIMEOUT).
Accepts file inputs only; a folder input returns 400 INVALID_INPUT_TYPE. Supports custom assertions and parent provenance.
C2PA Audio¶
POST /v2/c2pa/audio (async) and POST /v2/sync/c2pa/audio (sync, same timeout behavior as above).
Accepts file inputs only; a folder input returns 400 INVALID_INPUT_TYPE. Each input must be a single file whose extension names a container the C2PA SDK can sign: mp3, wav, flac, m4a, and mp4/m4v for audio-only assets. An input with no derivable extension is accepted and its media type is settled during resolution. Supports custom assertions and parent provenance, with the same params shape as video signing.
C2PA Fragmented¶
POST /v2/c2pa/fragmented (async) and POST /v2/sync/c2pa/fragmented (sync, same timeout behavior as above).
Accepts folder inputs only. playlist_pattern, init_pattern, and frag_pattern are required. Supports custom assertions and parent provenance, embedded into every signed init segment's manifest.
Media Packaging¶
POST /v2/package (async) and POST /v2/sync/package (sync, same timeout behavior as above).
Accepts folder inputs only; no required params. Packaging-only — no signing, so custom assertions and parent provenance don't apply.
Package And Sign¶
POST /v2/c2pa/package (async) and POST /v2/sync/c2pa/package (sync, same timeout behavior as above).
Accepts folder inputs only. playlist_pattern, init_pattern, and frag_pattern are optional. Supports custom assertions and parent provenance, same as fragmented signing.
Custom Assertions¶
All four C2PA signing endpoints (/v2/c2pa/video, /v2/c2pa/audio, /v2/c2pa/fragmented, /v2/c2pa/package) accept optional custom assertions embedded in the signed manifest via params.assertions. Each entry is a label plus a JSON payload:
"assertions": [
{
"label": "com.example.rights",
"data": { "owner": "ACME Media", "license": "CC-BY-4.0" }
}
]
label: non-empty string; use a reverse-domain label (com.example.*) to avoid collisions with standard C2PA assertions.data: arbitrary JSON embedded as the assertion payload. Only JSON payloads are accepted.
For fragmented and packaged publications, the assertions are embedded into every signed init segment's manifest, so the whole publication carries the same custom assertions.
Parent Provenance¶
All four C2PA signing endpoints (/v2/c2pa/video, /v2/c2pa/audio, /v2/c2pa/fragmented, /v2/c2pa/package) accept an optional parent manifest attached as a provenance ingredient via params.parent, with optional per-input overrides via params.parent_overrides. Custom assertions and parent provenance can be combined in the same request on any of these endpoints.
For fragmented and packaged publications, the supplied parent is attached to every signed init segment's manifest, marking the publication as derived from that parent. When no parent is supplied, signing still succeeds: the service treats the signed output as an edit of its own source segment by default.
A parent is either a reference token (bare ingredient, no file resolved) or a media file whose embedded C2PA manifest is read and included in the provenance chain:
"parent": {
"type": "file",
"source": { "type": "local_file_path", "path": "./tests/fixtures/video/mp4/parent.mp4" }
}
File sources mirror single-file inputs: local_file_path, or remote_file_url with an optional filename_hint.
Per-input overrides replace or disable the parent for specific inputs; parent: null disables it for that input:
"parent_overrides": [
{
"input_index": 1,
"parent": {
"type": "file",
"source": { "type": "remote_file_url", "url": "https://example.com/parent.mp4", "filename_hint": "parent.mp4" }
}
},
{ "input_index": 2, "parent": null }
]
Output Selection¶
The output section chooses the destination and placement. It applies to every signing and packaging endpoint. Omitting output (or sending null) is equivalent to {"type": "local"} with no fields.
Two variants are selected by type:
local— writes to the service host's filesystem underoutput_sinks.local.base_dir. Useful for local or self-hosted deployments (the files land on the machine running the service).s3— writes to object storage. This is the primary destination for hosted use. Available only when the service is built with--features s3, and the requestedbucketmust be present inoutput_sinks.s3.buckets.
Common fields (both variants):
prefix: optional caller namespace under the sink root."/"or omitted means "no request prefix".name: optional logical output folder/base for this request.
s3 also requires bucket. local takes no extra fields. The file-leaf naming
convention is not a request field; it is configured per output sink in the
service config (output_sinks.*.naming, see Request Output Types).
Naming and paths¶
Each input contributes its own leaf name, derived from the input reference. The
per-sink naming setting (derived default | in_place) controls single-file
outputs:
- Single-file (video, audio) inputs:
derivedproduces{stem}_c2pa.{ext}(e.g.clip.mp4→clip_c2pa.mp4);in_placekeeps the input filename (clip.mp4). - Folder / publication inputs (fragmented, package, package-and-sign): the leaf is the input folder's name; the
namingsetting does not apply.
The final location is composed as:
For local, base_prefix is output_sinks.local.base_dir; for s3 it is output_sinks.s3.base_prefix (may be empty). There is no job or batch id segment in the path. Reusing the same destination overwrites it — callers own uniqueness (differentiate via prefix or name).
Feature-Gated Behavior¶
openapi¶
- Exposes the runtime machine-readable spec at
/openapi.json - Enables generation of the runtime and synchronized docs-site raw spec
scalar-docs¶
- Extends
openapi - Exposes the Scalar UI at
/docs
s3¶
- Enables S3-backed remote inputs
- Enables request-selected S3 output destinations
- The docs build uses the full documentation profile and generates the raw spec with
openapiands3enabled
Watermark Placeholders¶
POST /v2/watermark¶
- Purpose: reserved placeholder for future softbinding watermark creation
- Current behavior:
501 Not Implemented - Body: plain text
Coming soon
GET /v2/watermark/{id}¶
- Purpose: reserved placeholder for future softbinding watermark retrieval
- Current behavior:
501 Not Implemented - Body: plain text
Coming soon
Error Model¶
Errors share one shape (ApiErrorResponse: error.code, error.message, optional error.details). The OpenAPI spec lists every error code per endpoint with example payloads. JOB_NOT_FOUND and REQUEST_TIMEOUT map directly to the job-polling behavior described above.
Operational Notes¶
- All processing endpoints accept batched requests via
inputs, but the array must contain at least one input. - Sync endpoints poll until the job reaches a terminal state or
server.sync_timeout_msis exceeded. - Partial job completion is surfaced as
status: "failed"in the HTTP response model. - Request body size is capped by
server.max_upload_bytes.