---
title: "Create a funding session"
method: POST
path: "/api/v2/wallet/fund"
tags: ["Wallet funding"]
---

# Create a funding session

`POST /api/v2/wallet/fund`

Returns an Apple Pay / Google Pay payment link for the amount you specify. Show it in your UI; when the user completes the payment the funds land in their wallet. The link is single-use and expires after 30 minutes. Requires a phone verification fresh within 60 days — see `POST /api/v2/wallet/phone/start`.

## Request body

- object
  - `user_id` string, required — The connected user's id.
  - `amount_cents` integer, required — Amount to fund, in USD cents.
  - `payment_method` 'apple_pay' | 'google_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).
  - `link_type` 'hosted' | 'embedded' — 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.

## Response `201`

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

- FundingSession
  - `object` 'funding_session'
  - `id` string
  - `user_id` string
  - `status` 'pending' | 'processing' | 'completed' | 'failed' | 'expired'
  - `amount_cents` integer
  - `currency` string
  - `payment_method` '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` 'region_not_supported' | 'provider_error' | 'null', nullable
  - `completed_at` string, date-time, nullable
  - `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.
  - `link_type` 'hosted' | 'embedded' — Which kind of checkout_url this session carries. Returned only on the create response; the poll endpoint does not include it.
  - `fee_cents` integer, nullable — 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` 'web' — 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.

## Other responses

- `400` — `invalid_request` — missing or malformed fields.
- `401` — `unauthorized` — the platform access token is missing or expired. Exchange your client credentials for a fresh one.
- `404` — `connection_not_found` — no connection exists for that user under your client.
- `409` — `user_conflict` — the email on file in your organization belongs to a different account. Contact support.
- `422` — `amount_out_of_range` (with `min_amount_cents` / `max_amount_cents`), `phone_verification_required`, `email_required`, or `region_not_supported`.
- `502` — `funding_provider_error` — try again.
- `503` — `funding_unavailable` — funding is temporarily unavailable.

---

[API](https://skmtc.dev/agentcard/apis/agentcard-api.md) · [All operations](https://skmtc.dev/agentcard/apis/agentcard-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/agentcard/agentcard-api/revisions/638d12c8303f/schema)
