---
title: "Buy an offering with your own wallet (preflight, then report the transaction)"
method: POST
path: "/api/wallet/offerings/purchase"
tags: ["wallet", "browser-session"]
---

# Buy an offering with your own wallet (preflight, then report the transaction)

`POST /api/wallet/offerings/purchase`

## Request

- Base URL: `https://www.immersivecommons.com`
- URL: `https://www.immersivecommons.com/api/wallet/offerings/purchase`
- Auth: API key in cookie `__session`

Used by /floor10/wallet/buy/{handle}/{slug}. Clerk-session only, same-site, application/json; an agt_ bearer is refused (agents pay over x402 at /m/{handle}/x/{slug}). `preflight:true` checks everything before the member signs, opens a 30-minute purchase intent and answers the seller's Base address and the EXACT amount (the price plus a few millionths of a USDC that identify this purchase). After the member's own wallet sent it, `{ handle, slug, intent_id, tx_hash }` is VERIFIED ON-CHAIN (a USDC Transfer from the buyer's smart account to the seller of exactly that amount, in a block no older than the intent) before fulfilment; a hash is claimed once, shared with the x402 route. Base only. 404 unless offerings are enabled.

## Request body

- OfferingPurchaseRequest
  - `handle` string, required
  - `slug` string, required
  - `amount` string: pay_what_you_want only.
  - `quantity` integer
  - `input` OfferingBuyInput: By kind. message: { message, from_name?, reply_to? }. booking: { start, name, email, note?, hold_token? }. manual: { note?, contact? }. webhook: any JSON (forwarded as `input`). file: none.
  - `preflight` boolean
  - `intent_id` string: After sending: the intent id preflight returned (pin_...).
  - `tx_hash` string: After sending: the Base transaction hash.

## Response `200`

Preflight answer, or the receipt.

- OfferingPurchaseResponse
  - `ok` boolean
  - `preflight` boolean
  - `pay` object
    - `chain` string
    - `to_address` string
    - `amount_usdc` string
    - `network_mode` string
  - `receipt` OfferingReceipt
    - `receipt_id` string, required: rcp_...
    - `offering_id` string, required
    - `offering_slug` string
    - `offering_title` string
    - `member` string, required: The seller's handle.
    - `buyer_address` string, required
    - `amount` string, required: Decimal USDC.
    - `amount_atomic` string
    - `asset` 'USDC'
    - `network` 'base' | 'solana', required
    - `network_caip2` string
    - `network_mode` 'testnet' | 'mainnet'
    - `tx_hash` string, nullable
    - `via` 'x402' | 'member_wallet'
    - `status` 'fulfilled' | 'fulfilment_failed', required
    - `fulfilled_at` string, date-time, nullable
    - `created_at` string, date-time
    - `result` object
    - `fulfilment_error` string

## Other responses

- `202`: The network has not shown the transaction yet; report it again shortly.
- `400`: Invalid input, amount, network or transaction.
- `401`: Not signed in.
- `403`: Cross-site, agent bearer, members-only, or blocked by the seller.
- `404`: No such offering on sale, or offerings not enabled.
- `409`: That transaction was already used, or is being recorded.
- `410`: Sold out.
- `415`: Content-Type is not application/json.
- `429`: Per-buyer daily limit reached.

---

[API](https://skmtc.dev/immersivecommons/apis/immersive-commons-agent-rest-api.md) · [All operations](https://skmtc.dev/immersivecommons/apis/immersive-commons-agent-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/immersivecommons/apis/immersive-commons-agent-rest-api/revisions/be67c1f67c27?raw)
