Quickstart
Get your first payment working in five minutes. This guide walks through the complete flow using the test environment.
Prerequisites
- An APISettle account with an API key
- Node.js 18+ or any HTTP client
https://api.apisettle.com/v1 All amounts are in USDC micro-units (1 USDC = 1,000,000). 1.Create a service
A service represents your API or product. It holds your default pricing and generates the API key you'll use for all vendor-side calls.
// Create a service (vendor project) to get your service_id
const res = await fetch('https://api.apisettle.com/v1/services', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'My API',
pricing_model: 'per_request',
quote_amount: '2000000', // $2.00 default price
}),
})
const { id: serviceId } = await res.json() 2.Create a quote
When a buyer requests your service, create a quote specifying the price. The quote token is a signed, tamper-proof payment request with a built-in expiry.
// Create a payment request (quote)
const res = await fetch('https://api.apisettle.com/v1/quote', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
service_id: serviceId,
quote_amount: '500000', // $0.50
}),
})
const { quote_token, quote_id } = await res.json()
Quotes expire after 10 minutes by default. Pass expires_in_seconds to customize.
3.Settle the payment
The buyer submits the quote token to settle. APISettle executes the on-chain transfer and returns a settlement token as proof of payment.
// Settle the payment (consumer-side)
const res = await fetch('https://api.apisettle.com/v1/settle', {
method: 'POST',
headers: {
'Authorization': `Bearer ${CONSUMER_JWT}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
quote_token,
payment_attempt_id: 'attempt_abc123',
}),
})
const { settlement_id, settlement_token, tx_hash } = await res.json()
The payment_attempt_id is your idempotency key. Same ID = same result, never double-charged.
4.Redeem the settlement
Before delivering your service, redeem the settlement. This is an atomic, one-time operation — it cannot be replayed or double-spent.
// Redeem the settlement (vendor-side)
const res = await fetch(
`https://api.apisettle.com/v1/settlements/${settlement_id}/redeem`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ settlement_token }),
},
)
const { status, redeemed_at } = await res.json()
// status === "redeemed" → deliver the service Full integration example
Here's how these steps fit together in a typical vendor endpoint. The pattern is simple: if the caller hasn't paid, return 402 with a quote. If they have, redeem and deliver.
export default async function handlePaidRequest(req, res) {
const settlementToken = req.headers['x-settlement-token']
// No token yet — create a quote and ask for payment
if (!settlementToken) {
const quote = await createQuote({
service_id: SERVICE_ID,
quote_amount: '500000',
})
return res.status(402).json({
quote_token: quote.quote_token,
quote_id: quote.quote_id,
amount: quote.quote_amount,
})
}
// Token present — redeem it
const settlementId = req.headers['x-settlement-id']
const result = await redeemSettlement(settlementId, settlementToken)
if (result.status !== 'redeemed') {
return res.status(402).json({ error: 'payment_required' })
}
// Payment confirmed — deliver the service
return res.status(200).json({ data: 'your response here' })
}