For the complete documentation index, see llms.txt. This page is also available as Markdown.

Endpoints

Every route — method, auth tier, request, and response — across all five order types.

The full route contract. Paths are relative to your environment base URL. The auth tier per route is in Authentication; the complete error catalog is in Error Codes.

Every response uses the envelope { "success": true, "data": … } on success and { "success": false, "error": { "code", "message", "details" } } on failure. The one exception is GET /health.

Public

GET /health

Liveness and database probe. No auth. Three shapes: 200 with status: "ok" and services.database: "healthy"; 200 with status: "degraded" and services.database: "unhealthy"; or 503 with status: "error" and no services field at all. The 503 body carries no error detail — this is the only endpoint outside the standard envelope, because it's consumed by load balancers rather than partner code.

Onboarding

POST /partner/onboard

X-Titan-Key only. Provisions a user's manager from a one-time SIWS signature. Idempotent. Full walkthrough in Onboarding.

// Request
{ "sub": "<your user id>", "userPubkey": "<base58>", "siws": { "message": "<canonical>", "signature": "<base58>" } }
// Response
{ "success": true, "data": { "userId": "<opaque>", "walletAddress": "<manager pubkey>" } }

User session

GET /me

X-Titan-Key + X-Titan-User. Resolves the current user. Returns { userId, walletAddress, sessionId } (sessionId is always empty for partners).

Balances

GET /me/balance?hideZero=false

Per-mint view of the manager, split into total / locked / available. hideZero=true drops rows where all buckets are zero.

lockedBreakdown.orderType is any of dca, stop_loss, take_profit, oco, or slice — trigger orders lock their full unspent amount while armed, and a Slice Order locks its unspent input while it runs. Field semantics are in Order & Execution Schema. Errors: 401 UNAUTHORIZED, 500 RPC_ERROR.

Orders — create

Always two steps, for every order type. intent returns an unsigned deposit tx; confirm submits the signed tx and activates the order.

POST /orders/intent

User-scoped. Optional X-Idempotency-Key. orderType accepts dca, stop_loss, take_profit, oco, or slice; the shared top-level fields are in Creating Orders, and each config shape is in Order Types. Pass onboardIfNeeded: true to provision a brand-new user inline and skip the separate SIWS step — see Single-transaction onboarding.

feeLamports is "0" when execution fees are sponsored on your environment (the partner default), otherwise "5000000" (0.005 SOL), included in the deposit tx.

POST /orders/confirm

After 200, a DCA order runs its cycles automatically; a trigger order is active and watching the price; a Slice Order begins executing. For a Slice Order, confirm can return 409 ACTIVE_BURST_EXISTS if a concurrent create won the race — the deposit has landed but no order was created.

Orders — read

Endpoint
Returns

GET /me/orders?status={status}&type={type}

All of the user's orders. status: pending | active | executing | pending_modification | paused | completed | cancelled | failed | expired. type: dca | stop_loss | take_profit | oco | slice.

GET /me/orders/active

Currently running orders.

GET /me/orders/history

Terminal orders (completed / cancelled / failed / expired).

GET /orders/pending

Orders awaiting confirmation (signed tx not yet submitted, or in flight).

GET /orders/pending/failed

Pending orders that timed out or failed before activating.

GET /orders/pending/history

All pending-order rows, any status, most recent first. Capped at 50 rows.

GET /dca/{orderId}

One DCA order with full cycle progress.

GET /stop-loss/{orderId}

One stop-loss order — adds amount, triggerPrice, priceDecimals, priceBasis, minOutputAmount?, expiresAt?, executedPrice?, executedPriceDecimals?, amountReceived?, trailingStopBps?, trailingMode?, currentTriggerPrice, highestObservedPrice?, and the bracket fields onFillOco?, childOrderId?, onFillError?.

GET /take-profit/{orderId}

One take-profit order — as stop-loss, but with trailingActivated in place of currentTriggerPrice, plus amountRemaining and scaleStepsExecuted.

GET /oco/{orderId}

One OCO order — adds amount, takeProfitPrice, stopLossPrice, priceDecimals, priceBasis, expiresAt?, executedPrice?, executedPriceDecimals?, amountReceived?, pendingLeg?, parentOrderId?, and the SL leg's trailingStopBps? / currentTriggerPrice / highestObservedPrice?.

GET /slice/{orderId}

One Slice Order. Returns { order, chunks } — the order nested under data.order, with confirmed slices in data.chunks. See Slice Orders.

GET /orders/{orderId}/executions

Execution history, most recent first. Capped at 500 rows.

GET /orders/{orderId}/deposit

The funding transfer that created the order. Any order type. Returns { txSignature, submittedAt }.

All five detail endpoints return 404 NOT_FOUND if the order doesn't exist, isn't this user's, or is a different orderType — so route off the orderType field from the list response rather than probing endpoints. GET /orders/{orderId}/deposit also 404s when the order has no recorded deposit. Full field lists in Order & Execution Schema.

Orders — modify, pause, resume, retry, cancel

Endpoint
What it does

PATCH /dca/{orderId}

DCA only. Modify an active/paused order. Returns requiresTransaction: false for in-place edits, or true with an unsigned tx when totalAmount changes.

POST /dca/{orderId}/modify/confirm

DCA only. Submit the signed modify tx with the matching cyclesCompleted + config.

PATCH /stop-loss/{orderId} · PATCH /take-profit/{orderId} · PATCH /oco/{orderId}

Modify an active/paused trigger order's prices, expiry and trail in place. Body { "config": { …partial… } }. No transaction. Returns { order } under data.

POST /orders/{orderId}/pause

Pause an active order. DCA and trigger orders; 400 PAUSE_NOT_SUPPORTED on a Slice Order.

POST /orders/{orderId}/resume

Resume a paused order. DCA and trigger orders.

POST /orders/{orderId}/retry

DCA only. Flip a failed order back to active, only before auto-return runs. Trigger orders and Slice Orders return 400 RETRY_NOT_SUPPORTED (usually preceded by 400 ALREADY_WITHDRAWN).

POST /orders/{orderId}/cancel

Cancel; discriminated on withdraw — { withdraw: false } or { withdraw: true, userPubkey }. DCA and trigger orders; 400 CANCEL_NOT_SUPPORTED on a Slice Order.

The flows and per-endpoint error codes are in Managing Orders — including Modify a trigger order — and, for DCA modify, DCA.

Wallet-level withdrawals

Endpoint
What it does

POST /withdraw/transaction

Build an unsigned wallet withdrawal tx. Body: { userPubkey, tokenMint, amount? } — omit amount for max.

POST /withdraw/confirm

Submit the signed tx. Body: { signedTransaction }.

Order-level withdrawals

Endpoint
What it does

POST /orders/{orderId}/withdraw

Build a withdrawal tx for one terminal order. Returns withdrawalAmounts (per-mint preview). Safe to retry.

POST /orders/{orderId}/withdraw/confirm

Submit the signed tx.

POST /orders/{orderId}/withdraw/abandon

Release a stuck withdrawalStatus: pending lock. Idempotent.

Both withdrawal flows are walked through in Withdrawals.

Partner reporting

Server-to-server, X-Titan-Key only — no X-Titan-User. Rows are scoped to your tenant and capped at 500. Narrow to one user with ?userId=<the userId from onboarding> (the opaque Titan id, not your sub).

GET /partners/me/orders

Query params: status (comma-separated; allowed subset: active, paused, completed, failed, cancelled), orderType (dca | stop_loss | take_profit | oco | slice), userId, createdAtGte, createdAtLte (ISO-8601 — an invalid timestamp returns 400 VALIDATION_ERROR).

The status filter here is a deliberate subset — executing, pending, pending_modification, and expired can't be filtered on this endpoint. Orders in those states still appear in unfiltered responses, just not when status= is set.

Each row is the same shape as the per-type detail endpoints except originatingPartner and the internal tenantId are omitted — every row here is yours by definition.

GET /partners/me/orders/{id}

A single order by id, scoped to your tenant. 404 if it doesn't exist or belongs to another partner (no cross-tenant existence leak).

GET /partners/me/orders/{id}/deposit

The tenant-scoped twin of GET /orders/{orderId}/deposit — same { txSignature, submittedAt } response. 404s under the same conditions, plus when the order belongs to another partner.

GET /partners/me/executions

Per-execution rows including the fee snapshot, for billing reconciliation. Query params: userId, createdAtGte, createdAtLte. executionType is one of dca_cycle, stop_loss, take_profit_full, take_profit_scaled, or slice_fill. Row shape and fixed-point rules are in Order & Execution Schema.

Last updated