Developer reference
/api/verify/[id] · JSON verification

Verify a Degree of Proof from any HRIS, ATS, or contractor-vetting pipeline.

A single GET returns the canonical state of any issued Degree. No auth. CORS open. The same endpoint serves browsers, curl, recruitment automation, and back-office reconciliation.

01 — Endpoint

One GET, one credential id.

GET against the canonical URL pattern below. The credential id is the slug shown on the credential card and on the holder's profile — the regex is enforced both client- and server-side.

GET https://proofworks.us/api/verify/<credentialId>
// credentialId matches: ^Po[TO]-\d{5}$
//   PoT-####  Trades  (Track 01)
//   PoO-####  Oddities (Track 02)

Transport notes

  • 01

    CORS open: Access-Control-Allow-Origin: *, methods GET + OPTIONS, Content-Type.

  • 02

    Cache-Control: public, max-age=30, must-revalidate — revocations surface within 30 seconds.

  • 03

    No auth. Treat the credential id itself as the secret — it is the lookup key.

02 — Response shape

Every field the wire exposes.

On 200 the body is one of two shapes — approved (the credential is currently in good standing) or revoked (it was minted then revoked by the panel). Status is binary by design: HRIS integrators branch on a literal without re-deriving.

Field-by-field (camelCase, matched exactly by the JSON returned to your terminal):

status

approved | revoked

Binary projection of the ledger row. 'approved' maps to Credential.status === 'active'; 'revoked' maps to Credential.status === 'revoked'. 'rejected' rows (panel-refused) DO NOT appear here — they 404.

isValid

boolean

Derived server-side from status === 'approved'. Lets downstream systems gate a fan-out on a literal without re-deriving from status. Always true on approved, false on revoked.

id

credential id

The credential id, matching ^Po[TO]-\d{5}$. PoT- = Trades; PoO- = Oddities.

credentialNumber

int

The per-track monotonically incrementing publication number. The 5-digit padded 'PoT-00001' form is derivable as id.split('-')[1].

track

trades | oddities

The track the credential lives on.

skill

string (≤ 4000 chars)

The canonical skill statement — what the steward panel approved.

holderName

string (1–120 chars)

The holder display name. The /api/verify surface deliberately extends the public posture here so a recruiter's portal can render 'Issued to <name>' from one round-trip — no second lookup needed.

issuedAt

ISO 8601

The credential's mint moment, surfaced as a string. Note: this is when the audit was recorded, not when the capability was practised.

revocationReasonconditional

string (≤ 2000 chars, CONDITIONAL)

Only present on revoked rows that carry a non-empty reason. Omitted from the envelope on approved rows. Stewards type this at revoke time; it is the reason a contest panel reads first.

03 — Try it

Copy-paste this curl — it targets the SAMPLE PoT-00012 worked example (not a real issued credential).

PoT-00012 is a SAMPLE worked example the team maintains for documentation only — it never resolves to a real issued credential. Paste straight into your terminal.

cURL — SAMPLE PoT-00012 (not a real issued credential)

SAMPLE · Sample

curl -sS -X GET \
  https://proofworks.us/api/verify/PoT-00012

04 — Worked samples

Approved, revoked, missing, and unavailable.

200 OK — approved (active credential)

SAMPLE · Sample

{
  "status": "approved",
  "isValid": true,
  "id": "PoT-00012",
  "credentialNumber": 12,
  "track": "trades",
  "skill": "Demonstrated competency in oxy-fuel fusion welding of low-carbon steel plate to AWS D1.1.",
  "holderName": "Maya Hernández",
  "issuedAt": "2026-04-12T18:24:53.000Z"
}

200 OK — revoked (still surfaced as issued; reason included when present)

SAMPLE · Sample

{
  "status": "revoked",
  "isValid": false,
  "id": "PoO-00007",
  "credentialNumber": 7,
  "track": "oddities",
  "skill": "Restoration of a 1962 vacuum-tube shortwave receiver to broadcast-grade alignment.",
  "holderName": "Idris Halvorsen",
  "issuedAt": "2025-11-02T15:09:11.000Z",
  "revocationReason": "Evidence provenance could not be re-verified on appeal."
}
404

404 — credential not found (also returned for panel-rejected rows)

SAMPLE · Sample

{
  "status": "not_found",
  "error": "credential_not_found",
  "message": "No issued Degree of Proof matches PoT-99999."
}

404 fires for both unknown IDs and rejected rows — a rejected row was panel-refused and never earned a Degree, so it is NOT in the ledger of issued credentials. Branch on status == 'not_found' (or on HTTP 404) the same way either way.

400

400 — invalid credential identifier

{
  "status": "invalid",
  "error": "invalid_credential_identifier",
  "message": "Credential identifier must match the PoT-00001 or PoO-00001 format."
}

503 — verification temporarily unavailable

{
  "status": "unavailable",
  "error": "credential_verification_unavailable",
  "message": "Credential verification is temporarily unavailable."
}

503 means the service could not complete the lookup. Retry safely; do not treat an unavailable response as proof that a credential is invalid.

05 — Related surfaces

Where to go next.

01

Read /how-it-works for the verification loop end-to-end.

/how-it-works

02

/for-employers — the recruiter-side plain-English reading guide.

/for-employers