SettleMint

A typed v2 API built for real integrations

The v2 REST API at /api/v2 adds JSON:API filtering and sorting, offset pagination, idempotency keys for safe retries, and headers that control identity, wallet routing, and response timing.

The v2 REST API is the surface real integrations needed. Filter and sort every list, page through results, and retry mutations safely with an idempotency key. Transactions run asynchronously first, so a write survives a slow or stuck chain. The v2 API is served at /api/v2, and the v1 API stays frozen at /api/v1.

v2 API

Query it like a database, retry it like it's safe.

Every list endpoint accepts structured filters, a sort field and direction, and offset pagination. The JSON:API query conventions keep the syntax the same across resources. Mutations accept an idempotency key so a retried request after an uncertain response runs once, not twice. The interactive reference and OpenAPI specification are served live at /api/v2.

Base path
/api/v2
Query conventions
JSON:API
Safe retries
Idempotency-Key
v1
Frozen at /api/v1

The v1 API answered a simple need: call an endpoint, get a result. Real integrations needed more.

They needed to ask for the 50 most recent holders of one token, retry a mint after a dropped connection without minting twice, and decide whether a call waits for on-chain settlement or returns immediately. The v2 API is built for that, on a typed contract the SDK generates a client from.

Filter and sort every list

List endpoints accept structured filters using JSON:API bracket notation. A filter with no operator uses the field's default; an explicit operator goes in a second bracket. Supported operators are eq, ne, gt, gte, lt, lte, iLike (case-insensitive match), inArray, notInArray, isEmpty, and isNotEmpty. An inArray filter accepts up to 100 values.

GET /api/v2/tokens?filter[status][eq]=active&filter[name][iLike]=acme&sortBy=createdAt&sortDirection=desc&limit=50&offset=0

Sorting takes a sortBy column and a sortDirection of asc or desc, defaulting to ascending by creation time. Each resource restricts sortBy to its own typed set of columns, so a sort request that an endpoint cannot honor is rejected at the contract rather than silently ignored.

Page through results predictably

Pagination is offset based. Pass limit (default 50, maximum 200) and offset, and every collection response returns the links you need to walk the set without computing offsets yourself.

{
  "data": [ /* ... */ ],
  "links": {
    "self": "/api/v2/tokens?limit=50&offset=0",
    "first": "/api/v2/tokens?limit=50&offset=0",
    "prev": null,
    "next": "/api/v2/tokens?limit=50&offset=50",
    "last": "/api/v2/tokens?limit=50&offset=200"
  }
}

Asynchronous first, synchronous when you ask

A blockchain write takes real time to settle. The platform submits it, waits for it to be included in a block, and confirms it, and that takes seconds, or longer when the network is busy. An API that blocks the caller's connection until the chain confirms is fragile: a dropped request loses the result, a slow block ties up the client, and a stuck transaction hangs the call. So transaction routes on the v2 API are asynchronous first.

When you submit a transaction, the platform accepts it, queues it durably, and returns 202 Accepted with a status URL straight away. The instruction then runs in the background on the durable transaction engine, so it survives a dropped connection, a restart, or a slow chain. You poll the status URL until the operation reaches a terminal state.

POST /api/v2/tokens/{address}/mints
Prefer: respond-async

202 Accepted
{ "statusUrl": "/api/v2/transactions/tx_01J...", "status": "pending" }

Switch to synchronous when you want the result inline

For a short, interactive flow where you need the result before continuing, ask the platform to wait. Send Prefer: wait=N to hold the response for up to N seconds, clamped to between 5 and 99, while the operation settles. A synchronous wait never changes the outcome. It only changes whether the platform returns the result inline or hands back a status URL to poll.

  • If the operation settles within the budget, the platform returns 200 OK with the settled response.
  • If the budget elapses first, it degrades to the same 202 Accepted status URL, and you poll from there.

The platform echoes the directives it honored in the Preference-Applied response header.

curl -X POST https://your-platform.example.com/api/v2/tokens/0x1234.../mints \
  -H "x-api-key: YOUR_DALP_API_KEY" \
  -H "Idempotency-Key: mint-2026-05-17-001" \
  -H "Prefer: wait=30" \
  -H "Content-Type: application/json" \
  -d '{ "recipients": ["0x1111..."], "amounts": ["1000"] }'

The SDK waits by default

The TypeScript SDK sends Prefer: wait=99 on mutations unless you set your own preference, so SDK calls return the settled result directly in most cases rather than a handle to poll. Opt back into the asynchronous handle with Prefer: respond-async, set on the client or on the individual call.

GoalWhat to send
Get the settled result inline for a short operationPrefer: wait=N (5 to 99 seconds)
Accept the request now and track the status URL yourselfPrefer: respond-async
Match the SDK default over raw HTTPPrefer: wait=99

Use a synchronous wait for short interactive flows. Use the asynchronous path for long-running operations, batch jobs, or any flow that already tracks transaction status and events. Pair Prefer with Idempotency-Key so a retry after a degraded 202 attaches to the original instruction instead of submitting a new one.

Retry mutations safely

The hardest part of any write API is the uncertain response: the request left, but the reply never arrived. Send an Idempotency-Key header with a mutation and a retry is safe. The platform recognizes the key, runs the operation once, and returns the original result on the retry instead of executing it again. The key is scoped to your organization. Generate a unique key per instruction, store it next to your own job ID, and reuse it only when retrying the same request. Change the payload, route, or method and you create a new instruction with a new key.

curl -X POST https://your-platform.example.com/api/v2/tokens/mint \
  -H "x-api-key: YOUR_DALP_API_KEY" \
  -H "Idempotency-Key: mint-2026-05-17-001" \
  -H "Content-Type: application/json" \
  -d '{ "token": "...", "to": "...", "amount": "1000" }'

Control identity and wallet per request

A few headers let one API key act precisely without a separate credential per actor.

X-Participant

Selects the participant the request acts as, in canonical pp_<uuid> form. Defaults to the authenticated session participant.

X-Executor

Selects the wallet that signs: a direct signing address or a smart wallet. Defaults to the organization's configured executor routing policy.

Prefer

Controls response timing for transactions: wait for settlement and return the result inline, or take the asynchronous handle. See the section above.

Idempotency-Key

Makes a mutation safe to retry: the same key runs the instruction once and replays the original result.

Errors your code can branch on

Every v2 response carries the same structured error envelope as the SDK and CLI. The envelope includes a stable DALP-NNNN id, a category that classifies the failure, a retryable boolean, a message for display, a why explaining the cause, and a fix describing the next step. When the platform knows how long to wait, it includes retryAfterSeconds. Calling code branches on the category and retryability, never on a parsed prose string. See the error code reference and error handling.

v1 stays available

The v2 API is the default, and /api redirects to /api/v2. The v1 API is not removed. It stays frozen at /api/v1 with its request and response shapes unchanged, so existing integrations keep working without a migration deadline. Its specification remains available at /api/v1/spec.json. Move to v2 when you want filtering, sorting, idempotency keys, and response-timing control; stay on v1 until then.

v1: call and get a result
  • List endpoints returned a set, with no structured filtering or sorting.
  • No standard idempotency, so a retried write risked running twice.
  • No per-request control over synchronous or asynchronous settlement.
  • Frozen and supported at /api/v1, with unchanged shapes.
v2: built for integrations
  • JSON:API filtering, sorting, and offset pagination on every list.
  • Idempotency keys make mutations safe to retry after an uncertain response.
  • The Prefer header chooses synchronous or asynchronous settlement per call.
  • A typed contract the SDK generates a client from, served at /api/v2.

Get started with the API → · Request headers →

On this page