> For the complete documentation index, see [llms.txt](https://doc.paysats.exchange/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.paysats.exchange/getting-started/quickstart.md).

# Settlement quickstart

Go from nothing to **IDR landed in a BCA account** in five steps. This guide covers the **bank settlement** primitive. See [Product primitives](/introduction/primitives.md) for agentic DCA and BTC-backed borrowing.

{% hint style="info" %}
All SDK calls happen **server-side**. Never expose `PAYSATS_API_KEY` in a browser bundle.
{% endhint %}

{% stepper %}
{% step %}

## Install the SDK

```bash
npm install @paysats/sdk
```

Requires **Node 18+** (for native `fetch`).
{% endstep %}

{% step %}

## Set your API key

Put your tenant key in an environment variable. Don't commit it.

```bash
export PAYSATS_API_KEY="pk_live_xxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

Need one? See [API keys](/getting-started/api-keys.md).
{% endstep %}

{% step %}

## List payout methods

Always pull the live list. Bank codes and e-wallet availability change.

```ts
import { PaysatsClient } from "@paysats/sdk";

const client = new PaysatsClient({
  apiKey: process.env.PAYSATS_API_KEY!,
});

const methods = await client.listPayoutMethods();
const bca = methods.find((m) => m.bankCode === "014")!;
```

See [Payout methods](/developers/payout-methods.md) for the shape and how banks vs e-wallets differ.
{% endstep %}

{% step %}

## Create an off-ramp order

Pick **either** `satAmount` **or** `idrAmount`. The server computes the other side from the locked quote.

```ts
const order = await client.createOfframpOrder({
  idrAmount: 50_000,
  depositChannel: "lightning",
  idrxBankCode: bca.bankCode,
  idrxBankName: bca.bankName,
  recipientDetails: "1234567890",
  bankAccountName: "Jane Doe",
});

console.log(order.bolt11);      // BOLT11 invoice to show the payer
console.log(order.satAmount);   // Exact sats the payer must send
console.log(order.invoiceExpiresAt);
```

For on-chain rails (`cbbtc` / `btcb`), `order.bolt11` is `null` and `order.deposit` contains the EVM deposit instructions instead.
{% endstep %}

{% step %}

## Pay the invoice and wait for settlement

The payer pays the BOLT11 with any Lightning wallet. Your server blocks until the order reaches a terminal state, or polls it instead.

```ts
const final = await client.waitForOrder(order.orderId, {
  onUpdate: (o) => console.log("state:", o.state),
});

if (final.state === "COMPLETED") {
  console.log("IDR settled", final.idrxRedeemId);
} else {
  console.error("Order failed", final);
}
```

`waitForOrder` polls every 5 s by default with a 30-minute timeout. See [Order lifecycle](/developers/order-lifecycle.md) for the full state list.
{% endstep %}
{% endstepper %}

## The whole thing, end-to-end

```ts
import { PaysatsClient } from "@paysats/sdk";

const client = new PaysatsClient({ apiKey: process.env.PAYSATS_API_KEY! });

const methods = await client.listPayoutMethods();
const bca = methods.find((m) => m.bankCode === "014")!;

const order = await client.createOfframpOrder({
  idrAmount: 50_000,
  depositChannel: "lightning",
  idrxBankCode: bca.bankCode,
  idrxBankName: bca.bankName,
  recipientDetails: "1234567890",
  bankAccountName: "Jane Doe",
});

const final = await client.waitForOrder(order.orderId);
console.log(final.state); // COMPLETED
```

## What to read next

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>SDK reference</strong></td><td>Every method, option, and error type.</td><td><a href="/pages/UccHaU6qy1ilMoJ4l5yz">/pages/UccHaU6qy1ilMoJ4l5yz</a></td></tr><tr><td><strong>Order lifecycle</strong></td><td>All possible order states and how to drive UI from them.</td><td><a href="/pages/7IpIXkcXcUjeoBJ9znBg">/pages/7IpIXkcXcUjeoBJ9znBg</a></td></tr><tr><td><strong>MCP server</strong></td><td>Let an LLM drive the same flow via Model Context Protocol.</td><td><a href="/pages/34Qs1fXJV5fqN5U9vJtA">/pages/34Qs1fXJV5fqN5U9vJtA</a></td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://doc.paysats.exchange/getting-started/quickstart.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
