Media Signing API
14 minute read
The Media Signing API signs a supported media file and embeds a C2PA-compliant manifest. The response includes the signed file as Base64 data and a JSON-encoded manifest store that your application can inspect.
Overview
Use the API to sign supported media files with a C2PA-compliant manifest. The resulting Content Credentials provide tamper-evident provenance information that helps a viewer verify who signed the content, which actions were declared, and whether the signed asset has changed.
The API also supports S/MIME Baseline Requirements (BR) certificates for CAWG identity assertions. A CAWG identity assertion adds verifiable creator, publisher, or contributor identity information to the Content Credentials. Please note that CAWG identity assertion signing is supported only in the production environment.
For an application integration that uses the native Media Signing Library, see Media Signing Library API integration.
You can use the API to:
Generate and embed a minimal C2PA manifest.
Add signing metadata and supported user-declared actions.
Disclose AI-assisted creation and record AI training or data-use permissions.
Include available EXIF metadata, a digital source type, and an external reference.
Add a CAWG identity assertion by using an S/MIME BR certificate credential.
Prerequisites
Before making your first request, make sure you have:
A DigiCert ONE account with Content Trust Manager enabled.
Your Content Trust Manager account ID.
One request-authentication method: an API key or a client authentication certificate for mutual TLS (mTLS).
Credentials created in the same production (one.digicert.com) or demo environment (demo.one.digicert.com) as the endpoint you call.
A supported media file.
For CAWG identity assertion signing, an S/MIME BR certificate credential and its credential ID, PIN, and OTP when your credential policy requires one.
Client authentication certificate
Use a client authentication certificate when your integration authenticates with mTLS. The certificate is presented during the TLS handshake; an API key is not sent on an mTLS request.
Create a client authentication certificate
Sign in to DigiCert ONE.
Select the user icon, select Admin profile, and then select Client authentication certificates.
Select Create client authentication certificate.
Enter a unique nickname using letters, numbers, spaces, dashes, or underscores.
Select an end date and optionally record it in your certificate-rotation process.
Select AES for Encryption.
Select SHA256 for Signature hash algorithm.
Select Generate certificate.
Copy the certificate password and store it securely, such as in your organization’s secrets-management system. You cannot retrieve the password later.
Download the certificate and store it securely. You cannot download the same certificate again.
Configure the certificate in Postman
Open Settings > Certificates.
Set Host to clientauth.one.digicert.com for production, or clientauth.demo.one.digicert.com for demo. Enter only the hostname (do not include https:// or the API path).
Set Port to 443.
Upload your client authentication certificate to the PFX file field and enter its password in Passphrase.
API key
Use an API key when your integration does not use mTLS. Send the key in the x-api-key header and use the API-key endpoint. Do not attach a client authentication certificate to the same request.
Create or copy an API key
Sign in to Content Trust Manager in the environment your integration will call.
Select the user icon, and then select Admin profile.
Scroll to API Keys.
Generate a key or copy an existing key for your integration.
Store the API key securely, such as in your organization’s secrets-management system. Do not commit it to source control or include it in a shared Postman collection.
Authentication
| Method | Request configuration | Do not send |
|---|---|---|
| API key mTLS | Use the API-key endpoint and send x-api-key in the header. Use the clientauth endpoint and present the client authentication certificate during TLS. | A client authentication certificate. The x-api-key header. |
Environment scope API keys, account IDs, and client certificates must belong to the selected environment. A missing, invalid, expired, or environment-mismatched API key returns HTTP 401 with error wrong_token and error_description Invalid session.
Do not send browser cookies The API does not require a Cookie header. Remove copied browser cookies from curl commands, Postman requests, and application code.
Endpoints
| Authentication method | Production endpoint |
|---|---|
| Client authentication certificate (mTLS) | https://clientauth.one.digicert.com/documentmanager/api/c2pa/v1/sign |
| API key | https://one.digicert.com/documentmanager/api/c2pa/v1/sign |
For the demo environment, use the corresponding demo.one.digicert.com or
clientauth.demo.one.digicert.com host. Keep the path unchanged and use demo-issued credentials.
Request parameters
Send a POST request as multipart/form-data. Add each body parameter as a separate form field.
Headers
| Header | Requirement | Value and guidance |
|---|---|---|
Accept | Recommended | application/json |
x-api-key | API-key requests only | Your API key. Omit this header for mTLS requests. |
Content-Type | Generated by client | Let curl, Postman, or your SDK generate multipart/form-data with the correct boundary. Do not hard-code this header. |
Body
| Field | Type | Requirement | Description |
|---|---|---|---|
accountId | String | Required | Your Content Trust Manager account ID for the selected environment. Find it on the Account Details page. The account ID uses UUID format. |
file | File | Required | Binary media file to sign. See Supported media types. |
role | Enum | Required | Standard roles: contributor, creator, and publisher. CAWG roles also include sponsor, editor, producer, and translator. Send one lowercase value. |
credentialId | String | Conditional | Identifier for the S/MIME BR certificate credential. Required for CAWG identity assertion signing. |
pin | String | Conditional | PIN for the selected credential. Required when you provide credentialId. |
otp | String | Conditional | One-time password for SCAL 2 OTP authentication, when required by the credential flow. |
additionalActions | String | Optional | JSON object encoded as one form string. Allowed keys: c2pa.edited, c2pa.resized, and c2pa.filtered. |
digitalSourceType | String | Optional | IPTC/C2PA Digital Source Type URI. createdWithAi=true overrides this value with the Generative AI digital source type. |
includeExifMetadata | Boolean | Optional | Set to true to add available source EXIF data in the c2pa.metadata assertion. |
isNewCreation | Boolean | Optional | Set to true only for new content without existing Content Credentials. This field has no effect if the media already contains Content Credentials. |
createdWithAi | Boolean | Optional | Set to true for AI-created content. Applies only when the API records c2pa.created. |
aiInference | Enum | Optional | allowed, prohibited, or constrained. |
aiInferenceConstraintsInfo | String | Conditional | Required and non-empty when aiInference=constrained. |
generativeAiTraining | Enum | Optional | allowed, prohibited, or constrained. |
generativeAiTrainingConstraintsInfo | String | Conditional | Required and non-empty when generativeAiTraining=constrained. |
dataMiningAndAnalytics | Enum | Optional | allowed, prohibited, or constrained. |
dataMiningAndAnalyticsConstraintsInfo | String | Conditional | Required and non-empty when dataMiningAndAnalytics=constrained. |
nonGenerativeAiTraining | Enum | Optional | allowed, prohibited, or constrained. |
nonGenerativeAiTrainingConstraintsInfo | String | Conditional | Required and non-empty when nonGenerativeAiTraining=constrained. |
externalReferenceUri | String | Optional | Absolute URI included in the c2pa.external-reference assertion. The URI must include a scheme, such as https://. The API records but does not retrieve the resource. |
externalReferenceContentType | String | Conditional | IANA media type for the referenced resource. Required with externalReferenceUri. |
Boolean values Send lowercase true or false. The service accepts some aliases for some fields, but relying on aliases such as TRUE, 1, or yes makes integrations less portable. An unrecognized Boolean value returns HTTP 400.
Supported media types
The file field accepts these documented media types. Send an accurate MIME type and make sure the file bytes match the declared type.
| Category | Supported media types |
|---|---|
| Still image | image/jpeg, image/png, image/x-adobe-dng, image/heic, image/heif, image/tiff, image/webp, image/svg+xml, image/gif, image/jxl |
| Video | video/mp4, video/x-msvideo, video/quicktime |
| Audio | audio/wav, audio/mp4, audio/flac, audio/mpeg |
| Document | application/pdf |
Manifest behavior
Generate a minimal manifest
When you submit accountId, role, and file without optional metadata, the API generates and embeds a minimal C2PA-compliant manifest.
Add signing metadata
Send optional signing metadata as separate multipart fields. The API combines the values with a system-managed action based on the input state.
| Input | System-managed action | Result |
|---|---|---|
New content; isNewCreation=true | c2pa.created | The manifest records a newly created asset. |
Content without isNewCreation=true | c2pa.opened | The source is represented as an ingredient. |
| File already has Content Credentials | c2pa.opened | Existing provenance wins, even when isNewCreation=true. |
isNewCreation=true is ignored. The API records c2pa.opened for the new signing event.User-defined manifest actions
Use additionalActions to declare transformations performed on the asset. Send the value as a JSON object encoded in one multipart text field, not as an array of action objects. For more details, see Request parameters.
| Action key | Meaning |
|---|---|
c2pa.edited | The content was edited. |
c2pa.resized | The asset dimensions changed. |
c2pa.filtered | A filter or effect was applied. |
Optional fields for each action
| Field | Description |
|---|---|
software | Software name written to softwareAgent. |
version | Software version. When software and version are present, the manifest writes softwareAgent as name/version. |
time | ISO 8601 timestamp written to when. If omitted, the API inserts the current UTC time. |
Timestamp format Always send a valid ISO 8601 timestamp, such as 2026-08-19T12:30:00Z.
Correct additionalActions JSON object
{
"c2pa.edited": {
"software": "Example Editor",
"version": "1.0",
"time": "2026-08-19T12:30:00Z"
},
"c2pa.resized": {
"time": "2026-08-19T12:31:00Z"
}
}
Incorrect: do not send an array
[
{
"action": "c2pa.edited",
"software": "Example Editor",
"version": "1.0"
}
]
Corresponding user-declared actions in the manifest
[
{
"action": "c2pa.edited",
"softwareAgent": "Example Editor/1.0",
"when": "2026-08-19T12:30:00Z"
},
{
"action": "c2pa.resized",
"when": "2026-08-19T12:31:00Z"
}
]
Reserved actions Do not send c2pa.created or c2pa.opened in additionalActions. The API manages those actions. Unknown or reserved action keys return HTTP 400.
allActionsIncluded
The API always emits allActionsIncluded in the c2pa.actions.v2 assertion. The value is true when the generated manifest contains an accepted additionalActions action or when createdWithAi successfully changes a new c2pa.created action to an AI-created action. The value is true when the manifest contains only the default c2pa.opened or non-AI c2pa.created action.
Existing signed media For a file that already has Content Credentials, createdWithAi=true does not add c2pa.created and does not, by itself, make allActionsIncluded true.
AI usage and permissions
AI creation disclosure
Set createdWithAi=true only for new content created with AI. Use it with isNewCreation=true on content that does not already contain Content Credentials. The c2pa.created action uses this exact digital source type when createdWithAi is set to true:
http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia
For that action, the AI-derived (createdWithAi=true) digital source type takes precedence over the request-level digitalSourceType. If the file already has Content Credentials, the API records c2pa.opened and ignores the creation disclosure.
AI training and data-use permissions
The permission fields aiInference, generativeAiTraining, dataMiningAndAnalytics, and nonGenerativeAiTraining are case-sensitive. Each accepts allowed, prohibited, or constrained.
| Request value | Manifest value | Constraint rule |
|---|---|---|
allowed | allowed | A matching ConstraintsInfo value is ignored. |
prohibited | notAllowed | A matching ConstraintsInfo value is ignored. |
constrained | constrained | The matching ConstraintsInfo field is required and must be non-empty. |
| Permission field | Matching constraint field |
|---|---|
aiInference | aiInferenceConstraintsInfo |
generativeAiTraining | generativeAiTrainingConstraintsInfo |
dataMiningAndAnalytics | dataMiningAndAnalyticsConstraintsInfo |
nonGenerativeAiTraining | nonGenerativeAiTrainingConstraintsInfo |
Orphan ConstraintsInfo values If the parent permission is omitted, allowed, or prohibited, the API accepts but ignores a supplied ConstraintsInfo value. It emits constraint_info only when the parent permission is constrained.
EXIF metadata ingestion
For a media file that contains EXIF metadata, set includeExifMetadata=true. The API extracts available metadata and embeds it in a c2pa.metadata assertion. If the source file contains no EXIF data, the signed manifest might not contain c2pa.metadata.
External references
Use externalReferenceUri and externalReferenceContentType together to add a c2pa.external-reference assertion.
externalReferenceUrimust be an accepted absolute URI with a scheme, such ashttps://www.example.com/resource.externalReferenceContentTypemust be an IANA media type, such asapplication/jsonortext/html.The API validates the values but does not access or fetch the referenced resource during signing.
If you send a content type without a URI, the API ignores it and does not emit an
externalReferenceassertion.
CAWG identity assertion signing
Use the CAWG signing flow when Content Credentials must include verifiable creator, publisher, sponsor, editor, producer, translator, or contributor identity information. Obtain an S/MIME BR certificate credential before sending the request. Check References to learn more about ordering an S/MIME BR certificate. Please note that CAWG identity assertion signing is supported only in the production environment.
| Field | Requirement | Purpose |
|---|---|---|
credentialId | Required for CAWG signing | Identifies the S/MIME BR certificate credential. |
pin | Required with credentialId | Authenticates use of the selected credential. |
otp | When required by the credential flow | One-time password for SCAL 2 OTP authentication. |
role | Required | Set to one or more of creator, publisher, sponsor, editor, producer, translator, or contributor. Identifies your relationship to the signed content. |
otp when the credential flow does not require it, and do not send a placeholder value.Examples
API key authentication
Minimal production request
curl --location 'https://one.digicert.com/documentmanager/api/c2pa/v1/sign' \
--header 'Accept: application/json' \
--header "x-api-key: ${DIGICERT_API_KEY}" \
--form "accountId=${DIGICERT_ACCOUNT_ID}" \
--form 'role=publisher' \
--form 'file=@/absolute/path/to/sample.jpg'
mTLS authentication
Minimal production request with a client certificate
curl --location 'https://clientauth.one.digicert.com/documentmanager/api/c2pa/v1/sign' \
--cert-type P12 \
--cert "/secure/path/client-auth.p12:${DIGICERT_CERT_PASSPHRASE}" \
--header 'Accept: application/json' \
--form "accountId=${DIGICERT_ACCOUNT_ID}" \
--form 'role=publisher' \
--form 'file=@/absolute/path/to/sample.jpg'
Signing metadata
AI-created image with permissions and an edit action
curl --location 'https://one.digicert.com/documentmanager/api/c2pa/v1/sign' \
--header 'Accept: application/json' \
--header "x-api-key: ${DIGICERT_API_KEY}" \
--form "accountId=${DIGICERT_ACCOUNT_ID}" \
--form 'role=creator' \
--form 'file=@/absolute/path/to/new-image.jpg' \
--form 'isNewCreation=true' \
--form 'createdWithAi=true' \
--form 'generativeAiTraining=constrained' \
--form 'generativeAiTrainingConstraintsInfo=Permitted only for internal evaluation.' \
--form 'additionalActions={"c2pa.edited":{"software":"Example Editor","version":"1.0"}}'
S/MIME signing for a CAWG identity assertion
CAWG signing with an S/MIME credential
curl --location 'https://one.digicert.com/documentmanager/api/c2pa/v1/sign' \
--header 'Accept: application/json' \
--header "x-api-key: ${DIGICERT_API_KEY}" \
--form "credentialId=${DIGICERT_CREDENTIAL_ID}" \
--form "pin=${DIGICERT_CREDENTIAL_PIN}" \
--form "otp=${DIGICERT_OTP}" \
--form "accountId=${DIGICERT_ACCOUNT_ID}" \
--form 'role=publisher' \
--form 'file=@/absolute/path/to/image.jpg'
OTP is conditional Remove the otp line when the selected credential flow does not require SCAL 2 OTP authentication. By default, OTP is not required.
Content-Type header. curl generates the required multipart boundary from the --form fields.Decode the signed media
macOS or Linux
Save the API response as response.json, and then decode the encoded_signed_content field to create the signed media file.
jq -r '.encoded_signed_content' response.json | base64 --decode > signed-output.jpg
Response parameters
| Field | Type | Description |
|---|---|---|
file_name | String | Output filename, normally prefixed with signed-. |
mime_type | String | MIME type of the signed media. |
encoded_signed_content | String | Base64-encoded signed media. Decode the value before saving the binary file. |
manifest_store | String | A JSON-encoded string containing structured manifest data. Parse the string as JSON to inspect the active manifest and assertions. |
Success response shape
{
"file_name": "signed-sample.jpg",
"mime_type": "image/jpeg",
"encoded_signed_content": "<base64-data>",
"manifest_store": "{\"active_manifest\":\"<manifest-id>\",\"manifests\":{}}"
}
200 and encoded_signed_content before treating a request as successful. If an error response contains manifest_store, treat it as partial failure data, not as a completed signed artifact.Errors and troubleshooting
HTTP response codes
| HTTP | Error | Meaning | What your application should do |
|---|---|---|---|
| 200 | - | Signing succeeded. | Decode encoded_signed_content and save the signed media. |
| HTTP | Error | Meaning | What your application should do |
|---|---|---|---|
| 400 | invalid_request | A required field, value, dependency, URI, role, or JSON payload is invalid. | Correct the request. Do not retry it unchanged. You may also get this error if cryptographic attribution of actor identity (CAWG identity assertion signing) is not enabled for your account. Please contact Support to enable it. |
| 401 | wrong_token | The API key is missing, invalid, expired, or belongs to a different environment. | Use a valid key and account ID from the selected environment. |
| 429 | invalid_request | The Media Signing API can process up to four signing requests concurrently for an account. Each request being processed occupies one signing slot. If all four slots are occupied, a new request waits up to two seconds for a slot to become available. The API returns this response when no slot becomes available before the waiting period expires. | Retry with bounded exponential backoff and jitter. |
| 500 | server_error | An unexpected server condition occurred. | Retry safely after a delay; contact Support if it persists. |
| 500 | upstream_service_error | An upstream dependency returned an invalid response. | Retry after a delay. |
| 500 | temporarily_unavailable | The service is unavailable because of maintenance or high load. | Retry later and check DigiCert system status. |
| 504 | request_timeout | An upstream service did not respond in time. | Retry later. |
401 response
{
"error": "wrong_token",
"error_description": "Invalid session."
}
429 response
{
"error": "invalid_request",
"error_description": "Too many requests. Please retry later."
}
Troubleshooting tips
Authentication failure: Confirm that you selected the correct host for the authentication method and environment.
For API key authentication, confirm that
x-api-keyis present and the key and account ID belong to the endpoint environment.For mTLS, confirm the Postman certificate Host contains only the hostname, Port is 443, and the PFX passphrase is correct.
For CAWG signing, confirm that
credentialIdidentifies the intended S/MIME BR certificate,pinis present, andotpis included only when required.
File error: Confirm the file path exists and the file uses a supported media type.
Role error: Send one documented lowercase role.
additionalActions error: Send a JSON object encoded as one form field. Use only c2pa.edited, c2pa.resized, and c2pa.filtered.
AI training and data-use permissions error: Use lowercase allowed, prohibited, or constrained. If constrained, send the matching non-empty ConstraintsInfo field.
External-reference error: Send an accepted absolute URI together with a valid IANA media type.
Unexpected c2pa.opened: Check whether the input already contains Content Credentials. Existing provenance takes precedence over isNewCreation=true.
Multipart error: Remove a manually set Content-Type header and allow your HTTP client to generate the boundary.
References
- Media Signing API: OpenAPI reference.
- S/MIME BR certificate setup: Get an S/MIME BR certificate.
- Digital Source Type vocabulary: IPTC NewsCodes.