Provenance

Guide: embeds — Provenance ceremonies in your product

@provenance/embed drops our ceremonies (approve, verify, capture, sign and enroll) straight into your UI as <provenance-*> web components. No redirects, no iframes. Embeds give you one script, one auth model and one theming contract.

The widgets are approval, verify badge and receipt, capture, signing, enrollment, order review and trace. This page covers the foundation every widget shares.

The auth model (read this first)

Three moving parts, and the split is deliberate:

| Credential | Where it lives | What it can do | | --- | --- | --- | | Secret API key (prv_test_…) | your backend, never a browser | mint everything, including embed tokens | | Publishable key (prv_pub_…) | safe to ship to the browser | identifies your account to the embed surface — and nothing else (zero data access) | | Embed token (emb_…) | minted per-ceremony, short-lived (≤ 15m) | one widget, one object — the scoped bearer the widget uses |

Object-scoping is a server decision. Your backend calls POST /v1/embed/tokens with your secret key to scope a token to exactly one object. A publishable key can never reach that endpoint — so a value you ship to browsers can never mint a token for an object you didn't authorize.

1. Mint a publishable key (once)

curl $PROVENANCE_API/v1/embed/publishable-keys \
  -H "Authorization: Bearer $PRV_SECRET_KEY" -H "Content-Type: application/json" \
  -d '{ "name": "marketing-site" }'
# → { "publishable_key": "prv_pub_…", "publishable_key_id": "01J…" }

2. Exchange your secret key for a scoped embed token (per ceremony, server-side)

curl $PROVENANCE_API/v1/embed/tokens \
  -H "Authorization: Bearer $PRV_SECRET_KEY" -H "Content-Type: application/json" \
  -d '{ "widget": "approve", "object_id": "appr_9f2…", "ttl": 600 }'
# → { "embed_token": "emb_…", "widget": "approve", "object_id": "appr_9f2…", "expires_at": "…" }

3. Render the component (browser)

<script type="module" src="https://unpkg.com/@provenance/embed"></script>

<provenance-approve
  base-url="https://api.provenance.io"
  publishable-key="prv_pub_…"
  embed-token="emb_…"
  theme="auto">
</provenance-approve>

<script>
  document.querySelector("provenance-approve")
    .addEventListener("pv:approved", (e) => console.log("approved", e.detail));
</script>

React (a thin, type-only peer — React is never bundled):

import { ProvenanceEmbed } from "@provenance/embed/react";
<ProvenanceEmbed baseUrl="…" publishableKey="prv_pub_…" embedToken="emb_…"
  onEvent={(name, detail) => …} />

The rules we don't bend

Theming

provenance-approve {
  --pv-accent: #0c837a;   /* your brand */
  --pv-radius: 10px;
}

Anything outside the allowlist is ignored, and any value containing CSS control characters is dropped (the same sanitizer philosophy we apply to SMS).

Pricing

The platform (publishable keys and embed tokens) is free. Each widget carries its own meter where the underlying action does (an approval still meters approval_resolved; capture still meters the attest). Verification and enrollment are free, permanently.

Observability

embed_tokens_total{widget} and embed_requests_total{widget,status}, plus a token-mint-abuse alert (a spike in minted tokens is the first sign of a leaked secret key).

<provenance-approve> — the approval ceremony

Renders one approval request for your user to decide, in your product:

<provenance-approve base-url="…" publishable-key="prv_pub_…" embed-token="emb_…"></provenance-approve>

<provenance-badge> + <provenance-receipt> — verify anywhere

The viral loop. Verification is client-side and FREE, permanently — no embed token for public artifacts (they're signed with public keys).

<!-- a chip: ✓ Verified · Provenance  /  ✗ Invalid  /  ⚠ Revoked  /  ⏳ Checking -->
<provenance-badge base-url="https://api.provenance.io" token="<intent-token-or-receipt>"></provenance-badge>

<!-- the human-readable receipt/attestation viewer with a live signature check -->
<provenance-receipt base-url="https://api.provenance.io" receipt="<receipt-jws>"></provenance-receipt>

<provenance-enroll> — grow the approver network

The sleeper. Embed approver onboarding in your signup and every enrolling user joins the approver network — the "Sign in with Provenance" funnel.

<provenance-enroll base-url="…" publishable-key="prv_pub_…" embed-token="emb_…"></provenance-enroll>

<provenance-capture> — attested capture in your portal

Capture a photo against a case, in the integrator's UI:

<provenance-capture base-url="…" publishable-key="prv_pub_…" embed-token="emb_…"></provenance-capture>

<provenance-sign> — embedded two-sided signing

One party's leg of a two-sided agreement, in your product — the DocuSign shape, powered by our execution-proof ceremony:

<provenance-sign base-url="…" publishable-key="prv_pub_…" embed-token="emb_…"></provenance-sign>

<provenance-order-review> — clinical order review

A mode="clinical-order" configuration of <provenance-approve> for an EHR/telehealth app — see the clinician-ordering guide for the full flow:

<provenance-order-review base-url="…" publishable-key="prv_pub_…" embed-token="emb_…"></provenance-order-review>

<provenance-trace> — show a model trace anywhere

A keyless view of a Trace share link. It is free, needs no publishable key or embed token, and works cross-origin. The share link is the credential.

<provenance-trace base-url="https://api.provenance.io" share-token="trs_…" theme="auto"></provenance-trace>