Attribute published AI content
Publish a provenance record per post, with model and editors, and embed the badge next to it.
Who this is for
Newsrooms, blogs, docs sites and content platforms that publish AI-assisted work.
The problem
Readers, search engines and other agents cannot tell how a piece was made or whether it changed since. A signed record per piece, linked from the page, answers both and makes corrections public.
How it works
- At publish time, the site hashes the final text and posts a provenance record with the model and editors.
- The page embeds the badge and a
<link rel="alternate">that points agents at the record. - A correction is an erratum on the record, never a silent edit.
Routes it uses
POST /v1/records: append a signed record; the answer carries its digest and inclusion proof.POST /v1/errata: append a public correction to one of your records.GET /r/{digest}?format=json: one record: publisher, key, model, log position and verdict.
Set it up
Step 1. Hash the published text
Hash the exact bytes you serve, such as the rendered markdown or HTML body, and keep the method fixed so readers can reproduce it.
Check: Re-hashing the live page body gives the record's asset digest.
Step 2. Publish the record
Post a provenance record with artifact (digest, type, version, title, url), model, created_at and edited_by for the editors. The answer carries the record digest and its inclusion proof.
BODY='{ ...record }'
SIG=$(printf %s "$BODY" | ./sign-ed25519) # base64url signature over these exact bytes
curl -s -X POST 'https://aisourceoftruth.com/v1/records' \
-H "Authorization: Bearer $AISOT_TOKEN" \
-H "X-AISOT-Key-Id: $AISOT_KEY_ID" \
-H "X-AISOT-Signature: $SIG" \
-H "Idempotency-Key: $(uuidgen)" \
-H 'Content-Type: application/vnd.aisot.record+json' \
--data-binary "$BODY"
Check: GET /r/{digest} shows the record within seconds.
Step 3. Embed the badge
Place the record's embed snippet (from the record page or registry.embed_html in its JSON) next to the article.
curl -s -H 'Accept: application/json' 'https://aisourceoftruth.com/r/{digest}?format=json'
Check: The page links to /r/{digest} and carries the alternate link.
Step 4. Correct in public
When the piece changes, publish a new record for the new text with lineage naming the old record, and file an erratum on the old one.
BODY='{"record_digest":"{digest}","correction":"{what changed and why}"}'
SIG=$(printf %s "$BODY" | ./sign-ed25519) # base64url signature over these exact bytes
curl -s -X POST 'https://aisourceoftruth.com/v1/errata' \
-H "Authorization: Bearer $AISOT_TOKEN" \
-H "X-AISOT-Key-Id: $AISOT_KEY_ID" \
-H "X-AISOT-Signature: $SIG" \
-H "Idempotency-Key: $(uuidgen)" \
-H 'Content-Type: application/json' \
--data-binary "$BODY"
Check: The old record's verdict becomes check with an erratum reason.
Publishing needs a publisher key and a token. The one-time setup is on /agents and in the plan's design.md.
Wire it into your agent
Hook the publish step of your CMS or static site build, after the final render. Fail the build if the record is refused, so no page ships without one.
MCP: add https://aisourceoftruth.com/mcp to the agent's MCP servers. Tools used: publish_record, resolve_record. Read tools need no token.
With the PromptReports products, or alone
- PromptReports: PromptReports already publishes a record per post this way; its blog records are live examples to copy.
- CommitOps: If a post announces a shipped feature, link its record to the matching promise in CommitOps.
- Alone: every step above uses only AI Source of Truth.
Expected outcomes
- Every AI-assisted piece has a public record with model and editors.
- Corrections appear on the record page and in the event feed.
What it does not prove
- The record carries what you state. Readers see it as your statement, labeled ATTESTED.
The OpenSpec plan for your agent
Your coding agent fetches the plan and writes it into your repo as openspec/changes/integrate-aisot-content-attribution/:
curl -H 'Accept: application/json' 'https://aisourceoftruth.com/use-cases/attribute-published-content/openspec?lang=python&with=promptreports,commitops'
proposal.md: why, what changes in your product, impact.design.md: where the calls sit in your agent, with code for each call.tasks.md: checkable tasks, each step paired with a check against the live registry.specs/content-attribution/spec.md: the requirements and scenarios.
Read it here: OpenSpec plan. Back to all use cases or the documentation library.