External relying party

One API call to verify. A cryptographic proof anyone can check.

One main API call. Decision + cryptographic proof. Independent verification. no inbox, no relay.

Four steps

1
Get an API key

Apply at /design-partner. You receive abx_test_ (sandbox) then abx_live_ (production) with verify:credential scope.

2
One verify call

POST /api/credentials/verify with record_id, credential_jwt, or sui_address + requested_action. Every decision returns proof_id + verify_url when signing is configured.

3
Gate on decision

Clear your action only when decision === "approved". Treat denied and manual_review as fail-closed unless your policy says otherwise.

4
Confirm the proof

GET verify_url from the response. Check signature_valid === true. Store proof_id for audit — anyone can re-verify later.

What you need to do

  • Request an API key (abx_live_…) with verify:credential scope
  • Call POST /api/credentials/verify server-side at your transaction gate
  • Gate on decision === "approved" (or handle denied / manual_review)
  • Optionally GET /api/proof/{proof_id} to independently confirm signature_valid === true

What you get back

  • decision — approved | denied | manual_review
  • proof_id — durable lookup key (aprx_…)
  • verify_url — absolute URL to GET /api/proof/{proof_id}
  • authentication_proof — signed Ed25519 artifact with payload_hash, anchor_status
  • decision_receipt — structured receipt when receipt DB is configured (may be null)

How to verify independently

  • Call GET verify_url (or GET /api/proof/{proof_id}) — no API key required
  • Check signature_valid === true and proof_reliable === true
  • Or verify locally: use public_key + payload + signature (Ed25519 over payload hash)
  • Public issuer key also at GET /api/credentials/public-key
  • No inbox, no email relay — the proof is the artifact

Minimal integration (copy-paste)

Server-side only. One verify call, optional proof confirmation, gate on decision === "approved".

// Step 1 — Verify (server-side only)
const verifyRes = await fetch("https://abraxasworld.xyz/api/credentials/verify", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer abx_live_YOUR_KEY",
  },
  body: JSON.stringify({
    record_id: "ABX-RE-HOSP-001",
    policy_id: "abraxas-verify-v1",
  }),
});

if (!verifyRes.ok) {
  throw new Error(`Verify failed: ${verifyRes.status}`);
}

const result = await verifyRes.json();
// result.decision, result.proof_id, result.verify_url, result.authentication_proof

if (result.decision !== "approved") {
  // Fail closed — do not clear the gated action
  return;
}

// Step 2 — Optional: independently confirm the proof (no API key needed)
const proofRes = await fetch(result.verify_url);
const proof = await proofRes.json();

if (!proof.signature_valid || !proof.proof_reliable) {
  throw new Error("Proof signature invalid or proof no longer reliable");
}

// Clear your gated action — user/asset verified with cryptographic proof on record

Proof lookup

Use verify_url from the verify response. No API key required. Check signature_valid and proof_reliable.

// Independent proof check — anyone can call this
const proofRes = await fetch(
  "https://abraxasworld.xyz/api/proof/aprx_YOUR_PROOF_ID"
);
const proof = await proofRes.json();

if (proof.signature_valid && proof.proof_reliable) {
  // Cryptographically verified — no need to trust Abraxas UI or email relay
  console.log(proof.payload.event_type, proof.anchor_status);
}

curl

curl -s -X POST https://abraxasworld.xyz/api/credentials/verify \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer abx_live_YOUR_KEY" \
  -d '{"record_id":"ABX-RE-HOSP-001","policy_id":"abraxas-verify-v1"}'

curl -s https://abraxasworld.xyz/api/proof/aprx_YOUR_PROOF_ID

Verify modes. pick one

registry

You gate on an Abraxas asset or registry record (e.g. ABX-RE-HOSP-001)

Auth: Authorization: Bearer abx_live_… recommended; optional for public registry lookup

{
  "record_id": "ABX-RE-HOSP-001",
  "policy_id": "abraxas-verify-v1"
}
credential_jwt

User presents a W3C Verifiable Credential JWT from Abraxas Passport

Auth: None — public endpoint when credential_jwt is provided

{
  "credential_jwt": "eyJ…",
  "policy_id": "abraxas-verify-v1",
  "verifier_id": "your-company"
}
policy_check

You gate on wallet verification level for a specific action

Auth: Authorization: Bearer abx_live_… required

{
  "sui_address": "0x…",
  "requested_action": "invest_rwa",
  "policy_id": "abraxas-verify-v1"
}

Policy check actions: browse, book_asset, high_value_transaction, invest_rwa, submit_asset, verified_participant

HTTP status codes

200. Decision approved (registry or credential verified)
202. Manual review required (policy check)
400. Missing or invalid request body
401. Missing or invalid partner API key (when required)
403. Denied by policy check
404. Record not found (registry mode)
422. Credential JWT invalid or revoked

Example verify response (approved)

{
  "decision": "approved",
  "status": "active",
  "assurance_level": 3,
  "policy_id": "abraxas-verify-v1",
  "policy_version": "2026-07-08",
  "decision_reference": "abx-dec-yourco-a1b2c3d4",
  "valid_until": null,
  "record_id": "ABX-RE-HOSP-001",
  "record_type": "asset",
  "verified": true,
  "proof_id": "aprx_cielo_sunrise_7f3a9c2e",
  "verify_url": "https://abraxasworld.xyz/api/proof/aprx_cielo_sunrise_7f3a9c2e",
  "authentication_proof": {
    "proof_id": "aprx_cielo_sunrise_7f3a9c2e",
    "payload_hash": "a3f2…64 hex chars",
    "signature": "base64url Ed25519 signature",
    "signing_key_id": "abraxas-primary",
    "anchor_status": "signed",
    "sui_tx_digest": null,
    "explorer_url": null,
    "verify_url": "https://abraxasworld.xyz/api/proof/aprx_cielo_sunrise_7f3a9c2e",
    "issued_at": "2026-07-20T14:00:00.000Z",
    "event_type": "credential_verify",
    "record_id": "abx-dec-yourco-a1b2c3d4",
    "network": "devnet",
    "status": "active"
  },
  "decision_receipt": null
}

Example proof lookup response

{
  "artifact_type": "authentication_proof",
  "proof_id": "aprx_cielo_sunrise_7f3a9c2e",
  "payload": {
    "proof_id": "aprx_cielo_sunrise_7f3a9c2e",
    "schema_version": "1.0.0",
    "event_type": "credential_verify",
    "record_id": "abx-dec-yourco-a1b2c3d4",
    "payload_hash": "a3f2…",
    "issued_at": "2026-07-20T14:00:00.000Z",
    "network": "devnet"
  },
  "signature": "base64url…",
  "signing_key_id": "abraxas-primary",
  "public_key": {
    "kty": "OKP",
    "crv": "Ed25519",
    "x": "…"
  },
  "signature_valid": true,
  "payload_hash": "a3f2…",
  "anchor_status": "signed",
  "sui_network": "devnet",
  "sui_tx_digest": null,
  "explorer_url": null,
  "issued_at": "2026-07-20T14:00:00.000Z",
  "event_type": "credential_verify",
  "record_id": "abx-dec-yourco-a1b2c3d4",
  "independently_verifiable": true,
  "anchor_note": "Cryptographically signed off-chain. Sui anchor pending package deploy.",
  "proof_status": "active",
  "proof_reliable": true,
  "superseded_by": null,
  "asset_abx_id": "ABX-RE-HOSP-001"
}

Errors and edge cases

Response has decision but no proof_id

Cause: ABRAXAS_SIGNING_KEY not configured on Abraxas production, or proof issuance threw

Action: Contact Abraxas — proofs should always attach when signing is live

GET /api/proof/[id] returns 404

Cause: Proof not persisted (Supabase authentication_proofs) or wrong proof_id

Action: Use proof_id from the verify response immediately; confirm persistence with Abraxas ops

signature_valid === false

Cause: Tampered proof, wrong public key, or unsigned legacy proof

Action: Fail closed — do not clear the transaction

proof_status === refresh_required or superseded

Cause: Asset monitoring detected material state change

Action: Re-run verify or request fresh credential from holder

Get started →Full RP programDeveloper hub →