---
title: "Stellar anchors vs a payout API: how SEP-24, SEP-31, and SEP-38 off-ramp USDC"
seoTitle: "Stellar anchors vs a payout API: SEP-24, SEP-31, SEP-38"
description: "How Stellar anchors off-ramp USDC through SEP-24, SEP-31, and SEP-38 quotes, how a payout API does the same job, and which one fits your product."
date: "2026-10-05"
updated: "2026-10-05"
category: "stablecoins"
author: "BlindPay Team"
faq:
  - q: "What is a Stellar anchor?"
    a: "An anchor is a business that connects the Stellar network to off-chain money: it takes deposits of bank currency and issues or delivers Stellar assets, and it takes Stellar assets back and pays out bank currency. Anchors interoperate through Stellar Ecosystem Proposals, or SEPs, such as SEP-24 for hosted deposits and withdrawals and SEP-31 for cross-border payments."
  - q: "What is the difference between SEP-24 and SEP-31?"
    a: "SEP-24 is a wallet-to-anchor flow for a user's own deposits and withdrawals: the anchor hosts a web page for KYC and details, and the wallet sends the payment. SEP-31 is a business-to-business flow: a sending anchor pays a receiving anchor, which delivers to an account outside Stellar, with KYC through SEP-12 and optional quotes through SEP-38."
  - q: "Are SEP-38 quotes firm?"
    a: "They can be. SEP-38 separates indicative prices, from GET /prices and GET /price, from firm quotes, from POST /quote. A firm quote carries an expires_at, the time by which the anchor must receive the funds, and SEP-31 says the Stellar transaction must be submitted before the quote expires. SEP-38 itself is still marked Draft."
  - q: "Can I off-ramp USDC on Stellar without an anchor?"
    a: "Yes, through a payout API that accepts Stellar. With BlindPay, you create a payout quote with a Stellar network, call authorize to get an unsigned transaction, sign it with your Stellar key, submit it, and create the payout with the signed transaction. BlindPay re-validates the destination and amount, then pays the bank account over a local rail."
  - q: "When should a business use an anchor instead of a payout API?"
    a: "Use anchors when you build a consumer Stellar wallet and want users to pick a local anchor and complete KYC on that anchor's own page, or when you already have bilateral SEP-31 relationships in your corridors. Use a payout API when you pay many recipients across several countries and want one integration, one KYC relationship, and one quote format."
---

Stellar anchors and payout APIs both turn USDC on Stellar into money in a bank account. Anchors do it through open standards: SEP-24 for a user's own withdrawals, SEP-31 for business cross-border payments, and SEP-38 for quotes. A payout API does it behind one REST integration. The choice comes down to who owns the user, the KYC, and the corridors.

Stellar is unusual here. Most networks have no shared standard for off-ramps, so every provider invents its own. Stellar has a whole family of them. That's worth understanding even if you end up using an API, because the SEPs spell out the same steps every off-ramp has to solve.

**Key takeaways**

- An anchor bridges Stellar assets and bank money, and talks to wallets through SEPs.
- SEP-24 is interactive: the anchor hosts the KYC page, the wallet sends the payment with a memo.
- SEP-31 is for businesses: a sending anchor pays a receiving anchor outside Stellar.
- SEP-38 separates indicative prices from firm quotes with an `expires_at`. It's still a Draft.
- Each anchor brings its own auth, KYC rules, and quote server, so corridors multiply integrations.
- A payout API like BlindPay takes signed USDC on Stellar and pays out over local rails from one integration.

## What is a Stellar anchor?

An anchor is a business that connects Stellar to the outside financial system. It accepts bank currency and delivers a Stellar asset, or accepts a Stellar asset and pays bank currency out. The SEP-24 spec describes its goal as "the standard way for anchors and wallets to interact on behalf of users" ([SEP-24](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md)).

Anchors publish what they support in a `stellar.toml` file and authenticate clients with SEP-10 web authentication. On top of that sit the flows. Three matter for off-ramps: SEP-24, SEP-31, and SEP-38.

In payment terms, an anchor is an off-ramp with a public protocol. [Types of crypto off-ramps](/resources/more/types-of-crypto-off-ramps) places it next to exchanges, widgets, and payout APIs.

## How does a SEP-24 withdrawal work?

SEP-24 is the hosted flow. The wallet asks, the anchor collects what it needs on its own page, and the wallet sends the funds.

1. The wallet authenticates with SEP-10. The spec says anchors "must support SEP-10 and/or SEP-45 web authentication."
2. The wallet starts a withdrawal. If the anchor needs KYC or bank details, it returns a URL, and the wallet "should open a popup browser window or embedded webview" to it.
3. The user fills in the anchor's form. The transaction moves to `pending_user_transfer_start`.
4. The wallet pays. "In order to fulfill a withdrawal, a wallet must make a payment to the Stellar address that the anchor provides," using the anchor's `withdraw_memo`.
5. The anchor sees the payment and sends the bank transfer. Status ends at `completed`.

Good for a consumer wallet: the user picks a local anchor, and the anchor owns its compliance screen. The tradeoff is that you don't control that screen, and each anchor's form looks different.

## How does SEP-31 move a cross-border payment?

SEP-31 is the business version. It "defines a protocol for enabling payments between two financial accounts that exist outside the Stellar network" ([SEP-31](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0031.md)). A sending anchor collects from its client and pays a receiving anchor, which delivers to the recipient's bank.

What the receiving anchor requires:

- **SEP-10 auth.** "Sending Anchors must authenticate with Receiving Anchors via SEP-10 Web Authentication."
- **SEP-12 KYC**, when the receiving anchor needs customer data, through its own `KYC_SERVER`.
- **SEP-38 quotes**, for flows with asset conversion, through its `ANCHOR_QUOTE_SERVER`.

Transactions report statuses like `pending_sender`, `pending_stellar`, `pending_receiver`, `pending_external`, `completed`, `refunded`, `expired`, and `error`. SEP-31 is marked Active at version 3.1.0.

The catch is in the plural. Every receiving anchor is a separate counterparty with its own KYC fields and its own quote server. Three corridors can mean three integrations.

## What do SEP-38 quotes lock?

SEP-38, the Anchor RFQ API, has two kinds of price ([SEP-38](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0038.md)):

- **Indicative**, from `GET /prices` and `GET /price`. "These prices are indicative." The actual price is set at conversion time.
- **Firm**, from `POST /quote`. The quoted amount "must be held in reserve" until expiry, and `expires_at` is "the date and time by which the anchor must receive funds from the client."

SEP-31 ties the two together: with a firm quote, "the Stellar transaction must be submitted to the Stellar network prior to the quote's expiration." Same idea as any binding payout quote. One more detail: SEP-38 is still a Draft, at version 2.5.0, so anchors may implement it differently.

That split mirrors the RFQ model in wholesale FX, covered in [RFQ pricing for stablecoin FX](/resources/more/rfq-pricing-stablecoin-fx-explained).

## How does a payout API do the same off-ramp?

One integration, one quote format, one KYC relationship. On BlindPay, a Stellar payout funded from your own wallet takes three calls ([payout with Stellar](/docs/payout-stellar)):

1. **Quote.** Create a [payout quote](/docs/payout-quotes) against the recipient's bank account with a Stellar `network`. It locks the rate and fees for 5 minutes.
2. **Authorize and sign.** Stellar has no allowance mechanism, so the authorize endpoint returns an unsigned transaction to BlindPay's treasury address. You sign it with your Stellar key and submit it.
3. **Create the payout.** Send the quote ID and the signed transaction. BlindPay "independently re-validates the signed transaction against the quote (destination and amount)" before paying out.

On Stellar, BlindPay payouts are funded in USDC on mainnet, and development instances use USDB on `stellar_testnet` ([supported chains](/docs/kb/supported-chains)). The fiat side runs on local rails: ACH, wire, RTP, and SWIFT (POBO/COBO) in the US and globally, Pix and TED in Brazil, SPEI in Mexico, ACH Colombia, Transfers 3.0 in Argentina, and SEPA in Europe. The recipient never sees Stellar. They see a bank deposit.

Which network to fund from in the first place is its own question; [the best network to off-ramp stablecoins](/resources/more/best-network-to-off-ramp-stablecoins) compares finality and fees.

## How do anchors and a payout API compare?

| | SEP-24 | SEP-31 | SEP-38 | Payout API (BlindPay) |
| --- | --- | --- | --- | --- |
| Job | User's own deposit or withdrawal | Business cross-border payment | Prices and firm quotes | Business payout to a bank account |
| Who runs KYC | Anchor, on its hosted page | Receiving anchor, via SEP-12 | n/a | BlindPay, through the API |
| Price | Anchor's terms | SEP-38 quote, optional | Indicative or firm with `expires_at` | Locked quote, 5 minutes |
| Integration per corridor | One per anchor | One per receiving anchor | Per anchor quote server | One API for every rail |
| Spec status | Active, v3.8.0 | Active, v3.1.0 | Draft, v2.5.0 | Versioned REST API |

## Illustrative example: what do three corridors cost to integrate?

Illustrative example. A company holding USDC on Stellar pays contractors in Brazil, Mexico, and the US every month. These counts describe integration work, not prices.

| Step | Through anchors (SEP-31) | Through a payout API |
| --- | --- | --- |
| Find a counterparty per country | 3 receiving anchors | 1 provider |
| Auth setups (SEP-10 or API key) | 3 | 1 |
| KYC field sets to map | 3 SEP-12 schemas | 1 customer schema |
| Quote formats to parse | Up to 3 SEP-38 servers | 1 quote object |
| Status models to reconcile | 3 implementations of the SEP-31 statuses | 1 payout status model |

The anchor column isn't wrong. It's open, and nobody sits in the middle. It's just more surface. Add a fourth country and the left column grows by one of everything.

## Which one fits your product?

Pick by who owns the user.

- **Consumer Stellar wallet.** SEP-24 fits. Users pick a local anchor, the anchor's page handles their KYC, and your wallet only sends the payment.
- **Remittance business with existing anchor partners.** SEP-31 fits, if you already have the bilateral relationships in your corridors.
- **A business paying many recipients across countries.** A payout API fits. One quote format, one KYC flow, and the same code path for Stellar and every other network you hold.

You can mix them. A wallet that offers SEP-24 to its users can still send its own treasury payouts through an API. And the hub question behind both, who earns what on a conversion, is in [how on/off-ramp providers make money](/resources/more/how-onramp-offramp-providers-make-money).

## What to do next

If you hold USDC on Stellar, run one test payout on a development instance: create a quote with `stellar_testnet` and USDB, call authorize, sign, and create the payout. Time it end to end and compare it with the anchor flow you have today. The [Stellar payout guide](/docs/payout-stellar) has the code.
