---
title: Agent Pay | API Docs
description: Request payments over iMessage and collect with Apple Pay — funds settle directly to your own Stripe account.
---

Request a payment from a recipient over iMessage. You create a payment request, send its `checkout_url` to the recipient, and they pay with Apple Pay or card. Funds settle **directly to your own Stripe account** — Linq never holds the money.

## How it works

1. **Create** a payment request with an amount and currency. You get back a `checkout_url` and a `status` of `requested`.
2. **Send** the `checkout_url` to the recipient as a `link` message part so it arrives as a tappable card (see *Sending the link* below).
3. The recipient **pays** on the hosted checkout (Apple Pay App Clip on a supported iPhone, web checkout everywhere else).
4. You receive a **`payment.succeeded`** webhook and the request’s `status` becomes `succeeded`. Requests you don’t collect eventually `expire`.

## Connected accounts (Stripe Standard, direct charges)

Agent Pay runs on **Stripe Connect Standard accounts** using **direct charges**: the charge is created on *your* connected account and **you are the merchant of record**. That means the money, the payout schedule, the customer relationship, and the compliance surface are all yours — Linq orchestrates the request and the checkout but is never in the funds flow.

**Refunds, disputes, and chargebacks are handled by you, in your own Stripe Dashboard.** Because charges settle directly to your account, Linq has no custody of the funds and cannot issue refunds or contest disputes on your behalf — and there is no refund/dispute endpoint in this API by design. Use the Stripe Dashboard (or the Stripe API on your own account) for the money lifecycle after a payment succeeds.

## Getting set up

Open **Agent Pay** in your Linq dashboard (`https://zero.linqapp.com/organization/payments`), click **Connect Stripe**, and complete Stripe’s onboarding (business details + a bank account). When your account reaches `charges_enabled`, request creation unlocks; until you connect Stripe, `POST /v3/payment_requests` returns `403`. You can keep collecting even while Stripe finishes background verification.

## Sending the link

Deliver the `checkout_url` as a **`link` message part** via `POST /v3/chats/{chatId}/messages` — it renders as a rich card with your branding (title, amount, image) instead of a bare URL, which converts far better. A `link` part must be the only part in the message. See [Rich Link Previews](/guides/messaging/sending-messages/index.md).

On a supported iPhone the link opens an **Apple Pay App Clip** — a native, no-install checkout sheet. Everywhere else (Android, desktop, iPhones without the App Clip yet) the same URL opens the web checkout, so the link always works. The App Clip experience for your payment links is registered automatically by Linq and refreshed whenever you update your Agent Pay branding; a newly registered experience can take up to \~24 hours to activate on Apple’s side, during which links open the web checkout.

## Webhooks

Subscribe to payment lifecycle events to reconcile server-side rather than polling: `payment.succeeded`, `payment.canceled`, and `payment.expired`. Each event carries the payment request id, amount, currency, and your `metadata`. See [Webhooks](/guides/webhooks/index.md).

## The flow

Collecting a payment is three steps and one webhook:

1. **Create a payment request** with an amount and currency. You get back a `checkout_url` and a `status` of `requested`.
2. **Send the `checkout_url`** to the recipient as a `link` message part, so it arrives as a tappable card rather than a bare URL — see [Sending payment links](/guides/payments/sending-payment-links/index.md).
3. The recipient **pays** on the hosted checkout — an Apple Pay App Clip on a supported iPhone, web checkout everywhere else.
4. You receive a **`payment.succeeded`** [webhook](/guides/payments/webhooks/index.md) and the request’s `status` becomes `succeeded`.

## Create a payment request

- [cURL](#tab-panel-136)

Terminal window

```
curl -X POST https://api.linqapp.com/api/partner/v3/payment_requests \
  -H "Authorization: Bearer $LINQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "amount": 497,
      "currency": "usd",
      "description": "Coffee with Ava",
      "metadata": {
        "order_id": "order_8675309"
      }
    }'
```

`amount` is in the currency’s minor units (cents for `usd`), with a `50`-cent minimum. The response includes the `checkout_url` you send to the recipient and an `expires_at` after which the request can no longer be paid.

Store your own identifiers in `metadata` (up to 49 keys) — e.g. an order id or the chat id — and they’re echoed back on retrieval and on every `payment.*` webhook, so you can reconcile against your records. Keys beginning with `linq_` are reserved.

## Before you can charge

Payments settle **directly to your own Stripe account**, so you connect Stripe once before your first request. New accounts also need to clear Stripe’s verification. See [Connected accounts](/guides/payments/connected-accounts/index.md) for the one-time setup and what “merchant of record” means for you (including refunds and disputes).

## Reference

- `POST /v3/payment_requests` — [Create a payment request](/api/resources/payment_requests/methods/create/index.md)
- `GET /v3/payment_requests/{paymentRequestId}` — [Retrieve a payment request](/api/resources/payment_requests/methods/retrieve/index.md)
- `GET /v3/payment_requests` — [List payment requests](/api/resources/payment_requests/methods/list/index.md)
- `POST /v3/payment_requests/{paymentRequestId}/cancel` — [Cancel a payment request](/api/resources/payment_requests/methods/cancel/index.md)
