Media Signing API

Sign media with C2PA Content Credentials by using the DigiCert Content Trust Manager Media Signing API.

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.

Choose one request-authentication method—API key or mutual TLS—and use credentials issued for the same environment as the endpoint.

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.

The maximum supported file size is 80 MB per upload. Validate the file size before sending the request. You can upload only one media file per request.

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.

Create and deploy a replacement before the certificate expires. Requests that continue to use an expired certificate cannot complete the mTLS handshake.

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

MethodRequest configurationDo 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 methodProduction endpoint
Client authentication certificate (mTLS)https://clientauth.one.digicert.com/documentmanager/api/c2pa/v1/sign
API keyhttps://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

HeaderRequirementValue and guidance
AcceptRecommendedapplication/json
x-api-keyAPI-key requests onlyYour API key. Omit this header for mTLS requests.
Content-TypeGenerated by clientLet curl, Postman, or your SDK generate multipart/form-data with the correct boundary. Do not hard-code this header.

Body

FieldTypeRequirementDescription
accountIdStringRequiredYour Content Trust Manager account ID for the selected environment. Find it on the Account Details page. The account ID uses UUID format.
fileFileRequiredBinary media file to sign. See Supported media types.
roleEnumRequiredStandard roles: contributor, creator, and publisher. CAWG roles also include sponsor, editor, producer, and translator. Send one lowercase value.
credentialIdStringConditionalIdentifier for the S/MIME BR certificate credential. Required for CAWG identity assertion signing.
pinStringConditionalPIN for the selected credential. Required when you provide credentialId.
otpStringConditionalOne-time password for SCAL 2 OTP authentication, when required by the credential flow.
additionalActionsStringOptionalJSON object encoded as one form string. Allowed keys: c2pa.edited, c2pa.resized, and c2pa.filtered.
digitalSourceTypeStringOptionalIPTC/C2PA Digital Source Type URI. createdWithAi=true overrides this value with the Generative AI digital source type.
includeExifMetadataBooleanOptionalSet to true to add available source EXIF data in the c2pa.metadata assertion.
isNewCreationBooleanOptionalSet to true only for new content without existing Content Credentials. This field has no effect if the media already contains Content Credentials.
createdWithAiBooleanOptionalSet to true for AI-created content. Applies only when the API records c2pa.created.
aiInferenceEnumOptionalallowed, prohibited, or constrained.
aiInferenceConstraintsInfoStringConditionalRequired and non-empty when aiInference=constrained.
generativeAiTrainingEnumOptionalallowed, prohibited, or constrained.
generativeAiTrainingConstraintsInfoStringConditionalRequired and non-empty when generativeAiTraining=constrained.
dataMiningAndAnalyticsEnumOptionalallowed, prohibited, or constrained.
dataMiningAndAnalyticsConstraintsInfoStringConditionalRequired and non-empty when dataMiningAndAnalytics=constrained.
nonGenerativeAiTrainingEnumOptionalallowed, prohibited, or constrained.
nonGenerativeAiTrainingConstraintsInfoStringConditionalRequired and non-empty when nonGenerativeAiTraining=constrained.
externalReferenceUriStringOptionalAbsolute 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.
externalReferenceContentTypeStringConditionalIANA 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.

CategorySupported media types
Still imageimage/jpeg, image/png, image/x-adobe-dng, image/heic, image/heif, image/tiff, image/webp,
image/svg+xml, image/gif, image/jxl
Videovideo/mp4, video/x-msvideo, video/quicktime
Audioaudio/wav, audio/mp4, audio/flac, audio/mpeg
Documentapplication/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.

InputSystem-managed actionResult
New content; isNewCreation=truec2pa.createdThe manifest records a newly created asset.
Content without isNewCreation=truec2pa.openedThe source is represented as an ingredient.
File already has Content Credentialsc2pa.openedExisting provenance wins, even when isNewCreation=true.
If the file already contains Content Credentials, 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 keyMeaning
c2pa.editedThe content was edited.
c2pa.resizedThe asset dimensions changed.
c2pa.filteredA filter or effect was applied.

Optional fields for each action

FieldDescription
softwareSoftware name written to softwareAgent.
versionSoftware version. When software and version are present, the manifest writes softwareAgent as name/version.
timeISO 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 valueManifest valueConstraint rule
allowedallowedA matching ConstraintsInfo value is ignored.
prohibitednotAllowedA matching ConstraintsInfo value is ignored.
constrainedconstrainedThe matching ConstraintsInfo field is required and must be non-empty.
Permission fieldMatching constraint field
aiInferenceaiInferenceConstraintsInfo
generativeAiTraininggenerativeAiTrainingConstraintsInfo
dataMiningAndAnalyticsdataMiningAndAnalyticsConstraintsInfo
nonGenerativeAiTrainingnonGenerativeAiTrainingConstraintsInfo

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.

EXIF data can contain capture time, device, software, or location information. Confirm that the metadata is appropriate to publish before enabling ingestion.

External references

Use externalReferenceUri and externalReferenceContentType together to add a c2pa.external-reference assertion.

  • externalReferenceUri must be an accepted absolute URI with a scheme, such as https://www.example.com/resource.

  • externalReferenceContentType must be an IANA media type, such as application/json or text/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 externalReference assertion.

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.

FieldRequirementPurpose
credentialIdRequired for CAWG signingIdentifies the S/MIME BR certificate credential.
pinRequired with credentialIdAuthenticates use of the selected credential.
otpWhen required by the credential flowOne-time password for SCAL 2 OTP authentication.
roleRequiredSet to one or more of creator, publisher, sponsor, editor, producer, translator, or contributor. Identifies your relationship to the signed content.
Store the PIN and OTP in protected secret variables. Omit 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.

These examples omit an explicit 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

FieldTypeDescription
file_nameStringOutput filename, normally prefixed with signed-.
mime_typeStringMIME type of the signed media.
encoded_signed_contentStringBase64-encoded signed media. Decode the value before saving the binary file.
manifest_storeStringA 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\":{}}"
}
Require HTTP 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

HTTPErrorMeaningWhat your application should do
200-Signing succeeded.Decode encoded_signed_content and save the
signed media.
HTTPErrorMeaningWhat your application should do
400invalid_requestA 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.
401wrong_tokenThe API key is missing, invalid, expired, or
belongs to a different environment.
Use a valid key and account ID from the selected
environment.
429invalid_requestThe 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.
500server_errorAn unexpected server condition occurred.Retry safely after a delay; contact Support if it
persists.
500upstream_service_errorAn upstream dependency returned an invalid
response.
Retry after a delay.
500temporarily_unavailableThe service is unavailable because of
maintenance or high load.
Retry later and check DigiCert system status.
504request_timeoutAn 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-key is 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 credentialId identifies the intended S/MIME BR certificate, pin is present, and otp is 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