---
title: "Start here"
description: "What thru is, the five facts every integration needs, and a table for choosing between checkout sessions, direct payments, payment links, invoices and agent payments"
source: https://docs.thru.la/start-here.md
html: https://docs.thru.la/start-here
index: https://docs.thru.la/llms.txt
---
# Start here

thru lets your business accept stablecoin payments. For each payment it gives the payer a one-time address, watches the chain, sends your server a signed webhook when the money has arrived, and then forwards the funds to your own settlement wallet.

## Five facts every integration needs

| | |
|---|---|
| Base URL | `https://api.thru.la/v1` |
| Authentication | Send `x-api-key: thru_sk_…` on every server-to-server call. There is no `Authorization: Bearer` scheme. Keys are created in the console. |
| Amounts | Amounts are decimal **strings** in **token units**, so `"25"` means 25 USDC. `currency` is only a display label, and thru does no currency conversion. The one amount labelled USD is a custom-amount product's `amount` (at most 2 decimal places); it becomes the payment's `expectedAmount` unchanged, in the token of whichever rail the buyer picks, so give such a product stablecoin rails only. |
| Network | One key works on both `mainnet` and `testnet`. Send `network` on every create, and check `network` before you fulfil. |
| Unknown fields | A request body field the API does not define is rejected with `400`. Put your own data in `metadata`. |

## Choose your integration

| You want to… | Use | Who shows the payment page | How you know who paid |
|---|---|---|---|
| Sell a fixed-price item or pack on a hosted page | A **checkout session** for a fixed-price product (`checkout-sessions`) | thru, at `https://thru.la/c/<session id>` | Your `reference`, on the session and in every `checkout.session.*` event |
| Sell credit or a top-up, where the amount differs per purchase, on a hosted page | A **checkout session with `amount`** for a custom-amount product (`checkout-sessions`, `credit-topups`) | thru, at `https://thru.la/c/<session id>` | Your `reference`, on the session and as `checkoutSession` in every `payment.*` event |
| Charge an amount you decide, with your own payment screen | A **direct payment**, `POST /v1/payments` (`payments`) | You, or the React components in `@thru-payment/pay-sdk` | The payment `id` you stored when you created it |
| Share one link anyone can pay, such as a buy button | A **product payment link**, `/pay/<slug>` (`products`) | thru | Nobody. The link is anonymous. |
| Bill a named customer with line items | An **invoice** (`invoices`) | thru, at `https://thru.la/i/<publicId>` | The invoice's `paymentId`. There is no invoice webhook. |
| Charge AI agents per API request (HTTP 402) | **Agent payments** (`facilitator-x402`) | Nobody; it is machine to machine | Not enabled on api.thru.la yet |

Rules of thumb:

- **If the amount varies, use a custom-amount product.** A product is either `fixed` (its price is charged) or `custom_amount` (your server sends `amount` on each checkout session, within the product's `minAmount`/`maxAmount`, and the buyer cannot change it). A direct payment is for when you also want to show the payment screen yourself.
- **Grant from one webhook family.** Fixed-price sessions grant on `checkout.session.completed`; custom-amount sessions credit `receivedAmount` on `payment.*`, whose events carry `checkoutSession` with your `reference`.
- **A checkout session can point only at a product today.** The API accepts a session for an invoice, but the hosted page cannot display one yet.
- **Every integration ends the same way.** A webhook tells you money moved, and an authenticated read of the object confirms it before you fulfil.
- **Check `supported-chains` before you offer a chain.** The API accepts payments on chains and tokens that are not being watched, and such payments never confirm.

## Reading path

1. `quickstart`: a real testnet payment, end to end, with curl.
2. `auth`: keys, workspaces, and testnet versus mainnet.
3. The guide for your integration: `checkout-sessions`, `credit-topups`, `products` or `invoices`.
4. `webhooks`: signature verification, deduplication and retries.
5. `supported-chains`: which chain and token pairs confirm today.
6. `going-live`: the checklist.

Reference topics: `payments`, `api-conventions`, `refunds-and-settlement`, `sdks`.

## The secrets you will handle

| Secret | Format | Where it comes from | What it is for |
|---|---|---|---|
| API key | `thru_sk_` + 48 hex characters | Console → Developers → API keys. It is shown once. | The `x-api-key` header on server calls |
| Webhook signing secret | 64 hex characters, one per endpoint | The `secret` field returned by `POST /v1/webhooks` and `GET /v1/webhooks` | Checking the `x-thru-signature` header |
| Checkout signing secret | 64 hex characters, one per workspace | `GET /v1/checkout/secret`, or Console → Developers → Checkout | Checking `thru_sig` when a shopper returns from a checkout session |

Both signing secrets are HMAC-SHA256 keys, and the key is the **UTF-8 bytes of the secret string**. Do not hex-decode them. Keep all three secrets on your server; none may reach a browser or a mobile app.

## Reading these docs as a coding agent

`GET /v1/docs` returns the topic index, and `GET /v1/docs/:topic` returns one topic as markdown inside JSON. Neither needs a key. Fetch only the topics your task touches.

---

Related: [quickstart](https://docs.thru.la/quickstart.md) · [auth](https://docs.thru.la/auth.md) · [checkout-sessions](https://docs.thru.la/checkout-sessions.md) · [credit-topups](https://docs.thru.la/credit-topups.md) · [supported-chains](https://docs.thru.la/supported-chains.md)
