Documentation

Record agent output. Let anyone check it.

An agent records its final JSON output (or you record a file). The recipient gets the unchanged content, a record ID and a Verify link, and checks for themselves whether it matches what was recorded.

What a check proves — and what it doesn't

ShownMeaning
Content matches this recordThe content you supplied produces exactly the hash recorded under this ID.
Recorded atThe time ClearedBadge's server accepted the record. Without an Arweave anchor this is ClearedBadge's own record of the time, not an independent timestamp.
Arweave statusWhat the ClearedBadge anchor service reports about publishing this record on Arweave. Separate from the content check.

A match does not prove that the content is true or correct, which agent or organisation made it, that it was authorised, or that the other party received it. The record is created by the sender; it is not an acknowledgement of receipt.

Record

Agent output (JSON event) — through the connector

Save the agent's final output as one JSON object. Any fields are allowed; ClearedBadge does not interpret them. The agent records it once with the ClearedBadge connector (tool register_event), after the user has signed in: see For AI agents. Each account has a small registration quota. The engine canonicalises the JSON with RFC 8785 and records the SHA-256.

POST /record-event is reserved for the ClearedBadge connector (a server credential). A direct request without it is refused and records nothing; the earlier command-line agent recorder therefore no longer records on its own.

Do not retry a registration automatically. After a timeout the record may exist; a new registration creates a second, separate record.

A file — on the website

Use Record. Any file type up to 4 MB (4,000,000 bytes). No account is needed: to keep the registry open for everyone, the engine allows a few files per connection per hour and per day, and a total per day. The page shows the record ID, the Verify link and a downloadable receipt.

Keep the receipt

Hand the recipient the unchanged content together with the record ID or the Verify link.

Verify — for the recipient

  1. Open the Verify link (or go to Verify and enter the record ID).
  2. Drop the file you received, or choose Paste JSON instead and paste the JSON event.
  3. Press Verify. The comparison runs in your browser.
ResultMeaning
✓ Content matches this recordYour content produces the recorded hash.
✕ Content does not match this recordYour content produces a different hash. Even one changed character or byte gives this result.
! Unable to verifyThe check could not run: for example invalid JSON, pasted text for a file record, or a record whose hashing method is not clear. This is not a mismatch.
! Record not found / unreachableNo record for this ID, or the service could not be reached. Not a mismatch.

Example from a real test: verify?id=baf74f78-5bc7-45e4-b55d-45f34d0f5d42 — the original event.json matches; a copy with one value changed (900 → 901) does not.

File or JSON event

Hash coversConsequence
FileSHA-256 of the exact bytesAny change — also re-saving, reformatting or a changed PDF timestamp — gives no match.
JSON eventSHA-256 of the RFC 8785 canonical JSONWhitespace and key order do not matter; every value does. Duplicate keys, NaN or Infinity cannot be checked.

The record itself determines the method, never the file name. A .json file recorded through Record is a file record: check it as a file, byte for byte. In the fields of GET /verify/:id:

For RFC 8785 use an existing implementation, for example canonicalize (npm, by RFC 8785 co-author Erdtman, also served at /vendor/canonicalize.js) or rfc8785 (PyPI). Sorting keys alone is not RFC 8785.

Arweave status: Submitted and Confirmed

Submitted — confirmation pendingThe anchor service has submitted a transaction. Not yet confirmed.
Confirmed on ArweaveThe anchor service reports that its checks passed: at least 20 block confirmations and a matching hash of the published payload.
Not yet anchoredNo anchoring attempt has been recorded yet.
Anchoring pausedNew records are currently not anchored on Arweave. The record is stored in the ClearedBadge registry and can be verified; its recorded time is ClearedBadge's own record, without an independent external timestamp.
Anchoring not startedAnchoring was deliberately not started, with a reason: the daily limit or budget was reached, the anchoring wallet balance was too low, or anchoring was paused by configuration. The record itself is stored and can be verified; it is not anchored on Arweave, and it is not picked up again automatically.
Status temporarily unavailableThe status could not be retrieved. This does not mean the record is not anchored.

The status is reported by the ClearedBadge anchor service; the Verify page does not itself read the chain. To check independently: fetch the payload bytes from https://arweave.net/raw/<txid>, hash them with SHA-256, compare with latest.payload_sha256 from /anchor-status, and check that the payload names this record ID and hash. Block confirmations: https://arweave.net/tx/<txid>/status.

When something goes wrong

SituationWhat happenedWhat to do
HTTP 400 / 413 / 415Refused: invalid JSON, not a JSON object, too large, wrong content type. Nothing was recorded.Fix the input and record again.
Timeout, dropped connection, HTTP 5xxOutcome unknown. A record may exist.Keep the attempt, do not send again blindly, and investigate first — see below.
File over 4 MBRefused with 413 file_too_large. Nothing was recorded.Use a smaller file.
Event over 1 MiBRefused by the engine. Nothing was recorded.Record a smaller event, e.g. with a hash of a large attachment inside it.
HTTP 429 rate_limitedA registration limit was reached (per connection or in total). Nothing was recorded.Try again after the time in Retry-After.
HTTP 403 registration_paused, 503 registration_unavailableRegistration is switched off or cannot be checked right now. Nothing was recorded.Try again later.

After an unknown outcome

  1. Keep the attempt. Keep the unchanged content and what you know about the attempt. The connector reports an unknown outcome as such and never sends again on its own.
  2. Do not send again blindly. A second POST creates a second, separate record.
  3. Investigate first.
    • File: POST /verify-file without ?id= (multipart, field file) looks the file up by its hash and returns result: "match" with the badge_id of the earliest record, or not_found. This sends the file to the engine again; it is compared, not stored.
    • JSON event: there is no public lookup by content. Check whether a receipt was written or your own logs show a 201 with a record_id.
  4. Only then decide. If no record can be found and you need a record ID, record again knowingly. If the first attempt did create a record, both records are valid; either ID verifies the same content.

What leaves your device

Both file methods give the same fingerprint for the same file and are verified the same way. Neither shows who made a file, that its content is true, or that anyone received it. The time on a record is when ClearedBadge registered the fingerprint (“Fingerprint registered by ClearedBadge at”); without external anchoring it is not an independently confirmed timestamp. Older records, made before the method was stored, show the fingerprint method as Not specified.

Recording is currently free. New records are kept in the ClearedBadge registry and are not anchored on Arweave for now. Record once per final output, not every step.

API reference

Using the API means you accept the Beta Terms; see the Privacy Policy for what the API receives and stores.

Engine: https://clrbadge-seven.vercel.app · Anchor service: https://clrbadge-anchor.vercel.app · Reading and verifying need no key. POST /upload and POST /record-file-hash are public with server-side limits, counted together; POST /record-event is for the ClearedBadge connector only.

EndpointPurpose
POST /record-eventClearedBadge connector only (server credential; otherwise 401 unauthorized or 403 record_event_disabled). Body: any JSON object (max 1 MiB). 201 → record_id, hash, canonicalization: "RFC8785", hash_algorithm: "SHA-256", recorded_at, status. 400 body_must_be_json_object / canonicalization_failed.
POST /uploadmultipart/form-data, field file, max 4,000,000 bytes. 201 → badge_id, hash, created_at, status, … 400 no_file, 413 file_too_large, 429 rate_limited (with scope, window, Retry-After), 403 registration_paused, 503 registration_unavailable.
POST /record-file-hashPrivate file registration: the body is exactly {"sha256":"<64 lowercase hex>"}, the SHA-256 of the exact file bytes, as text/plain or application/json (max 256 bytes; no file, no name, no size). 201 → the same fields as /upload, with fingerprint_method: "device_sha256" (/upload answers "server_sha256"). 400 invalid_fingerprint, 413 body_too_large; 429, 403 and 503 as for /upload, on the same limits.
GET /verify/:idThe recorded facts: badge_id, hash, created_at, status, record_type, and metadata.fingerprint_method for newer file records. 400 invalid_id, 404 not_found.
GET /anchor-status/:idAnchor service. status: not_anchored, submitted, confirmed or failed, with latest.txid and latest.confirmed_at. When anchoring was not started: not_anchored plus not_started.reason and not_started.since; while new submissions are paused, not_started.reason is submission_paused (no since).
POST /verify-event, POST /verify-fileServer-side comparison. These send your content to the engine; the Verify page does not use them.

record_id and badge_id are the same identifier; recorded_at and created_at are the same time. The same content may be recorded more than once; each record is separate.

← Back to CLRBADGE