Integrators · Partner Flow

Partner Flow — browser redirect integration

Redirect holders to Abraxas, receive a signed session receipt on your callback URL, and verify it server-side via the public receipt endpoint. No API key in the browser.

Canonical production host: https://abraxasworld.xyz · Open receipt tester →

PARTNER FLOW · START HERE

First integration tasks

  1. Apply at /integrations#apply — describe your age-gated checkout or eligibility gate.
  2. Read /docs/partner-flow — entry URL params, lifecycle, and receipt checks.
  3. Implement callback handler — fetch public receipt server-side; never trust URL params alone.
  4. Run npm run partner:conformance after operators provision partner_id, policy_id, and return_url.

Sandbox limitation: sandbox policies and test credentials are operator-provisioned after approval. Production-usable receipts require production policy context — no self-serve production access.

PARTNER_FLOW_RP_PARTNER_ID=your-partner-id \
PARTNER_FLOW_RP_POLICY_ID=your-policy-v1 \
PARTNER_FLOW_RP_RETURN_URL=https://your-app.example.com/auth/abraxas/callback \
PARTNER_FLOW_RP_BASE_URL=https://abraxasworld.xyz \
npm run partner:conformance

Server-side receipt check: Your backend must call GET /api/receipts/{receipt_id}/public and validate the signed result before granting access. The public receipt tester is a mirror only.

Jump to receipt verification docs

Choose your integration path

Partner Flow (this guide)

Web or mobile app with a browser redirect; age-gated retail, booking, or policy-based eligibility

Auth: Browser session cookie on abraxasworld.xyz only — no partner API key in client code

Start: https://abraxasworld.xyz/partner/verify?partner_id=…&policy_id=…&return_url=…

Verify: GET /api/receipts/{receipt_id}/public (no auth)

Server verification requests

Your backend starts the flow and polls for a decision after holder consent

Auth: Partner API key (verify:requests) server-side only

Start: POST /api/v1/verification-requests → redirect holder to consent_url

Verify: GET /api/v1/decisions/{id}/status

Read more →
Credential / registry verify

Gate on an existing credential JWT, wallet policy check, or registry record

Auth: API key when required; public for credential_jwt mode

Start: POST /api/credentials/verify

Verify: GET /api/proof/{proof_id} or signature on response

Read more →
Abraxas Connect

EVM wallet binding + consent-gated authorization loop

Auth: Partner API key server-side; browser session on Connect UI

Start: POST /api/v1/authorize → hosted_connect_url

Verify: GET /api/v1/authorize/{id}/status

Read more →

Partner Flow entry URL

Redirect the holder to /partner/verify on the canonical host. All query parameters are required unless noted.

ParameterRequiredDescription
partner_idYesRelying party identifier (must exist in partners table)
policy_idYesActive partner_policies.id to evaluate (or use permission + permission_version instead)
return_urlYesHTTPS callback on your origin; must be allowlisted in partners.allowed_return_urls
permissionNoAlternative to policy_id — resolved to a policy for the relying party
permission_versionNoOptional permission version pin
https://abraxasworld.xyz/partner/verify?partner_id=your-partner-id&policy_id=your-policy-v1&return_url=https%3A%2F%2Fyour-app.example.com%2Fauth%2Fabraxas%2Fcallback

Your return_url must be explicitly allowlisted in partners.allowed_return_urls. Unconfigured partners fail closed.

Lifecycle: evaluate → Passport → complete / refresh

1
Redirect to Partner Flow entry

Send the holder to https://abraxasworld.xyz/partner/verify with partner_id, policy_id, and return_url query parameters.

2
Holder authenticates

zkLogin or wallet sign-in sets an httpOnly abraxas_browser_session cookie on the Abraxas origin. Your site never sees this cookie.

3
POST /api/v1/partner-flow/evaluate

Abraxas UI calls evaluate with the browser session. next=enter (returning user), passport (ID required), pending_review, denied, or authenticate.

4
Passport + consent (first visit)

When next=passport, holder completes ID/biometric capture and consent. After admin approval, POST /api/v1/partner-flow/complete issues the session receipt.

5
Callback redirect

Holder returns to return_url with frozen query parameters (no PII). Your server validates the receipt before granting access.

6
Refresh (optional)

When the session receipt TTL expires but the credential remains valid, POST /api/v1/partner-flow/refresh re-issues a receipt (browser session required).

  • next=authenticate — holder must sign in
  • next=passport — ID + biometric required
  • next=enter — approved; redirect with receipt
  • next=denied — policy denial
  • next=pending_review — manual review queue

Callback query parameters (frozen — no PII)

Callback query parameters contain no PII — no legal name, DOB, document numbers, images, or wallet address. Verify eligibility via the signed receipt, not the URL alone.

  • status
  • decision_id
  • receipt_id
  • receipt_expires_at
  • credential_id
  • policy_id
  • partner_id

Receipt verification (server-side)

Fetch GET /api/receipts/{receipt_id}/public from your backend. No API key required. Never trust callback URL parameters alone.

  • signature_valid === true — Ed25519 signature over canonical payload_hash
  • decision_result === "approved" — Fail closed on denied or manual_review
  • status === "active" — Reject expired, revoked, or unknown receipt state
  • expires_at present, valid, and not passed — Session receipt TTL; re-verify at settlement time
  • production_usable === true — Required for production gates; sandbox policies need explicit allowSandbox opt-in in your validator
  • partner_id matches your integration — Prevents cross-partner receipt replay
  • policy_id matches your gate — Ensures the evaluated policy is the one you requested
// Server-side only — after holder lands on your callback URL
import { validatePartnerFlowPublicReceipt } from "@/lib/partner/verifyPartnerFlowReceipt";

const receiptId = searchParams.get("receipt_id");
const res = await fetch(
  `https://abraxasworld.xyz/api/receipts/${receiptId}/public`
);
const receipt = await res.json();

const result = validatePartnerFlowPublicReceipt(receipt, {
  partnerId: "your-partner-id",
  policyId: "your-policy-v1",
  // allowSandbox: true, // only for explicit sandbox/pilot policy testing
});

if (!result.ok) {
  throw new Error(result.errors.join("; "));
}

// Grant gated action — receipt cryptographically verified

Browser session vs server API key

Browser session only (httpOnly cookie on Abraxas origin):

  • POST /api/v1/partner-flow/evaluate
  • POST /api/v1/partner-flow/complete
  • POST /api/v1/partner-flow/refresh
  • /partner/verify UI
  • /passport consent and capture

Server API key (never in browser):

  • POST /api/v1/verify/authorize
  • GET /api/v1/verify/decisions/{id}
  • POST /api/v1/verification-requests
  • GET /api/v1/receipts/{id} (authenticated partner view)
  • POST /api/credentials/verify

Public (no auth):

  • GET /api/receipts/{receipt_id}/public
  • GET /api/credentials/public-key

Webhook sandbox test delivery

Queue a single partner.webhook.test event from the partner portal with an abx_test_ key. Queued does not mean delivered — confirm in your handler and delivery history.

Sandbox test events (partner.webhook.test with test: true) are for signature and handler verification only. They are not Partner Flow lifecycle notifications such as partner.receipt.issued.

  • Sandbox test event type: partner.webhook.test (test: true only)
  • Lifecycle event types: partner.receipt.issued, partner.receipt.revoked, partner.access.revoked, partner.credential.revoked
  • Status API: /api/partner/webhooks/status
  • Delivery history: /api/v1/partner/webhooks/deliveries
  • Test enqueue (sandbox key + webhooks:read, user-initiated only): /api/partner/webhooks/test-delivery
  • A successful enqueue returns queued: true. Delivery is asynchronous; inspect delivery history for delivered, retrying, or failed outcomes.
  • Webhook endpoint URL and signing secret are configured by Abraxas ops — not self-serve.

External design partner sandbox

Two independent tracks: Partner Flow (browser redirect + public receipt verification) and Webhooks (optional, requires webhooks:read). Complete each track on its own — they do not share credentials or proof.

Sandbox receipts with production_usable: false cannot authorize Production access. Reserve currently_valid === true for Production gates only.

Track A — Partner Flow

  • Operator provisioning: Abraxas ops supplies partner_id, policy_id, and an allowlisted return_url. You cannot self-build a complete entry URL without all three.
  • Partner Flow entry URL: Redirect holders to /partner/verify with operator-supplied policy_id and return_url. Use the template below — do not guess missing values.
  • Callback handler: Your server receives frozen callback query parameters (no PII) and fetches GET /api/receipts/{receipt_id}/public before granting access.
  • Sandbox receipt validated: Confirm signature_valid, matching partner_id/policy_id, and approved decision. production_usable: false is expected — sandbox receipts never authorize Production access.

Abraxas operations supplies policy_id and return_url. Replace the placeholders below before redirecting holders.

https://abraxasworld.xyz/partner/verify?partner_id=your-partner-id&policy_id=%3Cpolicy_id%3E&return_url=%3Chttps%3A%2F%2Fyour-app.example.com%2Fauth%2Fabraxas%2Fcallback%3E

Sandbox receipt checks

  • signature_valid === true — Ed25519 signature over canonical payload_hash — required even in sandbox
  • decision_result === "approved" — Fail closed on denied or manual_review outcomes
  • partner_id matches your integration — Prevents cross-partner receipt replay
  • policy_id matches your gate — Ensures the evaluated policy is the one Abraxas ops provisioned
  • production_usable may be false — Expected for sandbox policies — do not use sandbox receipts to gate Production access
  • currently_valid may be false — Sandbox receipts often invalidate with production_not_usable:false — this is expected, not a failure

Track B — Webhooks (optional)

partner.webhook.test events are webhook transport tests only. They are never validated via GET /api/receipts/{receipt_id}/public.

  • webhooks:read scope: Default promote keys include verify:credential and verify:registry only. Request a separate key with webhooks:read from Abraxas ops for this track.
  • Endpoint registered: Abraxas ops registers your HTTPS callback and enables delivery after you confirm signature handling.
  • Test event queued: User-initiated POST enqueues a single partner.webhook.test event. Queued does not mean delivered.
  • HTTP delivered: Delivery history shows status delivered — your endpoint returned a successful HTTP response. This is transport only, not signature verification.
  • Signature verified by your receiver: Manually confirm your handler validated the Abraxas webhook signature. Abraxas cannot infer this from delivery records.

Default promote keys include verify:credential and verify:registry only. Request webhooks:read via Abraxas ops for webhook testing.

Approved design partners: your Abraxas operator shares the full 14-day external pilot playbook during secure sandbox handoff. Use this section plus /design-partner while you wait. Production activation is a separate later step.

Errors and status behavior

ConditionHTTPAction
No browser session on evaluate/complete/refresh401Holder must sign in on abraxasworld.xyz first
return_url not in partners.allowed_return_urls400Ask Abraxas ops to allowlist your exact callback URL
Missing partner_id or return_url400Fix redirect URL construction
Policy does not belong to partner400Align policy_id with partner_id
next=denied200Show denial UX; do not grant access
next=pending_review200Manual review in progress; poll or ask holder to return later
Receipt not found (public)404Fail closed; check receipt_id from callback
signature_valid === false200Fail closed; do not trust callback params without valid receipt
Audit persistence failed503Retry evaluate; contact Abraxas ops if persistent

Copy-paste redirect

// Server-render or link — never embed API keys in the browser
const verifyUrl = "https://abraxasworld.xyz/partner/verify?partner_id=your-partner-id&policy_id=your-policy-v1&return_url=https%3A%2F%2Fyour-app.example.com%2Fauth%2Fabraxas%2Fcallback";

// <a href={verifyUrl}>Continue with Abraxas</a>
Partner onboarding · honest capability map

One verification. Faster onboarding. Fewer forms.

Abraxas helps users prove eligibility and securely continue into partner experiences without repeatedly exposing sensitive identity information.

Available now

  • Partner FlowAvailable now

    Browser redirect entry, policy evaluation, and privacy-preserving callback parameters.

  • Abraxas PassportAvailable now

    Holder sign-in and optional identity capture when a partner policy requires it.

  • Policy-based eligibility verificationAvailable now

    Partners define required claims; Abraxas returns approved, denied, or manual_review.

  • Signed public receiptsAvailable now

    Server-side GET /api/receipts/{receipt_id}/public with signature and trust fields.

  • Privacy-preserving partner callbacksAvailable now

    Frozen callback query parameters contain no PII — partners verify receipts, not URLs alone.

  • Sandbox design-partner integrationAvailable now

    Manual review, operator-provisioned sandbox policies, callback allowlists, and conformance tooling.

In development

  • Consented passwordless partner-account creationIn development

    Create or recover a partner-local account from an Abraxas verification — not deployed yet.

  • Pairwise partner identityIn development

    Per-partner subject identifiers so partners cannot correlate users across services.

  • Optional email sharingIn development

    Separate consent scope for contact information — never bundled with eligibility verification.

  • Separate newsletter / marketing consentIn development

    Marketing enrollment is optional and independently consented — never preselected.

  • Returning “Continue with Abraxas” loginIn development

    Faster return visits using verified Passport context — partner sessions remain partner-owned.

  • Partner-owned sessions and benefitsIn development

    Partners issue their own sessions, preferences, purchases, rewards, and communications.

In development: With explicit user consent, partners will be able to create or recover a local account from an Abraxas verification, request selected contact information, and unlock partner-specific benefits without requiring another password.

How it works

  1. User selects Continue with Abraxas PassportThe partner starts Partner Flow with an allowlisted return_url — available today.
  2. User creates or opens their PassportzkLogin sign-in and optional identity steps when the policy requires them.
  3. Abraxas evaluates the partner’s eligibility policyPolicy engine returns approved, denied, or manual_review against required claims.
  4. User reviews and approves the requested information and actionsToday: Partner Flow consent for verification. Future: separate scopes for account, email, and marketing.
  5. Partner validates the signed result server-sideFetch and validate GET /api/receipts/{receipt_id}/public before granting access.
  6. Partner creates or finds its local account and issues its own sessionPlanned: consented passwordless account bootstrap from verification — partners own sessions today.
  7. Optional perks or communications are enabled only from independent consent choicesPlanned: email and newsletter scopes are separate from eligibility verification.

Privacy and ownership

  • Partners receive only the claims and information the user explicitly authorizes.
  • Abraxas does not send ID photos or date of birth to partners.
  • Eligibility verification is separate from marketing consent.
  • Newsletter enrollment must be optional and separately consented.
  • Each partner owns its local accounts, sessions, preferences, purchases, rewards, and communications.
  • Abraxas must not silently enroll users in third-party services.
  • Future partner identity must be pairwise so partners cannot correlate users across services.
Illustrative consent layout (not live)

Illustrative consent layout only — not a live enrollment form. Newsletter is never preselected.

Technical planning (not deployed): see docs/PARTNER_PASSWORDLESS_ONBOARDING_PLAN.md in the repository. Good Trouble Canna sandbox eligibility reference: /good-trouble.

Operator provisioning

Partner rows, policies, callback allowlists, and sandbox credentials are provisioned by Abraxas operators after manual review. Approved partners then use the Partner Portal to validate their assigned integration. There is no self-serve Production provisioning or automatic API-key issuance.