Proofs

Validate proof token

Validate a JWT proof token. Public endpoint — no authentication required. Can also be done offline using JWKS.

post/api/v1/proofs/validate

Request

  • Base URL: https://api.proof.holdings
  • URL: https://api.proof.holdings/api/v1/proofs/validate
  • Auth: none required

Request body

proof_tokenstring required

JWT proof token to validate

identifierstring

Optional binding check: the identifier you expect this proof to be about. When supplied, the proof is only valid if it hashes to the token's signed identifier_hash — a mismatch returns valid:false with reason "identifier_mismatch", and a proof whose hash is derived from ciphertext returns "identifier_unverifiable". For a proof about a verified identifier (phone, email, domain, social, wallet, telegram_bot) any format is accepted and canonicalized as it was at issuance; a proof of an approval decision binds only on the exact recipient value it was issued for.

Example request

{
  "proof_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
  "identifier": "+19295909022"
}

Response

Validation result

validboolean required
proof_idstring

Public proof id (ph_ctl_*), present when the proof is registered

reasonstring

Failure reason: expired, revoked, suspended (a reversible pause — the owner can lift it), invalid, identifier_mismatch (the supplied identifier is not what this proof is about), or identifier_unverifiable (the proof's hash is derived from ciphertext, so no identifier can be bound to it)

suspended_atstring date-time

When the suspension began — present only with reason suspended

messagestring

Human-readable message

revoked_atstring date-time

When the proof was revoked (only present when reason is "revoked")

revoked_reasonstring

Reason for revocation (only present when reason is "revoked")

token_type'delegation'

Present ONLY when the submitted token is a delegation (m-delegation-verifier-ref). Its absence means the answer is about a verification/decision proof and the verification block applies.

Example response

{
  "valid": true,
  "proof_id": "ph_ctl_0123456789abcdef0123456789abcdef",
  "verification": {
    "id": "507f1f77bcf86cd799439011",
    "type": "phone",
    "channel": "whatsapp",
    "identifier_hash": "a1b2c3d4e5f6...",
    "decision": "approve"
  },
  "reason": "expired",
  "message": "Proof token has expired",
  "delegation": {
    "id": "ph_dlg_0123456789abcdef0123456789abcdef",
    "principal": "postmarkapp.com",
    "delegate": "pkg:npm/postmark-mcp",
    "scope": [
      "send-email"
    ],
    "control_proof": "ph_ctl_0123456789abcdef0123456789abcdef"
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.