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 →
First integration tasks
- Apply at /integrations#apply — describe your age-gated checkout or eligibility gate.
- Read /docs/partner-flow — entry URL params, lifecycle, and receipt checks.
- Implement callback handler — fetch public receipt server-side; never trust URL params alone.
- 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.
Choose your integration path
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)
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 →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 →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.
| Parameter | Required | Description |
|---|---|---|
| partner_id | Yes | Relying party identifier (must exist in partners table) |
| policy_id | Yes | Active partner_policies.id to evaluate (or use permission + permission_version instead) |
| return_url | Yes | HTTPS callback on your origin; must be allowlisted in partners.allowed_return_urls |
| permission | No | Alternative to policy_id — resolved to a policy for the relying party |
| permission_version | No | Optional 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
Send the holder to https://abraxasworld.xyz/partner/verify with partner_id, policy_id, and return_url query parameters.
zkLogin or wallet sign-in sets an httpOnly abraxas_browser_session cookie on the Abraxas origin. Your site never sees this cookie.
Abraxas UI calls evaluate with the browser session. next=enter (returning user), passport (ID required), pending_review, denied, or authenticate.
When next=passport, holder completes ID/biometric capture and consent. After admin approval, POST /api/v1/partner-flow/complete issues the session receipt.
Holder returns to return_url with frozen query parameters (no PII). Your server validates the receipt before granting access.
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 verifiedBrowser 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
| Condition | HTTP | Action |
|---|---|---|
| No browser session on evaluate/complete/refresh | 401 | Holder must sign in on abraxasworld.xyz first |
| return_url not in partners.allowed_return_urls | 400 | Ask Abraxas ops to allowlist your exact callback URL |
| Missing partner_id or return_url | 400 | Fix redirect URL construction |
| Policy does not belong to partner | 400 | Align policy_id with partner_id |
| next=denied | 200 | Show denial UX; do not grant access |
| next=pending_review | 200 | Manual review in progress; poll or ask holder to return later |
| Receipt not found (public) | 404 | Fail closed; check receipt_id from callback |
| signature_valid === false | 200 | Fail closed; do not trust callback params without valid receipt |
| Audit persistence failed | 503 | Retry 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>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
- User selects Continue with Abraxas Passport — The partner starts Partner Flow with an allowlisted return_url — available today.
- User creates or opens their Passport — zkLogin sign-in and optional identity steps when the policy requires them.
- Abraxas evaluates the partner’s eligibility policy — Policy engine returns approved, denied, or manual_review against required claims.
- User reviews and approves the requested information and actions — Today: Partner Flow consent for verification. Future: separate scopes for account, email, and marketing.
- Partner validates the signed result server-side — Fetch and validate GET /api/receipts/{receipt_id}/public before granting access.
- Partner creates or finds its local account and issues its own session — Planned: consented passwordless account bootstrap from verification — partners own sessions today.
- Optional perks or communications are enabled only from independent consent choices — Planned: 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 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.