Skip to content

POST /v1/records

Ingest a cryptographically signed provenance record. Counts as 1 signature against your plan quota.

Authentication requiredAuthorization: Bearer ctv_key_…


POST /v1/records
Content-Type: application/json
Authorization: Bearer ctv_key_abc123
{
"watermark_id": "wm_7f3kx9mq2",
"generator_id": "gen_abc123",
"model": "stable-diffusion-xl",
"content_hash": "sha3-256:a3f1...",
"signature": "<ml-dsa base64>",
"signed_payload": {
"content_hash": "sha3-256:a3f1...",
"generator_id": "gen_abc123",
"model": "stable-diffusion-xl",
"watermark_id": "wm_7f3kx9mq2"
}
}
FieldTypeDescription
watermark_idstringOpaque ID embedded in the image watermark
generator_idstringID of the registered generator that signed this
modelstringModel name (e.g. stable-diffusion-xl)
content_hashstringsha3-256:<64 hex chars> — SHA-3 hash of the content
signaturestringML-DSA signature (base64) over signed_payload canonical JSON
signed_payloadobjectThe exact payload that was signed

{
"token": "ctv_7f3kx9mq2...",
"record_id": "rec_uuid"
}
FieldDescription
tokenCompact signed artifact — embed in XMP metadata or pass alongside content
record_idUUID of the stored provenance record

StatusCodeMeaning
400Validation failed or signature invalid
401Missing or invalid API key
402signature_limit_reachedFree tier monthly limit hit — upgrade to continue
403Generator does not belong to your organization
404Generator not found or revoked
{
"error": "signature_limit_reached",
"message": "Free tier limit of 500 signatures/month reached. Upgrade at https://certivu.ai/pricing",
"upgrade_url": "https://certivu.ai/pricing",
"limit": 500,
"current": 500
}

GET /v1/records/:record_id

Returns the full ProvenanceRecord. No authentication required.


  • The content_hash must use format sha3-256:<64 lowercase hex chars>
  • signed_payload must be the exact object that was canonically serialized and signed — verification replays this
  • Use @certivu/sdk to handle hashing, signing, and submission automatically