Use Ariadne Mark in the final export stage of your image or video generator. The Python SDK adds a recoverable image watermark, signs C2PA provenance and checks the serialized output before publishing it. A persistent registry supports later record recovery.
The qualified media runtime is Linux x86-64 / Python 3.12 on CPU. Start with the Docker release quickstart. Install models during deployment; processing does not download missing dependencies inside a request.
Add an invisible watermark and C2PA record to a PNG or JPEG
This example is for your own new generated image without an existing C2PA credential. Prepare the final dimensions and visual edits first. Supply the actual generation time and public product facts. Choose a new output path; the SDK intentionally does not overwrite an existing result.
In a fresh evaluation directory, after provisioning the SDK:
ariadne init-dev .ariadne/dev
Download python-image-export.py. The function below marks the file and performs a separate verification call. Its command-line entry point creates the SDK with two image threads, the development identity and a persistent registry.
def export_image(sdk, *, source, destination, publisher, system, version, created_at):
record = ProvenanceRecord.create(
publisher=publisher, system=GenerativeSystem(system, version),
media_kind=MediaKind.IMAGE, action=Action.CREATED, created_at=created_at,
)
receipt = sdk.mark(Path(source), Path(destination), record)
verification = sdk.verify(Path(destination))
return {'receipt': receipt, 'verification': verification}
Run the complete downloaded example with your file and its actual timestamp:
python python-image-export.py input.png output.png \
--created-at "$GENERATED_AT" \
--publisher "Example Studio" --system "Example Generator" --system-version "1.0" \
--identity .ariadne/dev --registry .ariadne/registry.sqlite3 --allow-dev
Set GENERATED_AT from your generation job as an ISO 8601 timestamp with timezone; replace the example publisher and system with your actual public product values. Never put user emails, prompts or account IDs into public provenance.
What should a successful export produce?
- A new
output.pngcontaining the watermark and signed C2PA record. - An
output.png.receipt.jsonsidecar and the corresponding registry entry. - JSON with the receipt and separate verification evidence. Development credentials remain explicitly identified as development credentials.
Compare the recovered watermark token with the receipt. Read signature, issuer trust and file binding as separate results; the result guide explains each state. You can also inspect full-SDK sample exports and reports.
Reuse the SDK inside a background worker
The downloaded script handles one file so the first integration is easy to inspect. In a running product, construct one SDK per worker process after that process starts. Call export_image() for jobs and close the SDK during shutdown. Put synchronous media work in your existing bounded queue.
This avoids initializing the models for every request. Do not share a live SDK across a process fork. For more than one worker, size memory and admission limits explicitly; use the stock-product queue example as a reference.
Export video with the same SDK
For a supported final SDR MP4, create a ProvenanceRecord with MediaKind.VIDEO and call SDK.mark() with the selected video_profile and truthful audio_kind.
| Setting | Use |
|---|---|
economy_5s |
Lower-inference marking windows; current default |
economy_2s |
More frequent windows, useful to evaluate for shorter content |
resilient |
Fresh watermark inference on every frame; higher compute cost |
Use audio_kind="none" for silent input or "original" for preserved original audio. Synthetic audio is not independently watermarked by this visual kit. The complete video call is in the SDK integration reference. Read formats, profile behavior and current CPU timings before choosing a mode.
Publication, retries and existing Content Credentials
Publish the returned output after success; preserve the receipt internally. Treat a failed export as a failed job rather than publishing the unmarked input as a fallback. Use new output paths and your own idempotency keys when retrying. A completed earlier job in a batch is not rolled back merely because a later job failed.
If the SDK reports that a credentialed input requires action=altered, preserve that history rather than stripping metadata. Use the underlying SDK's supported Action.ALTERED workflow instead of this new-image helper. Do not claim a newly created origin for an upstream signed asset. See final renditions and the upstream-input checklist.
Production identity and signing · Verifier deployment · Node.js integration