Skip to content

Recipes

Recipes

A recipe is a YAML document that configures exactly what happens when you call POST /v1/sign or POST /v1/verify. It controls which watermark engine to use, which C2PA assertions to include, anchoring tier, manifest retention, and billing meter.

Built-in presets

Verbitas ships 10 preset recipes. They are immutable after the release tag.

Recipe IDMedia typeC2PAWatermarkAnchoringUse case
image-genai-v1imagerequiredTrustMarkOTS Tier 1Standard AI image
image-editorial-v1imagerequiredTrustMarkOTS + ArbitrumEditorial photography
image-deepfake-v1imagerequired + deepfake assertionTrustMarkOTS + ArbitrumDeepfake disclosure
image-legal-evidence-v1imagerequiredTrustMark5-min OTS + ArbitrumLegal chain of custody
audio-genai-v1audiorequiredAudioSealOTS Tier 1AI-generated audio
audio-voiceclone-v1audiorequired + voiceclone assertionAudioSealOTS + ArbitrumVoice clone disclosure
video-genai-v1videorequiredVideoSealOTS Tier 1AI-generated video
video-advertising-v1videorequiredVideoSealOTS + ArbitrumAdvertising provenance
text-genai-disclosure-v1textrequired (sidecar)SynthID-TextOTS Tier 1LLM text disclosure
enterprise-strict-v1anyrequiredall applicableOTS + Arbitrum + BYOCBYOK KMS, enterprise

Recipe YAML structure

id: my-image-pipeline-v1 # unique ID; convention: <slug>-v<N>
version: 1 # starts at 1; increment on each change
extends: image-genai-v1@1 # base preset to extend (required for custom recipes)
media_type: image # image | audio | video | text
description: My image pipeline provenance
c2pa:
enabled: true # must be true for ai_generated: true content
assertions:
- ai_generated
- generator
- model
- created_at
require_ingredient_chain: false # set true for editorial / legal-evidence
watermark:
enabled: true
engine: trustmark # trustmark | audioseal | videoseal | synthid_text
payload:
type: manifest_pointer
encoding: compact
soft_binding:
enabled: true
methods:
- exact_watermark # exact_watermark | exact_hash | perceptual_hash
- perceptual_hash
anchoring:
enabled: true
methods:
- opentimestamps # opentimestamps | arbitrum
batch_interval_minutes: 60 # 5 = legal-evidence fast anchor; 60 = standard
kms_mode: kms # kms (default) | byok | dev_local
retention:
manifest_days: 365 # how long to keep the manifest
original_asset_days: 0 # 0 = do not store original asset
derived_asset_days: 30 # 0 = do not store derived (signed) asset
verification:
minimum_confidence: 0.92
ocsp_mode: default # default | required
ambiguous_match_behavior: manual_review # manual_review | reject | accept_partial
billing:
meter: image_sign # see Reference: Meter Kinds
unit: asset
ui:
public_label: "AI-generated image with verifiable provenance"

Step kinds (closed enum)

A recipe specifies which operations run, but the operations themselves are a closed enum. You cannot add new step kinds without an RFC in docs/rfcs/. The current valid values are:

Step kindWhat it does
c2pa_buildConstructs the C2PA claim structure from assertions and metadata
watermark_embedRuns the watermark engine to embed the payload in the asset signal
soft_binding_writeWrites the fingerprint index entry (exact hash, pHash, watermark_id)
anchor_queueEnqueues the manifest digest for the next anchor batch
c2pa_finalizeCalls the signer, receives signature + cert chain + timestamp, assembles JUMBF manifest

These steps run in the order above during every sign job. The recipe controls whether each step is active and which parameters it uses — not the order.

Custom recipes

Custom recipes must extend one of the 10 presets using the extends field. They are validated against packages/recipes/schema/recipe.schema.json on submission.

Custom recipes are immutable after first use. If an asset was signed with my-recipe-v1, it will always verify against my-recipe-v1. To change the recipe, create my-recipe-v2.

Create via API

Requires admin-scoped key.

Terminal window
curl -X POST https://api.verbitas.io/v1/recipes \
-H "Authorization: Bearer vb_admin_..." \
-H "Content-Type: application/yaml" \
--data-binary @my-image-pipeline-v1.yaml

Response:

{ "recipe_id": "my-image-pipeline-v1", "version": 1, "created_at": "2026-05-09T10:00:00Z" }

Errors

CodeMeaning
verbitas.recipes.invalid_schemaYAML does not pass recipe.schema.json validation
verbitas.recipes.unknown_step_kindstep.kind outside closed enum
verbitas.recipes.byok_plan_requiredkms_mode: byok requires Enterprise BYOK plan
verbitas.recipes.conflictRecipe ID + version already exists

Recipe selection guide

Use caseRecipe
AI-generated imageimage-genai-v1
Editorial photographyimage-editorial-v1
Deepfake disclosure requiredimage-deepfake-v1
Legal chain of custodyimage-legal-evidence-v1
AI-generated audio / TTSaudio-genai-v1
Voice clone disclosureaudio-voiceclone-v1
AI-generated videovideo-genai-v1
Advertising video provenancevideo-advertising-v1
LLM text disclosuretext-genai-disclosure-v1
Enterprise, BYOK, all anchorsenterprise-strict-v1
CustomPOST /v1/recipes with extends:

See Guides: Custom Recipes for a complete walkthrough of writing a custom recipe.