Protocol · Eligibility presentation
Abraxas Eligibility Presentation Protocol
A presentation is one audience-bound, one-time eligibility result. It is not a transferable identity passport, not a reusable bearer credential, and not automatic KYC or KYB approval. The partner backend must re-fetch the current public receipt and apply its own policy.
What this is
Any protocol can request one narrow KYC, KYB, authorized-signer, jurisdiction, age, membership, or policy result from Abraxas without collecting the holder’s underlying evidence or inventing its own verification stack. The envelope media type is application/abraxas-eligibility-presentation+json. This is a server-to-server presentation standard. Partners never send a receipt_id. Abraxas derives the one completed Hosted Partner Flow receipt bound to the presentation request. It is not a transferable identity passport, generic KYC form, raw credential wallet, browser-authoritative flow, or reusable bearer token.
Verification sequence
- Create the presentation request from your backend for one audience, policy, version, action, environment, and nonce.
- Redirect the holder to Hosted Partner Flow. Fresh consent is required.
- Issue with only request_ref and the original verifier nonce. Abraxas derives the completed receipt. Partners never send a receipt_id.
- Verify signature and key lifecycle, then re-fetch GET /api/receipts/{id}/public before any grant.
- A presentation is never a bearer credential or automatic KYC/KYB approval.
Discover envelope versions and endpoints at /.well-known/abraxas-eligibility. Signatures reuse the existing Ed25519 receipt verification-key lifecycle. There is no parallel signing trust.
KYC/KYB planning posture
These planning categories are Utila-compatible private result shapes only. There is no live Utila API, wallet governance, AML/KYT, quorum, or transaction-policy integration. A protocol such as Utila still runs those controls after an Abraxas result.
organization_eligible, authorized_signer, jurisdiction_eligible, and institutional_counterparty_eligible are planning categories only. They flow through Policy Proposals → Release Candidates → a reviewed catalog change. A browser or partner cannot self-publish them as a live policy.
Server example
import { AbraxasPartnerKit } from "@abraxas/partner-kit";
const kit = new AbraxasPartnerKit({
partnerId: process.env.ABRAXAS_PARTNER_ID,
policyId: process.env.ABRAXAS_POLICY_ID,
policyVersion: Number(process.env.ABRAXAS_POLICY_VERSION),
requirePolicyVersion: true,
environment: "sandbox",
baseUrl: process.env.ABRAXAS_BASE_URL,
});
export async function requestEligibilityPresentation(nonce) {
const created = await fetch(process.env.ABRAXAS_BASE_URL + "/api/v1/eligibility-presentations/requests", {
method: "POST",
headers: {
"content-type": "application/json",
authorization: "Bearer " + process.env.ABRAXAS_SANDBOX_API_KEY,
},
body: JSON.stringify({
policy_id: process.env.ABRAXAS_POLICY_ID,
policy_version: Number(process.env.ABRAXAS_POLICY_VERSION),
purpose: "Confirm one protocol eligibility result",
action: "retail_access",
action_scope: "sandbox:protocol_access",
environment: "sandbox",
result_category: "age_21",
verifier_nonce: nonce,
}),
}).then((res) => res.json());
return created.hosted_verify_url;
}
export async function issueEligibilityPresentation(requestRef, nonce) {
const issued = await fetch(process.env.ABRAXAS_BASE_URL + "/api/v1/eligibility-presentations/issue", {
method: "POST",
headers: {
"content-type": "application/json",
authorization: "Bearer " + process.env.ABRAXAS_SANDBOX_API_KEY,
},
body: JSON.stringify({
request_ref: requestRef,
verifier_nonce: nonce,
}),
}).then((res) => res.json());
return issued.envelope;
}
export async function verifyEligibilityPresentation(envelope, nonce) {
const verified = await fetch(process.env.ABRAXAS_BASE_URL + "/api/v1/eligibility-presentations/verify", {
method: "POST",
headers: { "content-type": "application/abraxas-eligibility-presentation+json" },
body: JSON.stringify({
envelope,
expected: {
verifier_nonce: nonce,
policy_id: process.env.ABRAXAS_POLICY_ID,
policy_version: Number(process.env.ABRAXAS_POLICY_VERSION),
action: "retail_access",
environment: "sandbox",
},
}),
}).then((res) => res.json());
if (!verified.ok) return { action: "deny", presentation_sufficient: false };
const receipt = await kit.fetchPublicReceipt(verified.payload.receipt_verification_ref);
if (!receipt.ok) return { action: "deny", presentation_sufficient: false };
const evaluated = kit.evaluateFetchedReceipt(receipt.receipt);
return { ...evaluated, presentation_sufficient: false };
}
Where this connects
Hosted Partner Flow · Selective disclosure · Receipt key lifecycle · Policy proposals · Integration Studio