Skip to main content
POST
Create a funding session

How it works

Ask for a funding session for an amount; we return a checkout_url. There are two kinds, picked with link_type:
  • hosted (default): an Agentcard-hosted payment page. Render it anywhere — an “Add funds” button, a QR code, a chat message — and the user opens it and pays with Apple Pay, Google Pay, or card. Safe to relay: the underlying payment order is created only when the user opens the page. Creating a hosted session is free; an unopened link costs nothing.
  • embedded: an in-app payment link, minted immediately. Load checkout_url in a WKWebView (iOS) or Android WebView and the user pays without leaving your app.
When the payment completes, the funds land in the user’s wallet. Poll GET /api/v2/wallet/fund/{session_id} to know when — that endpoint is the source of truth for money; treat any client-side signal as advisory.

Requirements

  • The user must be identity-verified. Funding reuses the user’s completed identity verification — there is no separate verification step inside checkout. If the user isn’t verified, create-session returns 422 kyc_required; run identity verification first, then retry. Other verification-related 422s:
    • funding_profile_required — a one-time funding profile is missing (collect it, then retry).
    • kyc_transfer_required — the user’s existing verification needs a one-time carry-over before funding (a single extra step, no re-verification).
    • unsupported — the user’s verification can’t be used for funding (for example, a non-US user).
  • Amount bounds come from the API. If the amount is out of range you get 422 amount_out_of_range with min_amount_cents and max_amount_cents in the response — read those rather than hardcoding limits.
  • Link lifetime. hosted and embedded links both stay openable for the session’s 30-minute window.

Embedded: in-app checkout

Create the session with link_type: "embedded", hand checkout_url to your app, and load it in a WebView:
  • Apple Pay renders inside a WKWebView on iOS 16+ (Apple Pay on the Web is supported in WKWebView, but not in SFSafariViewController — use a WKWebView). On older iOS the user pays with Google Pay or card. No domain verification is required on your side; the checkout runs on our Apple-registered domain and pops the native Apple Pay sheet in-app.
  • Google Pay works in a modern Android WebView; card is always available as a fallback.
  • Completion: the page navigates to /fund/success when the payment completes — observe that navigation to close your WebView — and the status endpoint is the authoritative confirmation.
  • Wallet-only sheet: append &only=apple_pay (or &only=google_pay) to the checkout_url fragment to present just that wallet button with no card form.
  • fee_cents on the create response is null when the fee is already included in the quoted total.

Mint on demand, not per render

Every embedded session creates a real payment order the moment you call the endpoint. Mint one only when the user has actually initiated payment (tapped “Add funds”), render it immediately, and create a fresh session for the next attempt if the link lapses. Don’t mint on page render or in retry loops — the API refuses excess pending sessions for the same user with too_many_pending_sessions.
  • Never relay an embedded link through chat or email; link unfurlers can consume it and leave the user a dead page. Server → WebView, immediately, is the only safe path.
  • The embedded checkout_url appears only on the create response; the status endpoint never re-serves it. If it lapsed, create a new session.
  • Test with sandbox-mode credentials — sandbox clients create TEST orders (never charged), so you can exercise the full WebView flow end to end before switching to live keys.
  • On a physical device, cards must be in the platform wallet; simulators cannot show the Apple Pay sheet.

Authorizations

Authorization
string
header
required

A platform access token. Get one on the Create an access token endpoint by exchanging your client_id + client_secret, then send it as Authorization: Bearer <token>. Tokens live one hour.

Body

application/json
user_id
string
required

The connected user's id.

amount_cents
integer
required

Amount to fund, in USD cents.

payment_method
enum<string>
default:apple_pay

google_pay with link_type "embedded" is accepted when the user's rail returns the web checkout style; on web rails embedded is Apple Pay only (422 payment_method_not_supported).

Available options:
apple_pay,
google_pay

hosted returns an Agentcard-hosted payment page, safe to relay anywhere (chat, email, QR); the underlying payment order is created only when the user opens it, so unopened hosted sessions cost nothing. embedded creates a REAL payment order immediately and returns the raw single-use Apple Pay link for rendering inside your own in-app webview; it lives about 5 minutes, must never be relayed through chat (link unfurlers consume it), and counts toward the user's per-user payment limits even if never paid, so mint it only when the user initiates payment. Embedded sessions support payment_method apple_pay only (google_pay with embedded is rejected). Sandbox-mode credentials create TEST orders (never charged). Embedded responses carry checkout_style (web | web) — branch your rendering on it.

Available options:
hosted,
embedded

Response

The funding session, with the payment link to show the user.

object
string
Allowed value: "funding_session"
id
string
user_id
string
status
enum<string>
Available options:
pending,
processing,
completed,
failed,
expired
amount_cents
integer
currency
string
payment_method
enum<string>
Available options:
apple_pay,
google_pay
checkout_url
string

The payment link to show the user. hosted: an Agentcard-hosted page, present while the link can still be opened. embedded: the raw provider Apple Pay link, present ONLY on the create response; the poll endpoint never re-serves it, so load it in an in-app webview immediately, never relay it, and create a new session if it lapses.

failure_reason
enum<string> | null
Available options:
region_not_supported,
provider_error,
null
completed_at
string<date-time> | null
created_at
string<date-time>
expires_at
string<date-time>

On the create response: hosted links stay openable for 30 minutes; embedded links are single-use and expire about 5 minutes after creation (create a new session instead of retrying a lapsed link). On the poll endpoint, expires_at always reflects the session's 30-minute fundability window, not the embedded link's shorter life.

Which kind of checkout_url this session carries. Returned only on the create response; the poll endpoint does not include it.

Available options:
hosted,
embedded
fee_cents
integer | null

Provider fee included in amount_cents, in USD cents. Returned only on the create response of embedded sessions (the order is priced at create time); absent on hosted sessions and on the poll endpoint. Null on the web checkout style (the fee is inside the quoted total).

checkout_style
enum<string>

Embedded create responses only. How to render checkout_url: 'web' — an Agentcard-hosted checkout page. Load it in a WKWebView (iOS) or Android WebView; on iOS 16+ the Apple Pay button renders in-app. The page navigates to /fund/success on completion.

Available options:
web