Skip to content

Changelog

Changes to the API and the dashboard, newest first. API v1 is in preview until launch; from launch it's frozen: breaking changes come only in a new version, announced 12 months ahead.

: The checker reads wide pictures

  • Check a picture reads the watermark of a picture more than twice as wide as it is high, or twice as high as it is wide, such as a banner or a phone screenshot: it looks in the centre square, where TrustMark puts the mark.

: POST /v1/verify reads turned pictures

  • POST /v1/verify also reads our watermark at each quarter turn: a picture saved on its side or upside down still leads to its Content Credentials.
  • A TrustMark watermark that isn't ours shows only when the picture's centre reads the very same one, so a picture without a mark no longer shows one by chance, in results and signed results alike.

: Markets and receipts

  • A new markets field on POST /v1/mark and in the Python SDK: eu, us-ca, us-wa, us-ut, or us. A call missing what those laws need is refused, before anything is marked or counted.
  • A mark made with markets has a receipt: what its file carries for each law, and what stays with you, signed with our checker key when you ask for it.

: The checker reads turned pictures

  • Check a picture also reads our watermark at each quarter turn, as TrustMark's own decoder can: a picture saved on its side still leads to its Content Credentials.
  • A TrustMark watermark that isn't ours shows only when the picture's centre reads the very same one, so a picture without a mark no longer shows one by chance.

: California's latent disclosure

  • Two new fields on POST /v1/mark, the Python SDK and the ComfyUI nodes: provider, your legal name, and app_version, your AI system's version beside app_name. With the time, the unique IDs and the source we already record, a mark carries all five items of California's latent disclosure.
  • Without app_name, a manifest no longer names us as the AI system that made the content: it names none.
  • The checker and POST /v1/verify show the provider, the AI system and its version, the model and the creation time: a new origin object in the result.
  • New guides: the EU AI Act and the California AI Transparency Act.

: The Free plan: one per person

  • The Free plan's 1,000 marks a month are one allowance per person: your first organisation has them, and any other you create starts with none until it has a paid plan (402 quota_exceeded says so).
  • Test keys on Free have 100 marks and 100 MB a month; on paid plans, as many as live. New accounts are capped per day across the service; past it, sign-up opens again at 00:00 UTC.

: Limits per organisation

  • The plan's calls a minute count for the whole organisation, all its keys together. Marks and checks that fail after we worked on them have a daily cap per organisation.
  • Limits per address count an IPv6 address by its /64. Without a key, the whole service answers at most 5,000 checks a day (500 signed); with a key (free), checks count toward your organisation's calls a minute. The Python SDK waits out a 429 that asks for a minute or less.

: Clip limits

  • A clip holds up to 4,500 frames (2.5 minutes at 30 frames a second, 75 seconds at 60): what we can mark within a job's time. A flat clip's watermark strength is now chosen from a sample before every frame is marked, so it takes one pass.
  • Each plan marks a few clips at a time (Free 1, Indie 2, Startup 3, Scale 5), and clips that fail after we worked on them have a daily cap. Past either, 429 rate_limited with Retry-After.

: Clip downloads

  • A finished clip's file is kept for a day, and each download link works for 5 minutes, up to 5 links per clip. Asking again within a link's 5 minutes gives the same link's time. Each link after the first counts the file's size against the month's data. New fields: download_links_left and download_error.
  • Marked clips come back at up to 20 Mbit/s of video.

: Songs and clips

  • POST /v1/mark marks songs: MP3, WAV and M4A up to 15 minutes, with Meta's AudioSeal in the sound, shaped under the music so no one hears it, and signed, time-stamped Content Credentials. A song counts five marks per started minute. New headers: X-Marks-Counted and X-Audio-Watermark.
  • And clips: MP4 up to 5 minutes at 1080p, with Meta's Video Seal in every frame, carrying an ID that leads to the clip's durable credential, and AudioSeal in its sound. A clip is a job: 202, then GET /v1/marks/{id} for its status and a download link. A clip counts five marks per started second; its safety check reads 12 frames, two marks each.
  • Uploads take a clip of up to 1 GB. POST /v1/verify reads songs and clips, and POST /v1/check clips. A new webhook event, mark.failed, for a clip whose job failed.
  • The Python SDK 0.2.0 marks songs and clips (it waits for a clip's job), and the ComfyUI nodes add Mark & Save Audio and Mark & Save Video.

: Launch: plans, uploads, webhooks, and API v1 frozen

  • Paid plans: Indie, Startup and Scale, monthly or yearly, bought and changed from the dashboard's Billing page through Stripe. Monthly plans run past their allowance into extras (USD 0.0003 a mark, USD 0.10 a GB of data), billed on the 1st, up to ten times the allowance; Free and annual plans stop at it. GET /v1/usage adds marks.ceiling.
  • POST /v1/uploads: a request now carries at most 4 MB; files up to 25 MB go up first, straight to our storage in Zurich, and calls name them in upload (or input_upload). The Python SDK does it by itself. New error codes: upload_not_found, storage_unavailable.
  • Webhooks: mark.completed and check.blocked, signed (Kennmarq-Signature, Stripe's scheme), retried for a day. Endpoints are added in the dashboard.
  • API v1 is frozen: additions only, 12 months' notice before anything breaking (versioning), and an OpenAPI 3.1 document at /v1/openapi.json.
  • The trust center, the status page, the robustness report for picture marks, and the legal pages: terms, privacy, the DPA and our two sub-processors.

: Local mode, the Python SDK and the ComfyUI nodes

  • POST /v1/sign: local mode's signature. The watermark and the Content Credentials are made on your machine, and only the manifest (about 13 KB, never pixels) comes here to be signed and time-stamped. We sign only what a cloud mark carries: an AI source type, no thumbnails, every assertion as the claim hashes it. Keys need the sign scope; each file counts one mark.
  • The Python SDK: the cloud API, local mode, the safety check on your machine, and verify. And the ComfyUI nodes: Mark & Save Image and Safety Check. Both go to PyPI and the ComfyUI Registry with the launch.
  • A new kind of transparency-log entry, c2pa.local_signature, which holds the file's hard binding where a cloud signature's holds its hash. Local marks with a watermark keep a durable credential too, without a file hash: same_file is then null.

: The safety check

  • POST /v1/check: screens a picture for sexual content with an apparent minor or a realistic face, the AI Act's Art. 5 bans, under the policy ai-act or safe-only. It answers allow, flag or block, with the reason; never an age or an identity. Two marks per picture; keys need the new check scope.
  • check on POST /v1/mark: the file and any input are checked before marking. A block answers 422 content_blocked with the check, and nothing is marked; a flag marks, with X-Safety-Verdict and X-Safety-Reason.
  • Our own floor on every mark, whatever the policy: explicit content with someone who appears to be a child is never marked.
  • The check's models, their licences and their measured error rates are published.

: The free checker

  • Check a picture: whether it carries Content Credentials and a TrustMark watermark, ours or anyone's, and what they say. The check runs in the browser; the picture never leaves the device.
  • POST /v1/verify: the same check through the API, no key needed, 10 files a minute and 200 a day per address. With signed=true, a result signed by our checker key (JWS, ES256), written to the transparency log before it's returned, with X-Log-Index; the key is at GET /v1/verify/key. See POST /v1/verify.
  • Durable Content Credentials: every watermarked file's manifest store is kept under its watermark ID, so a copy whose metadata was stripped leads back to it. GET /v1/credentials/{watermark_id} returns it, as JSON or as a .c2pa file.
  • A new kind of transparency-log entry, checker.result: the hashes of each signed result and of the file it's about.

: The transparency log

  • Every signature from POST /v1/mark and every token from POST /v1/tsa/{key} is appended to a public, append-only log before it's returned. Both responses carry its place in X-Log-Index.
  • GET /v1/log/root, /roots, /proof/{entry}, /consistency, /entries and /key: signed roots and the proofs to check them, no key needed. See the transparency log.
  • Each organisation's audit-log head is anchored in the log whenever it moves; the dashboard's audit page shows the latest anchor.

: API v1 preview: marking pictures

  • POST /v1/mark: an invisible watermark and signed, time-stamped C2PA Content Credentials for PNG, JPEG and WebP pictures up to 25 MB.
  • POST /v1/tsa/{key}: our RFC 3161 time-stamp server, with tsa-only keys.
  • GET /v1/certificate and GET /v1/usage.
  • Organisations with roles, projects, test and live keys with scopes and IP allowlists, and a hash-chained audit log with CSV and JSON export.