Consumer Delegation

Agentic transaction governance: your customers authorize AI agents to transact on their behalf, and every transaction is governed by the delegation they granted. This page is the integration contract — the flows, configuration shapes, and refusal codes. It assumes the Quickstart. For governing your own trading agents (strategies and PM mandates), see Agentic Trading.

The integration loop

  1. Register the subject. Your CIAM asserts the customer; Eniyan mints a pairwise pseudonymous subject. No PII crosses the wire — you keep the mapping.
  2. Run the consent ceremony. Your app submits the session signals you attest; Eniyan scores them into a Consent Assurance Level (CAL). Signals of duress or coercion cap the score outright.
  3. Activate the delegation. The grant becomes a durable record: tier, scopes, per-transaction cap, windowed budget, counterparty allow-list, expiry — plus the vertical constraints below. One live delegation per customer–agent pair.
  4. Mint. The agent presents its credential, the delegation reference, and RFC 9396 authorization_details naming the exact transaction — and receives a 5-minute token (consumer as subject, agent as actor per RFC 8693).
  5. Verify and report. Introspect via RFC 7662 — the delegation is re-evaluated live at that moment. Report executed spend to the budget ledger.
  6. Step up — or revoke. When a step-up rule matches, the mint refuses with the artifacts your app needs to resolve it (below). Revocation flips the very next introspection to inactive.

Vertical packs

Scopes are organized into enableable packs on your configuration (enabled_verticals on PUT /v1/consumer/config): retail and banking are included; capital markets and healthcare each additionally require their add-on (/v1/billing/add-ons/capital-markets / /v1/billing/add-ons/healthcare) and fail closed if it lapses. Core read scopes are always available.

  • An omitted enabled_verticals preserves your current selection; a config with no selection ever made means retail + banking.
  • Disabling a pack is a live kill switch: new grants refuse, and existing delegations carrying its scopes go dark on the very next mint or introspection (vertical_disabled). Re-enabling resumes them — no reinstatement ceremony. Disabling only ever narrows.
  • GET /v1/consumer/verticals is the machine-readable catalogue: every pack with its scope family, transaction types, enablement state, and suggested step-up rules.

Scope catalogue

ScopeTierWhat the customer seesPack
consumer:account:readread_onlySee your account detailscore
consumer:activity:readread_onlySee your activity historycore
consumer:profile:readread_onlySee your profile informationcore
consumer:orders:proposeproposePrepare orders for your approvalretail
consumer:orders:placeexecute_cappedPlace orders on your behalfretail
consumer:returns:initiateproposeStart returns for your approvalretail
consumer:subscriptions:manageexecute_cappedManage your subscriptionsretail
consumer:payments:initiateexecute_cappedStart payments on your behalfbanking
consumer:counterparties:manageexecute_fullManage who you can paybanking
consumer:cards:controlexecute_fullControl your card settingsbanking
consumer:portfolio:readread_onlySee your investments and balancescapital_markets
consumer:trades:proposeproposePrepare trades for your approvalcapital_markets
consumer:trades:placeexecute_cappedPlace trades on your behalf, within your limitscapital_markets
consumer:trades:scheduleexecute_cappedRun your scheduled, pre-authorized tradescapital_markets
consumer:prescriptions:readread_onlySee your prescriptions and refill statushealthcare
consumer:prescriptions:proposeproposePrepare refill orders for your approvalhealthcare
consumer:prescriptions:renewal_requestproposeAsk your prescriber to renew a prescriptionhealthcare
consumer:prescriptions:fillexecute_cappedOrder and pay for refills of prescriptions you designatehealthcare
consumer:prescriptions:fill_controlledexecute_cappedInclude the controlled-substance refills you designatehealthcare
consumer:prescriptions:scheduleexecute_cappedRun your scheduled, pre-authorized refillshealthcare

Two deliberate absences: there is no uncapped trading scope (capped execution is the product), and the only Schedule II prescription verb is renewal_request at propose tier — an agent can ask you to route a renewal to the prescriber, never execute one.

Step-up policy configuration

Your step-up policy is a versioned list of rules. Each rule matches on a scope or a delegation tier, optionally floored by an amount, and demands one or more methods:

  • platform_approval / platform_approval_mfa — your in-app approval loop; the MFA variant requires an MFA-grade assertion with the decision.
  • eniyan_mfa — an Eniyan-hosted passkey or TOTP challenge showing the exact transaction. Requires the customer to have verified identity and enrolled an authenticator.
  • verify_document / verify_document_liveness / verify_document_liveness_id — a Stripe Identity check at rising assurance (document; + selfie; + ID number). Consumer consent is captured before any biometric step.

Verification freshness is per rule: a max-age window makes one check durable across transactions; a zero window demands a fresh check bound to each transaction's exact terms. When several rules match one mint, their requirements combine — rules are floors, never ceilings. Two additions with the vertical packs:

  • Pack suggestions are advisory. The step-up GET returns a suggested block (source pack_default) for your enabled packs — rules you can adopt verbatim with a PUT. They are never enforced until you adopt them. Enable capital markets or healthcare alongside a policy review.
  • Verticals can inject floors. Healthcare fills paid by Medicare Part D or Medicaid require a per-fill platform approval by default (org-overridable via the delegation's payer configuration) — injected requirements combine with your policy exactly like matching rules. Scheduled transactions never bypass step-up: pre-authorization is consent, not an exemption.

The full reference for this surface is delivered to customers under NDA.

Windows & schedules

Delegations can constrain when an agent may transact, and pre-authorize recurring transactions. Both live in the vertical constraint subtree the customer consents to at the ceremony (constraints.trading / constraints.healthcare), always in one declared IANA timezone:

  • Windows (days + start/end times): a discretionary mint outside the window refuses with the next-open time. Evaluation happens in the declared timezone, so a "9:30–4:00" intent survives DST.
  • Schedules (daily / weekly / monthly / every-N-days with an anchor date): each entry names the exact instrument-or-prescription, amount, and cadence. Schedule ids are server-assigned at activation — read them back from the delegation hub; they never appear on consumer-facing surfaces.
  • Once per occurrence: a scheduled mint must match its schedule exactly and consumes that occurrence — replays refuse, and the notional holds against the budget in the same write. An occurrence is due for its whole calendar day, with optional grace past midnight.

Web execution

With the org opt-in on (PUT /v1/consumer/config web_execution_enabled, or Settings → Consumer Delegation → Web execution), the same delegations execute at ordinary web checkouts through the eniyan-web browser gate — identical caps, budgets, counterparty allow-lists, step-up, and ledger on either surface:

  • Web counterparties: allow-list entries may be the merchant’s web domain — shop.example (exact) or *.shop.example (apex + every subdomain, dot-boundary). The gate mints with the page host it is actually on as merchantRef — never a model-asserted value — and the toggle activates the same domain-aware matching for API mints. Opaque refs keep exact matching; with the toggle off, domain-shaped entries are inert (fail closed).
  • Step-up at the checkout: the mint’s 403 carries the approval reference (and the challenge link under Eniyan-hosted MFA); the agent relays it to the consumer through your platform and retries with approval_id. The consumer approves the exact store and amount; any drift burns the approval.
  • Fill-less by design: the authorization gates the checkout submit — merchant-saved cards, wallet buttons, and payment methods on file ride it. Eniyan touches no payment instrument of any kind.
  • Honest ledger: report execution to POST /v1/consumer/delegations/{ref}/usage with the mint’s reserve key as platform_txn_ref — the reserved hold flips to executed at the reported amount instead of double-counting (the response says reserved_flip). This flip benefits API integrations identically.

Healthcare pack

Agents fill and pay for prescriptions the customer designates — the allow-list is mandatory for fill authority, per prescription, always. Regulatory posture, encoded as contract:

  • Eniyan never holds patient data. Prescription and pharmacy refs must be opaque single-token platform identifiers — free text and drug-code shapes (NDC) are refused at the schema layer, and every Eniyan-rendered surface truncates refs to their last 4 characters. Your platform keeps the mapping and the patient record. Reflect Eniyan as a service provider/processor in your privacy notices.
  • Schedule II is never fillable by an agent (21 CFR 1306.12) — unconditional, regardless of scopes or consent. Controlled fills at schedules III–V require the separate controlled-fill scope AND the delegation's controlled consent, optionally capped by class.
  • Payer rules: Medicare Part D and Medicaid default to per-fill human confirmation (your org can override the payer list per delegation). Early-refill spacing is enforced per designated prescription.
  • Consumer refill requests are outside EPCS (21 CFR 1311) — prescription issuance stays prescriber-side. Your platform remains the covered entity/pharmacy of record: dispensing decisions, state pharmacy law, FSA/HSA eligibility handling, and coupon rules stay with you. Eniyan authorizes transactions, never dispensing. This documentation is not legal advice — engage your own counsel.

Mint a signed, Eniyan-hosted view link per delegation and deliver it to your customer — they see exactly what they authorized (labelled scopes, caps, remaining budget, trading limits, designated prescriptions as truncated refs, schedules in plain language) and the step-up rules protecting them, with no account. Hosted links are double-gated: your org must hold the view-links add-on and the agent must have passed Eniyan's transparency review. Links are revocable, expire on a TTL you control, and the page goes dark if the agent's review approval is withdrawn. The org-API delegation hub is not gated — render it in your own app at no extra cost.

Mint refusal codes

A refused consumer mint returns a standard OAuth error body; branch on the code:

CodeWhen
amount_exceeds_capThe transaction amount is over the delegation's per-transaction cap.
counterparty_not_allowedThe counterparty is not on the delegation's allow-list.
budget_exceededThe windowed budget has no room for this amount.
rar_scope_mismatchThe authorization_details type is not permitted by the granted scopes (e.g. a trade order on a retail-only grant, or a discretionary trade on a schedule-only grant).
approval_requiredA step-up rule demands the customer's approval; retry with approval_id after they decide.
verification_requiredA step-up rule demands an identity check; the response carries a requirement reference.
enrollment_requiredAn Eniyan-hosted MFA rule matched but the customer has no enrolled authenticator.
step_up_requiredMultiple step-up requirements are unmet; the response carries each reference.
delegation_not_liveThe delegation is revoked, expired, suspended, its consent no longer supports the tier, or its vertical pack was disabled (vertical_disabled — the pack kill switch).

Trading (capital-markets pack)

CodeWhen
instrument_required / invalid_side / invalid_order_typeThe trade entry is malformed: missing instrument, or a side/order type outside the vocabulary.
limit_price_requiredA limit or stop-limit order arrived without a positive limit_price_minor.
instrument_not_allowedThe instrument is not on the delegation's allow-list.
side_not_allowed / order_type_not_allowedThe side or order type is outside what the customer consented to.
trade_count_exceededThe delegation's max_trades_per_day is already consumed.
outside_trading_windowA discretionary trade outside the consented trading hours; the detail carries the next window-open time.
schedule_unknown / schedule_not_dueThe schedule_id doesn't exist on this delegation, or has no due occurrence now.
schedule_amount_mismatch / schedule_instrument_mismatch / schedule_side_mismatchA scheduled trade must present the exact pre-authorized amount, instrument, and side.
schedule_occurrence_consumedThis occurrence was already used — scheduled trades are once-per-occurrence.
schedule_scope_requiredScheduled trades require the scheduled-trading scope in the grant.

Prescriptions (healthcare pack)

CodeWhen
prescription_required / invalid_prescription_refThe fill entry is missing a prescriptionRef, or the ref failed the opaque-identifier guard (free text and drug-code shapes are refused).
prescription_not_designatedThe prescription is not on the delegation's designated list — designation is per-prescription, always.
schedule_ii_refill_prohibitedUNCONDITIONAL: Schedule II prescriptions cannot be refilled by an agent under any consent combination (21 CFR 1306.12). Route a renewal request to the prescriber instead.
controlled_not_allowedA controlled-substance fill without BOTH the controlled-fill scope and the delegation's controlled consent.
schedule_class_exceeds_maxThe fill's schedule class is more restricted than the delegation permits.
refill_too_earlyThis prescription filled within the delegation's minimum spacing window.
outside_fill_windowA discretionary fill outside the consented fill windows.
invalid_payer_type / invalid_schedule_class / invalid_day_supplyThe entry carries a payer, schedule class, or day supply outside the vocabulary.

General API errors are on Errors & rate limits.

CAL scoring model

CAL weighs evidence across four classes — presence, freedom, session integrity, and comprehension — with hard caps for duress and coercion signals, and each delegation tier demands a minimum score. The at-grant score is immutable; the current score reprices as late signals arrive.

The full reference for this surface is delivered to customers under NDA.