Skip to content

Certificates

An MC4P certificate is a JSON-LD document that describes one product or one image, plus a signed proof that Mintall issued it for a specific domain.

Every endpoint on this page is public. Certificate responses carry Cache-Control: public, max-age=86400, so a crawler can cache a certificate for a day.

Terminal window
curl https://api.mintall.ai/api/v1/mc4p/products/$PRODUCT_ID/certificate

Mintall publishes the certificate as its own JSON-LD block on the product page, alongside whatever product markup the store already emits. It identifies the same product by productID and url.

{
"@context": ["https://schema.org", { "mintall": "https://mintall.ai/ns/" }],
"@type": "Product",
"productID": "...",
"url": "https://merchant.example/products/pendant",
"mintall:issuedFor": { "domain": "merchant.example", "productID": "..." },
"mintall:status": { "canonicalSource": "..." },
"mintall:images": [...],
"mintall:trust": { "certifiedAssets": 4, "totalAssets": 5, "coveragePercent": 80 },
"verification": { "verifyEndpoint": "...", "hasSignature": true },
"proof": { "type": "JsonWebSignature2020", "jwt": "eyJ...", "algorithm": "RS256" }
}

mintall:trust reports coverage as two counts and their ratio. All three are signed into the JWT.

Terminal window
curl https://api.mintall.ai/api/v1/mc4p/assets/$ASSET_ID/certificate

An asset certificate is the full expansion of one entry in the product certificate’s mintall:images[] array, as a mintall:-namespaced ImageObject. It adds mintall:contentCredentials (the C2PA manifest summary and hashes) and mintall:nft where one exists.

Terminal window
curl -L https://api.mintall.ai/api/v1/mc4p/assets/$ASSET_ID/content -o image.jpg

Every certificate names the signed image by contentUrl: on the asset certificate, and on each entry of the product certificate’s mintall:images[]. That URL is this endpoint. It redirects to a short-lived download URL for the C2PA-signed bytes, so store contentUrl and follow it when you need the image; the Location it redirects to expires. The redirect is Cache-Control: no-store.

A browser cannot read that Location, and a fetch that follows it reaches storage with Origin: null, which CORS rejects. Send Accept: application/json to get the same URL as {"url": ...} with no redirect, then hand it to whatever needs the file, such as a Content Credentials viewer on another origin.

Terminal window
curl -H "Accept: application/json" https://api.mintall.ai/api/v1/mc4p/assets/$ASSET_ID/content

An asset whose product is not active returns 404 here, matching its identity-only certificate, which carries no contentUrl.

Every response is one of three outcomes:

if (res.status === 404) {
// Not served by Mintall: disabled, deleted, or never ingested.
} else if (!certificate.proof) {
// Known to Mintall, not currently publishing trust data. Not a failure.
} else {
// Signed by Mintall and verifiable.
}

A product that exists but is not active — the merchant has visibility off, or the product sits outside their plan capacity — returns 200 with identity fields only. mintall:images, mintall:trust, verification, and proof are omitted:

{
"@context": ["https://schema.org", { "mintall": "https://mintall.ai/ns/" }],
"@type": "Product",
"productID": "...",
"url": "https://merchant.example/products/pendant",
"mintall:issuedFor": { "domain": "merchant.example", "productID": "..." },
"mintall:status": { "canonicalSource": "..." }
}

Assets follow their parent product. If it is not active, the asset certificate omits mintall:contentCredentials, mintall:nft, verification, and proof. An asset Mintall does not know, or one with no certificate, returns 404.

proof.jwt is an RS256 JWT signed by Mintall. It expires 7 days after issuance, so refetch the certificate rather than caching the token past its exp.

Claim Meaning
iss The issuing API base URL
iat Issued at
exp Expires, 7 days after iat
domain The domain the certificate is authorized for

The header carries a kid. Match it against the keys from JWKS to pick the right public key.