diff --git a/api-reference/delta-v2/agents-list.mdx b/api-reference/delta-v2/agents-list.mdx
new file mode 100644
index 0000000..337fab1
--- /dev/null
+++ b/api-reference/delta-v2/agents-list.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/agents/list/{chainId}"
+description: "List the active solver agents competing in the auction for a chain. Use the names to filter pricing via includeAgents / excludeAgents."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/agents/list/{chainId}"
+---
diff --git a/api-reference/delta-v2/bridge-protocols.mdx b/api-reference/delta-v2/bridge-protocols.mdx
new file mode 100644
index 0000000..1cea4b7
--- /dev/null
+++ b/api-reference/delta-v2/bridge-protocols.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/prices/bridge-protocols"
+description: "Active bridge protocols (slug, display name, icon) for rendering a bridge picker."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/prices/bridge-protocols"
+---
diff --git a/api-reference/delta-v2/bridge-routes.mdx b/api-reference/delta-v2/bridge-routes.mdx
new file mode 100644
index 0000000..9a22e99
--- /dev/null
+++ b/api-reference/delta-v2/bridge-routes.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/prices/bridge-routes"
+description: "Crosschain bridge-route catalogue: every supported (srcChainId, destChainId, tokens) triple."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/prices/bridge-routes"
+---
diff --git a/api-reference/delta-v2/is-token-supported.mdx b/api-reference/delta-v2/is-token-supported.mdx
new file mode 100644
index 0000000..f4c7512
--- /dev/null
+++ b/api-reference/delta-v2/is-token-supported.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/prices/is-token-supported"
+description: "Quick yes/no check for token support on a chain."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/prices/is-token-supported"
+---
diff --git a/api-reference/delta-v2/orders-build.mdx b/api-reference/delta-v2/orders-build.mdx
new file mode 100644
index 0000000..57ac38c
--- /dev/null
+++ b/api-reference/delta-v2/orders-build.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/orders/build"
+description: "Server-built EIP-712 typed data ready to sign. Pass the route from /delta/v2/prices verbatim."
+openapi: "/api-reference/specs/delta-v2.json POST /delta/v2/orders/build"
+---
diff --git a/api-reference/delta-v2/orders-cancel.mdx b/api-reference/delta-v2/orders-cancel.mdx
new file mode 100644
index 0000000..8b8147c
--- /dev/null
+++ b/api-reference/delta-v2/orders-cancel.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/orders/cancel"
+description: "Cancel one or more open Delta V2 orders by ID."
+openapi: "/api-reference/specs/delta-v2.json POST /delta/v2/orders/cancel"
+---
diff --git a/api-reference/delta-v2/orders-fillable-balance.mdx b/api-reference/delta-v2/orders-fillable-balance.mdx
new file mode 100644
index 0000000..6ed7716
--- /dev/null
+++ b/api-reference/delta-v2/orders-fillable-balance.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/orders/fillablebalance/{chainId}/{userAddress}"
+description: "User's source-token balance minus any amounts already committed to open limit orders. Use it when sizing a new limit order."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/orders/fillablebalance/{chainId}/{userAddress}/{tokenAddress}"
+---
diff --git a/api-reference/delta-v2/orders-get-by-hash.mdx b/api-reference/delta-v2/orders-get-by-hash.mdx
new file mode 100644
index 0000000..d7950fd
--- /dev/null
+++ b/api-reference/delta-v2/orders-get-by-hash.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/orders/hash/{hash}"
+description: "Fetch a Delta V2 order by its EIP-712 hash — useful before the order id is assigned."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/orders/hash/{hash}"
+---
diff --git a/api-reference/delta-v2/orders-get-by-id.mdx b/api-reference/delta-v2/orders-get-by-id.mdx
new file mode 100644
index 0000000..0cf4292
--- /dev/null
+++ b/api-reference/delta-v2/orders-get-by-id.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/orders/{orderId}"
+description: "Fetch a Delta V2 order by its UUID — the id returned by POST /delta/v2/orders."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/orders/{orderId}"
+---
diff --git a/api-reference/delta-v2/orders-list.mdx b/api-reference/delta-v2/orders-list.mdx
new file mode 100644
index 0000000..f363b2a
--- /dev/null
+++ b/api-reference/delta-v2/orders-list.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/orders"
+description: "Paginated list of a user's Delta V2 orders, filterable by chain, status, type, and on-chain order type."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/orders"
+---
diff --git a/api-reference/delta-v2/orders-submit.mdx b/api-reference/delta-v2/orders-submit.mdx
new file mode 100644
index 0000000..0e77ffe
--- /dev/null
+++ b/api-reference/delta-v2/orders-submit.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/orders"
+description: "Submit a signed Delta V2 order. The relayer validates signature, balance, and allowance, then enrolls it into the sealed-bid auction."
+openapi: "/api-reference/specs/delta-v2.json POST /delta/v2/orders"
+---
diff --git a/api-reference/delta-v2/overview.mdx b/api-reference/delta-v2/overview.mdx
new file mode 100644
index 0000000..d4b646a
--- /dev/null
+++ b/api-reference/delta-v2/overview.mdx
@@ -0,0 +1,65 @@
+---
+title: "Delta V2 API"
+description: "Server-built EIP-712 orders, route-based pricing with alternatives, paginated history, and a unified status model. Recommended path for new Delta integrations."
+keywords: ["delta", "delta v2", "api-reference"]
+---
+
+Delta V2 is the recommended path for Delta integrations. The on-chain contracts and settlement model are identical to [Delta V1](/api-reference/delta/overview); the protocol surface changes for the better:
+
+- **Server-built orders.** `POST /delta/v2/orders/build` returns EIP-712 typed data ready to sign — clients don't compose `domain`, `types`, and `value` locally.
+- **Route-based pricing.** `GET /delta/v2/prices` returns a recommended `route` plus `alternatives` so users can pick a different bridge or path.
+- **Paginated history.** `GET /delta/v2/orders` returns `{ data, total, page, limit, hasMore }`.
+- **Unified status model.** Eleven values (`PENDING`, `AWAITING_SIGNATURE`, `ACTIVE`, `SUSPENDED`, `CANCELLING`, `BRIDGING`, `COMPLETED`, `FAILED`, `EXPIRED`, `CANCELLED`, `REFUNDED`) replace the V1 split between `status` + `bridgeStatus`.
+- **Server-resolved partner fee.** Pass `partner` / `partnerAddress` / `partnerFeeBps` raw — the server validates and encodes them. No client-side `getPartnerFee` round-trip.
+
+## Lifecycle
+
+
+
+ `GET /delta/v2/prices` — returns `route`, `alternatives`, and the `spender` contract address.
+
+
+ ERC-20 `approve(spender, amount)` against `price.spender`, or sign Permit / Permit2 with the same `verifyingContract`. Native tokens skip this.
+
+
+ `POST /delta/v2/orders/build` — returns `{ toSign: { domain, types, value }, orderHash }`.
+
+
+ Sign `toSign` with `signTypedData` on the user's wallet.
+
+
+ `POST /delta/v2/orders` — passes `order: toSign.value` and `signature` to the relayer.
+
+
+ `GET /delta/v2/orders/{orderId}` until `status === "COMPLETED"` (or a terminal failure).
+
+
+
+## Endpoints
+
+| Method | Path | Purpose |
+|---|---|---|
+| `GET` | `/delta/v2/prices` | Recommended route + alternatives, same-chain or crosschain |
+| `GET` | `/delta/v2/prices/bridge-routes` | Supported `(srcChainId, destChainId, tokens)` triples |
+| `GET` | `/delta/v2/prices/bridge-protocols` | Active bridge protocols (slug, name, icon) |
+| `GET` | `/delta/v2/prices/strategies/{chainId}` | Delta yield strategies with APR |
+| `GET` | `/delta/v2/prices/is-token-supported` | Quick token-support check |
+| `POST` | `/delta/v2/orders/build` | Server-built EIP-712 typed data ready to sign |
+| `POST` | `/delta/v2/orders` | Submit a signed order |
+| `POST` | `/delta/v2/orders/cancel` | Sign-and-post cancellation |
+| `GET` | `/delta/v2/orders` | List a user's orders (paginated) |
+| `GET` | `/delta/v2/orders/{orderId}` | Order by UUID |
+| `GET` | `/delta/v2/orders/hash/{hash}` | Order by EIP-712 hash |
+| `GET` | `/delta/v2/orders/fillablebalance/...` | Fillable balance for limit-order sizing |
+| `GET` | `/delta/v2/agents/list/{chainId}` | List active auction agents |
+
+## SDK shortcut
+
+Every endpoint is wrapped by [`sdk.deltaV2.*`](/sdk/modules/delta) — the SDK handles signing, partner-fee defaults, and the build → sign → post orchestration. For a 5-minute walkthrough see [SDK → Delta module](/sdk/modules/delta).
+
+## Related pages
+
+- [Why Delta](/delta/overview) — protocol overview.
+- [Order lifecycle and status codes](/delta/order-lifecycle-and-status-codes) — the V2 status model end-to-end.
+- [SDK → Delta module](/sdk/modules/delta) — TypeScript examples (V2 primary, V1 below).
+- [Delta V1 API](/api-reference/delta/overview) — the V1 surface, still fully supported.
diff --git a/api-reference/delta-v2/prices.mdx b/api-reference/delta-v2/prices.mdx
new file mode 100644
index 0000000..57d3b62
--- /dev/null
+++ b/api-reference/delta-v2/prices.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/prices"
+description: "Recommended route plus alternatives for a same-chain or crosschain Delta V2 swap."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/prices"
+---
diff --git a/api-reference/delta-v2/strategies.mdx b/api-reference/delta-v2/strategies.mdx
new file mode 100644
index 0000000..bb130ab
--- /dev/null
+++ b/api-reference/delta-v2/strategies.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/v2/prices/strategies/{chainId}"
+description: "Delta yield strategies (with APR) wired for ProductiveOrder swaps, keyed by underlying token."
+openapi: "/api-reference/specs/delta-v2.json GET /delta/v2/prices/strategies/{chainId}"
+---
diff --git a/api-reference/delta/agents-list.mdx b/api-reference/delta/agents-list.mdx
new file mode 100644
index 0000000..fab3700
--- /dev/null
+++ b/api-reference/delta/agents-list.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/agents/list/{chainId}"
+description: "List the active solver agents competing in the V1 auction for a chain."
+openapi: "/api-reference/specs/delta.json GET /delta/agents/list/{chainId}"
+---
diff --git a/api-reference/delta/bridge-info.mdx b/api-reference/delta/bridge-info.mdx
new file mode 100644
index 0000000..00fe638
--- /dev/null
+++ b/api-reference/delta/bridge-info.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/prices/bridge-info"
+description: "Supported crosschain bridge lanes grouped by srcChainId then destChainId."
+openapi: "/api-reference/specs/delta.json GET /delta/prices/bridge-info"
+---
diff --git a/api-reference/delta/bridge-protocols.mdx b/api-reference/delta/bridge-protocols.mdx
new file mode 100644
index 0000000..cf6dba2
--- /dev/null
+++ b/api-reference/delta/bridge-protocols.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/prices/bridge-protocols"
+description: "Active bridge protocols (slug, display name, icon)."
+openapi: "/api-reference/specs/delta.json GET /delta/prices/bridge-protocols"
+---
diff --git a/api-reference/delta/is-token-supported.mdx b/api-reference/delta/is-token-supported.mdx
new file mode 100644
index 0000000..12e3f08
--- /dev/null
+++ b/api-reference/delta/is-token-supported.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/prices/is-token-supported"
+description: "Quick yes/no check for Delta token support on a chain."
+openapi: "/api-reference/specs/delta.json GET /delta/prices/is-token-supported"
+---
diff --git a/api-reference/delta/orderbook.mdx b/api-reference/delta/orderbook.mdx
new file mode 100644
index 0000000..032d96f
--- /dev/null
+++ b/api-reference/delta/orderbook.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/orders/orderbook/{chainId}/{agent}"
+description: "Pending orderbook slice for a specific auction agent. Agent operators only — not intended for end-user integrations."
+openapi: "/api-reference/specs/delta.json GET /delta/orders/orderbook/{chainId}/{agent}"
+---
diff --git a/api-reference/delta/orders-build.mdx b/api-reference/delta/orders-build.mdx
index 4214e22..d588938 100644
--- a/api-reference/delta/orders-build.mdx
+++ b/api-reference/delta/orders-build.mdx
@@ -1,5 +1,5 @@
---
-title: "POST /delta/orders/build"
+title: "/delta/orders/build"
description: "Build a signable Delta order — EIP-712 typed data — from a Delta quote."
openapi: "/api-reference/specs/delta.json POST /delta/orders/build"
---
diff --git a/api-reference/delta/orders-cancel.mdx b/api-reference/delta/orders-cancel.mdx
new file mode 100644
index 0000000..0dfe76f
--- /dev/null
+++ b/api-reference/delta/orders-cancel.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/orders/cancel"
+description: "Cancel one or more open Delta V1 orders by ID."
+openapi: "/api-reference/specs/delta.json POST /delta/orders/cancel"
+---
diff --git a/api-reference/delta/orders-fillable-balance.mdx b/api-reference/delta/orders-fillable-balance.mdx
new file mode 100644
index 0000000..31a6139
--- /dev/null
+++ b/api-reference/delta/orders-fillable-balance.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/orders/fillablebalance/{chainId}/{userAddress}"
+description: "User's source-token balance minus amounts committed to open limit orders. Use it when sizing a new limit order."
+openapi: "/api-reference/specs/delta.json GET /delta/orders/fillablebalance/{chainId}/{userAddress}/{tokenAddress}"
+---
diff --git a/api-reference/delta/orders-get-by-hash.mdx b/api-reference/delta/orders-get-by-hash.mdx
new file mode 100644
index 0000000..ae2d526
--- /dev/null
+++ b/api-reference/delta/orders-get-by-hash.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/orders/hash/{hash}"
+description: "Fetch a Delta V1 order by its EIP-712 hash — useful before the order id is assigned."
+openapi: "/api-reference/specs/delta.json GET /delta/orders/hash/{hash}"
+---
diff --git a/api-reference/delta/orders-get-by-id.mdx b/api-reference/delta/orders-get-by-id.mdx
new file mode 100644
index 0000000..0b9c64d
--- /dev/null
+++ b/api-reference/delta/orders-get-by-id.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/orders/{orderId}"
+description: "Fetch a Delta V1 order by its UUID — the id returned by POST /delta/orders."
+openapi: "/api-reference/specs/delta.json GET /delta/orders/{orderId}"
+---
diff --git a/api-reference/delta/orders-list.mdx b/api-reference/delta/orders-list.mdx
new file mode 100644
index 0000000..ff8b2e4
--- /dev/null
+++ b/api-reference/delta/orders-list.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/orders"
+description: "List a user's Delta V1 orders. Returns a flat array — V2 wraps the response in a paginated envelope."
+openapi: "/api-reference/specs/delta.json GET /delta/orders"
+---
diff --git a/api-reference/delta/orders.mdx b/api-reference/delta/orders.mdx
index fc211e1..0574285 100644
--- a/api-reference/delta/orders.mdx
+++ b/api-reference/delta/orders.mdx
@@ -1,5 +1,5 @@
---
-title: "POST /delta/orders"
+title: "/delta/orders"
description: "Submit a signed Delta order to the solver network."
openapi: "/api-reference/specs/delta.json POST /delta/orders"
---
diff --git a/api-reference/delta/overview.mdx b/api-reference/delta/overview.mdx
index 0d4f611..1fa91d8 100644
--- a/api-reference/delta/overview.mdx
+++ b/api-reference/delta/overview.mdx
@@ -1,13 +1,48 @@
---
-title: "Delta API"
-description: "OpenAPI reference for the Velora Delta intents API."
-keywords: ["delta","intents","api"]
+title: "Delta V1 API"
+sidebarTitle: "Overview"
+description: "Local EIP-712 order building, flat order lists, and the unified /quote endpoint with Market fallback. Shares on-chain contracts with Delta V2."
+keywords: ["delta", "delta v1", "api-reference"]
---
-This page is a stub. Content coming soon.
+Delta V1 is the original Delta protocol surface. The on-chain contracts and settlement model are identical to [Delta V2](/api-reference/delta-v2/overview); V1 differs in how clients assemble and consume orders:
-## Parameters
+- **Locally built orders.** Clients compose EIP-712 typed data themselves from a `/delta/prices` (or `/quote`) response. `POST /delta/orders/build` returns the `data` / `domain` / `types` triple to sign.
+- **Flat price.** `GET /delta/prices` returns a single `DeltaPrice` (or `BridgePrice` for crosschain) — no `route` / `alternatives` envelope.
+- **Flat order list.** `GET /delta/orders` returns a plain array, paginated by `page` / `limit` query params (no `total` / `hasMore` envelope).
+- **Locally resolved partner fee.** Clients call `GET /prices/partnerfee/{chainId}` themselves to look up the registered fee config (the V1 SDK caches it).
+- **Unified quote.** `GET /quote` returns either a `delta` block or a `market` block (or both with `mode=ALL`) — useful when you want Delta with automatic Market fallback. V2 doesn't have an equivalent endpoint.
-## Examples
+[Delta V2](/api-reference/delta-v2/overview) is recommended for new integrations. V1 remains fully supported.
+
+## Endpoints
+
+| Method | Path | Purpose |
+|---|---|---|
+| `GET` | `/quote` | Unified Delta-with-fallback-to-Market price |
+| `GET` | `/delta/prices` | Delta price (same-chain or crosschain) |
+| `GET` | `/delta/prices/bridge-info` | Supported crosschain lanes (srcChainId → destChainId → tokens) |
+| `GET` | `/delta/prices/bridge-protocols` | Active bridge protocols (slug, name, icon) |
+| `GET` | `/delta/prices/strategies/{chainId}` | Delta yield strategies with APR |
+| `GET` | `/delta/prices/is-token-supported` | Quick token-support check |
+| `GET` | `/prices/partnerfee/{chainId}` | Resolve registered partner-fee config (shared with Market) |
+| `POST` | `/delta/orders/build` | EIP-712 typed data ready to sign |
+| `POST` | `/delta/orders` | Submit a signed order |
+| `POST` | `/delta/orders/cancel` | Sign-and-post cancellation |
+| `GET` | `/delta/orders` | List a user's orders (flat array) |
+| `GET` | `/delta/orders/{orderId}` | Order by UUID |
+| `GET` | `/delta/orders/hash/{hash}` | Order by EIP-712 hash |
+| `GET` | `/delta/orders/fillablebalance/...` | Fillable balance for limit-order sizing |
+| `GET` | `/delta/orders/orderbook/{chainId}/{agent}` | Agent-facing orderbook slice (operators only) |
+| `GET` | `/delta/agents/list/{chainId}` | List active auction agents |
+
+## SDK shortcut
+
+The V1 surface is wrapped by [`sdk.delta.*`](/sdk/modules/delta#delta-v1) on the [Velora SDK](/sdk/overview). For a 5-minute walkthrough see [SDK → Delta module](/sdk/modules/delta).
## Related pages
+
+- [Why Delta](/delta/overview) — protocol overview.
+- [Order lifecycle and status codes](/delta/order-lifecycle-and-status-codes) — V1 status model end-to-end.
+- [Delta V2 API](/api-reference/delta-v2/overview) — the recommended surface.
+- [SDK → Delta module](/sdk/modules/delta) — TypeScript examples for both V1 and V2.
diff --git a/api-reference/delta/partner-fee.mdx b/api-reference/delta/partner-fee.mdx
new file mode 100644
index 0000000..f9b706f
--- /dev/null
+++ b/api-reference/delta/partner-fee.mdx
@@ -0,0 +1,5 @@
+---
+title: "/prices/partnerfee/{chainId}"
+description: "Resolve the registered partner-fee config for a partner key. Shared between Market and Delta."
+openapi: "/api-reference/specs/delta.json GET /prices/partnerfee/{chainId}"
+---
diff --git a/api-reference/delta/prices.mdx b/api-reference/delta/prices.mdx
new file mode 100644
index 0000000..f359396
--- /dev/null
+++ b/api-reference/delta/prices.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/prices"
+description: "Delta V1 price for a same-chain or crosschain swap. Pass the response verbatim (with hmac) to /delta/orders/build."
+openapi: "/api-reference/specs/delta.json GET /delta/prices"
+---
diff --git a/api-reference/delta/quote.mdx b/api-reference/delta/quote.mdx
index 6e0e220..717e0e9 100644
--- a/api-reference/delta/quote.mdx
+++ b/api-reference/delta/quote.mdx
@@ -1,9 +1,10 @@
---
-title: "GET /quote (Delta)"
+title: "/quote"
description: "Retrieve a Delta price, with optional fallback to Market via mode=ALL or mode=MARKET."
openapi: "/api-reference/specs/delta.json GET /quote"
---
- This endpoint accepts `mode=DELTA`, `mode=MARKET`, or `mode=ALL`. See [Trading modes](/integrate/trading-modes) for guidance and fallback semantics.
+ This endpoint accepts `mode=DELTA`, `mode=MARKET`, or `mode=ALL`. See [Trading
+ modes](/integrate/trading-modes) for guidance and fallback semantics.
diff --git a/api-reference/delta/strategies.mdx b/api-reference/delta/strategies.mdx
new file mode 100644
index 0000000..f4e8649
--- /dev/null
+++ b/api-reference/delta/strategies.mdx
@@ -0,0 +1,5 @@
+---
+title: "/delta/prices/strategies/{chainId}"
+description: "Delta yield strategies with APR, keyed by underlying token. Used to source the strategy address for ProductiveOrder builds."
+openapi: "/api-reference/specs/delta.json GET /delta/prices/strategies/{chainId}"
+---
diff --git a/api-reference/market/prices.mdx b/api-reference/market/prices.mdx
index 315debe..edb7cc8 100644
--- a/api-reference/market/prices.mdx
+++ b/api-reference/market/prices.mdx
@@ -1,9 +1,11 @@
---
-title: "GET /prices (Market)"
+title: "/prices"
description: "Get a Market route from the Velora aggregator."
openapi: "/api-reference/specs/market.json GET /prices"
---
- Looking for a single endpoint that returns either a Market route or a Delta intent? Call [`GET /quote`](/api-reference/delta/quote) with `mode=ALL` — see [Trading modes](/integrate/trading-modes).
+ Looking for a single endpoint that returns either a Market route or a Delta
+ intent? Call [`GET /quote`](/api-reference/delta/quote) with `mode=ALL` — see
+ [Trading modes](/integrate/trading-modes).
diff --git a/api-reference/market/transactions.mdx b/api-reference/market/transactions.mdx
index 4c7a657..d5454e7 100644
--- a/api-reference/market/transactions.mdx
+++ b/api-reference/market/transactions.mdx
@@ -1,5 +1,5 @@
---
-title: "POST /transactions/:network (Market)"
+title: "/transactions/:network"
description: "Build calldata for an Augustus v6.2 swap from a Market priceRoute."
openapi: "/api-reference/specs/market.json POST /transactions/{network}"
---
diff --git a/api-reference/specs/delta-v2.json b/api-reference/specs/delta-v2.json
new file mode 100644
index 0000000..b79b884
--- /dev/null
+++ b/api-reference/specs/delta-v2.json
@@ -0,0 +1,606 @@
+{
+ "openapi": "3.0.3",
+ "info": {
+ "title": "Velora Delta API V2",
+ "version": "2.0.0",
+ "description": "Velora Delta API V2 — server-built EIP-712 orders, route-based pricing with alternatives, paginated order history, and a unified status model. Ships alongside Delta V1; both protocols share the same on-chain contracts."
+ },
+ "servers": [
+ { "url": "https://api.velora.xyz", "description": "Production" }
+ ],
+ "paths": {
+ "/delta/v2/prices": {
+ "get": {
+ "summary": "Get a Delta V2 price (same-chain or crosschain)",
+ "description": "Returns a recommended `route` plus `alternatives` (up to a few bridge options for crosschain). Pass the returned `route` and `side` verbatim to `POST /delta/v2/orders/build`.",
+ "operationId": "deltaV2Prices",
+ "parameters": [
+ { "name": "chainId", "in": "query", "required": true, "schema": { "type": "integer", "example": 1 }, "description": "Source chain ID. Supported: 1, 10, 56, 100, 130, 137, 8453, 42161, 43114." },
+ { "name": "srcToken", "in": "query", "required": true, "schema": { "type": "string", "example": "0x6B175474E89094C44Da98b954EedeAC495271d0F" } },
+ { "name": "destToken", "in": "query", "required": true, "schema": { "type": "string", "example": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" }, "description": "Destination token. For crosschain quotes, the destination token on `destChainId`." },
+ { "name": "amount", "in": "query", "required": true, "schema": { "type": "string", "example": "1000000000000000000" }, "description": "Source amount (SELL) or destination amount (BUY), in raw token units." },
+ { "name": "srcDecimals", "in": "query", "required": true, "schema": { "type": "integer", "example": 18 } },
+ { "name": "destDecimals", "in": "query", "required": true, "schema": { "type": "integer", "example": 6 } },
+ { "name": "side", "in": "query", "required": false, "schema": { "type": "string", "enum": ["SELL", "BUY"], "default": "SELL" } },
+ { "name": "destChainId", "in": "query", "required": false, "schema": { "type": "integer" }, "description": "Omit for same-chain. When set, response `route.bridge` is populated." },
+ { "name": "userAddress", "in": "query", "required": false, "schema": { "type": "string" } },
+ { "name": "beneficiary", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Address that receives the destination token. Defaults to `userAddress`." },
+ { "name": "partner", "in": "query", "required": false, "schema": { "type": "string", "default": "anon", "example": "my-app-name" }, "description": "Partner key. Defaults to `anon` (1bps fee)." },
+ { "name": "partnerFeeBps", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 0, "maximum": 200 }, "description": "Override partner fee in basis points (max 200 = 2%)." },
+ { "name": "maxImpact", "in": "query", "required": false, "schema": { "type": "number" }, "description": "Maximum price impact in % (default 15)." },
+ { "name": "maxUSDImpact", "in": "query", "required": false, "schema": { "type": "number" }, "description": "Maximum price impact in USD." },
+ { "name": "includeAgents", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated list of agent names to include." },
+ { "name": "excludeAgents", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated list of agent names to exclude." },
+ { "name": "includeBridges", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated bridge protocol names to include (crosschain only)." },
+ { "name": "excludeBridges", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated bridge protocol names to exclude." },
+ { "name": "allowBridgeAndSwap", "in": "query", "required": false, "schema": { "type": "boolean", "default": true }, "description": "Allow combining bridge + on-chain swap. Forced to `false` for BUY side." }
+ ],
+ "responses": {
+ "200": {
+ "description": "Recommended route plus alternatives.",
+ "content": {
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/PriceV2" }
+ }
+ }
+ },
+ "400": { "description": "Invalid parameters or no route" },
+ "422": { "description": "Unsupported chain or token" }
+ }
+ }
+ },
+ "/delta/v2/prices/bridge-routes": {
+ "get": {
+ "summary": "List supported crosschain bridge routes",
+ "description": "Returns the set of `(srcChainId, destChainId, tokens)` triples that the relayer can quote.",
+ "operationId": "deltaV2BridgeRoutes",
+ "parameters": [
+ { "name": "bridges", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated bridge protocol names (e.g., `acrossv3,stargatev2`). Omit to list every active bridge." },
+ { "name": "allowBridgeAndSwap", "in": "query", "required": false, "schema": { "type": "boolean", "default": true } }
+ ],
+ "responses": {
+ "200": {
+ "description": "Flat list of supported routes.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "routes": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "srcChainId": { "type": "integer" },
+ "destChainId": { "type": "integer" },
+ "tokens": { "type": "array", "items": { "type": "string" }, "description": "Token addresses bridgeable on this lane." }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/delta/v2/prices/bridge-protocols": {
+ "get": {
+ "summary": "List active bridge protocols",
+ "description": "Display catalogue of every bridge protocol currently active in the relayer's `BridgeApi`. Useful for rendering a bridge picker.",
+ "operationId": "deltaV2BridgeProtocols",
+ "responses": {
+ "200": {
+ "description": "Active bridge protocols.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "bridgeProtocols": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "protocol": { "type": "string", "description": "Stable protocol slug. Use this for `includeBridges` / `excludeBridges` filters on `GET /delta/v2/prices`." },
+ "displayName": { "type": "string" },
+ "icon": { "type": "string", "description": "Absolute URL to a 1:1 SVG icon hosted on cdn.velora.xyz." }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/delta/v2/prices/strategies/{chainId}": {
+ "get": {
+ "summary": "List Delta yield strategies (with APR) for a chain",
+ "description": "Returns the on-chain Delta-token vaults wired for `ProductiveOrder` swaps, keyed by the underlying token address. APRs are refreshed server-side every 3 hours; `apr` is `null` when the strategy is too new to compute.",
+ "operationId": "deltaV2Strategies",
+ "parameters": [
+ { "name": "chainId", "in": "path", "required": true, "schema": { "type": "integer", "example": 1 } }
+ ],
+ "responses": {
+ "200": {
+ "description": "Map of `underlyingTokenAddress → { address, strategies }`.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "address": { "type": "string", "description": "Delta token (dToken) wrapper address." },
+ "strategies": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "vault": { "type": "string", "description": "ERC-4626 vault address. Pass this as `strategy` to `POST /delta/v2/orders/build` for a `ProductiveOrder`." },
+ "name": { "type": "string" },
+ "apr": {
+ "type": "object",
+ "nullable": true,
+ "properties": {
+ "gross": { "type": "string", "description": "Gross APR as a decimal string (e.g. `\"0.052\"` = 5.2%)." },
+ "net": { "type": "string", "description": "Net APR after fees, decimal string." }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": { "description": "Unsupported chain" }
+ }
+ }
+ },
+ "/delta/v2/prices/is-token-supported": {
+ "get": {
+ "summary": "Check whether a token is supported for Delta on a chain",
+ "operationId": "deltaV2IsTokenSupported",
+ "parameters": [
+ { "name": "chainId", "in": "query", "required": true, "schema": { "type": "integer", "example": 1 } },
+ { "name": "token", "in": "query", "required": true, "schema": { "type": "string", "example": "0x6B175474E89094C44Da98b954EedeAC495271d0F" } }
+ ],
+ "responses": {
+ "200": {
+ "description": "Token support flag.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": { "supported": { "type": "boolean" } }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/delta/v2/orders/build": {
+ "post": {
+ "summary": "Build a signable Delta V2 order from a route",
+ "description": "Returns EIP-712 typed data ready to sign and the order hash. Pass the unmodified `route` from `GET /delta/v2/prices`. Use `orderType` to select Standard / External / Productive / TWAP families.",
+ "operationId": "deltaV2OrdersBuild",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/BuildOrderV2Request" }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "EIP-712 typed data ready to sign.",
+ "content": {
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/BuiltOrderV2" }
+ }
+ }
+ },
+ "400": { "description": "Invalid params (missing TWAP totals, mismatched slice amounts, etc.)" }
+ }
+ }
+ },
+ "/delta/v2/orders": {
+ "post": {
+ "summary": "Submit a signed Delta V2 order",
+ "description": "Validates EIP-712 signature, nonce, balance, and allowance, then enrolls the order into the sealed-bid auction.",
+ "operationId": "deltaV2OrdersSubmit",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/SubmitOrderV2Request" }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Order accepted.",
+ "content": {
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/DeltaAuction" }
+ }
+ }
+ },
+ "400": { "description": "Invalid signature, expired, or balance/allowance failure" }
+ }
+ },
+ "get": {
+ "summary": "List a user's Delta V2 orders (paginated)",
+ "operationId": "deltaV2OrdersList",
+ "parameters": [
+ { "name": "userAddress", "in": "query", "required": true, "schema": { "type": "string" } },
+ { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "default": 1 } },
+ { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 100 } },
+ { "name": "chainId", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated chain IDs. Omit for all chains." },
+ { "name": "type", "in": "query", "required": false, "schema": { "type": "string", "enum": ["MARKET", "LIMIT"] } },
+ { "name": "status", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated `OrderStatusV2` values. See [Order lifecycle](/delta/order-lifecycle-and-status-codes)." },
+ { "name": "onChainOrderType", "in": "query", "required": false, "schema": { "type": "string", "enum": ["Order", "ProductiveOrder", "ExternalOrder", "TWAPOrder", "TWAPBuyOrder"] } }
+ ],
+ "responses": {
+ "200": {
+ "description": "Paginated envelope.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "data": { "type": "array", "items": { "$ref": "#/components/schemas/DeltaAuction" } },
+ "total": { "type": "integer" },
+ "page": { "type": "integer" },
+ "limit": { "type": "integer" },
+ "hasMore": { "type": "boolean" }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/delta/v2/orders/cancel": {
+ "post": {
+ "summary": "Cancel one or more Delta V2 orders",
+ "description": "Sign-and-post cancellation. Only succeeds for orders still open in the auction (`PENDING`, `AWAITING_SIGNATURE`, `ACTIVE`, `SUSPENDED`).",
+ "operationId": "deltaV2OrdersCancel",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": ["orderIds", "signature"],
+ "properties": {
+ "orderIds": { "type": "array", "items": { "type": "string", "format": "uuid" }, "minItems": 1, "maxItems": 100 },
+ "signature": { "type": "string", "description": "EIP-712 signature over the cancellation payload." }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Cancellation accepted.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "cancelled": { "type": "array", "items": { "type": "string", "format": "uuid" } }
+ }
+ }
+ }
+ }
+ },
+ "400": { "description": "Invalid signature or order already settled" }
+ }
+ }
+ },
+ "/delta/v2/orders/fillablebalance/{chainId}/{userAddress}/{tokenAddress}": {
+ "get": {
+ "summary": "Compute a user's fillable balance for limit orders",
+ "description": "Returns the user's wallet balance **minus** any source-token already committed to open limit orders on a chain. Use this when sizing a new limit order so it doesn't double-commit funds.\n\n`tokenAddress` is an optional trailing path segment — **omit it** (`/delta/v2/orders/fillablebalance/{chainId}/{userAddress}`) to get the fillable balance for every token with open commitments. With `tokenAddress` set, the response holds a single entry for that token (or `\"0\"` if the user has no open commitments on it).",
+ "operationId": "deltaV2OrdersFillableBalance",
+ "parameters": [
+ { "name": "chainId", "in": "path", "required": true, "schema": { "type": "integer", "example": 1 } },
+ { "name": "userAddress", "in": "path", "required": true, "schema": { "type": "string" } },
+ { "name": "tokenAddress", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Source token to inspect. Omit the entire segment to get balances for every committed token." }
+ ],
+ "responses": {
+ "200": {
+ "description": "Map of `tokenAddress → fillableBalance` (raw token units as a string).",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": { "type": "string" },
+ "example": {
+ "0x6B175474E89094C44Da98b954EedeAC495271d0F": "500000000000000000"
+ }
+ }
+ }
+ }
+ },
+ "400": { "description": "Unsupported chain" }
+ }
+ }
+ },
+ "/delta/v2/orders/{orderId}": {
+ "get": {
+ "summary": "Get a Delta V2 order by ID",
+ "operationId": "deltaV2OrderById",
+ "parameters": [
+ { "name": "orderId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
+ ],
+ "responses": {
+ "200": {
+ "description": "Order details.",
+ "content": {
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/DeltaAuction" }
+ }
+ }
+ },
+ "404": { "description": "Order not found" }
+ }
+ }
+ },
+ "/delta/v2/orders/hash/{hash}": {
+ "get": {
+ "summary": "Get a Delta V2 order by EIP-712 hash",
+ "operationId": "deltaV2OrderByHash",
+ "parameters": [
+ { "name": "hash", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Order hash returned by `POST /delta/v2/orders/build`." }
+ ],
+ "responses": {
+ "200": {
+ "description": "Order details.",
+ "content": {
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/DeltaAuction" }
+ }
+ }
+ },
+ "404": { "description": "Order not found" }
+ }
+ }
+ },
+ "/delta/v2/agents/list/{chainId}": {
+ "get": {
+ "summary": "List active agents competing in the auction for a chain",
+ "description": "Use the names returned here to filter pricing via the `includeAgents` / `excludeAgents` params on `GET /delta/v2/prices`.",
+ "operationId": "deltaV2AgentsList",
+ "parameters": [
+ { "name": "chainId", "in": "path", "required": true, "schema": { "type": "integer", "example": 1 } }
+ ],
+ "responses": {
+ "200": {
+ "description": "Array of agent names.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": { "type": "string" }
+ }
+ }
+ }
+ },
+ "400": { "description": "Unsupported chain" }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Token": {
+ "type": "object",
+ "properties": {
+ "chainId": { "type": "integer" },
+ "address": { "type": "string" }
+ }
+ },
+ "TokenAmount": {
+ "type": "object",
+ "properties": {
+ "token": { "$ref": "#/components/schemas/Token" },
+ "amount": { "type": "string" },
+ "amountUSD": { "type": "string" }
+ }
+ },
+ "RouteStep": {
+ "type": "object",
+ "properties": {
+ "input": { "$ref": "#/components/schemas/TokenAmount" },
+ "output": { "$ref": "#/components/schemas/TokenAmount" }
+ }
+ },
+ "RouteBridge": {
+ "type": "object",
+ "nullable": true,
+ "properties": {
+ "protocol": { "type": "string" },
+ "estimatedTimeMs": { "type": "integer" },
+ "tags": { "type": "array", "items": { "type": "string", "enum": ["recommended", "fastest", "best-return"] } },
+ "contractParams": {
+ "type": "object",
+ "properties": {
+ "protocolSelector": { "type": "string" },
+ "outputToken": { "type": "string" },
+ "scalingFactor": { "type": "integer" },
+ "protocolData": { "type": "string" }
+ }
+ }
+ }
+ },
+ "Route": {
+ "type": "object",
+ "properties": {
+ "origin": { "$ref": "#/components/schemas/RouteStep" },
+ "destination": { "$ref": "#/components/schemas/RouteStep" },
+ "bridge": { "$ref": "#/components/schemas/RouteBridge" },
+ "fees": {
+ "type": "object",
+ "properties": {
+ "gas": { "$ref": "#/components/schemas/TokenAmount" },
+ "bridge": { "type": "array", "items": { "$ref": "#/components/schemas/TokenAmount" } }
+ }
+ }
+ }
+ },
+ "PriceV2": {
+ "type": "object",
+ "properties": {
+ "id": { "type": "string", "description": "Request id (echo for support tickets)." },
+ "side": { "type": "string", "enum": ["SELL", "BUY"] },
+ "inputToken": { "$ref": "#/components/schemas/Token" },
+ "outputToken": { "$ref": "#/components/schemas/Token" },
+ "route": { "$ref": "#/components/schemas/Route" },
+ "alternatives": { "type": "array", "items": { "$ref": "#/components/schemas/Route" }, "description": "Up to N additional routes (crosschain only)." },
+ "partner": {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "feePercent": { "type": "number", "description": "Resolved partner fee in percent (0.05 = 0.05%)." }
+ }
+ },
+ "spender": { "type": "string", "description": "Delta contract address; approve this as ERC-20 spender." }
+ }
+ },
+ "BuildOrderV2Request": {
+ "type": "object",
+ "required": ["route", "owner"],
+ "properties": {
+ "side": { "type": "string", "enum": ["SELL", "BUY"], "default": "SELL" },
+ "route": { "$ref": "#/components/schemas/Route", "description": "Pass the unmodified `route` from `GET /delta/v2/prices`. The chain ID is derived from the route." },
+ "owner": { "type": "string" },
+ "beneficiary": { "type": "string", "description": "Defaults to `owner`." },
+ "deadline": { "type": "integer", "description": "Unix seconds. Defaults to now + 1 hour." },
+ "nonce": { "type": "string" },
+ "permit": { "type": "string", "description": "Permit / Permit2 payload, or `0x` if approved on-chain." },
+ "slippage": { "type": "integer", "minimum": 0, "maximum": 10000, "default": 100, "description": "Slippage in basis points." },
+ "limitAmount": { "type": "string", "description": "Override the SDK-computed destAmount (SELL) / srcAmount (BUY)." },
+ "metadata": { "type": "string", "default": "0x" },
+ "partiallyFillable": { "type": "boolean", "default": false },
+ "partnerAddress": { "type": "string", "description": "Defaults to zero address." },
+ "partnerFeeBps": { "type": "integer", "minimum": 0, "maximum": 200, "default": 0 },
+ "partnerTakesSurplus": { "type": "boolean", "default": false },
+ "capSurplus": { "type": "boolean", "default": true },
+ "orderType": { "type": "string", "enum": ["Order", "ProductiveOrder", "ExternalOrder", "TWAPOrder", "TWAPBuyOrder"], "default": "Order" },
+ "handler": { "type": "string", "description": "Required for `ExternalOrder`." },
+ "data": { "type": "string", "description": "Required for `ExternalOrder`. Handler-specific encoded bytes." },
+ "strategy": { "type": "string", "description": "Required for `ProductiveOrder`." },
+ "useShares": { "type": "boolean", "default": true },
+ "interval": { "type": "integer", "minimum": 60, "description": "Required for TWAP. Slice interval in seconds." },
+ "numSlices": { "type": "integer", "minimum": 2, "description": "Required for TWAP." },
+ "totalSrcAmount": { "type": "string", "description": "Required for `TWAPOrder`. `route.origin.input.amount` must equal `floor(totalSrcAmount / numSlices)`." },
+ "totalDestAmount": { "type": "string", "description": "Required for `TWAPBuyOrder`. `route.origin.output.amount` must equal `floor(totalDestAmount / numSlices)`." },
+ "maxSrcAmount": { "type": "string", "description": "Required for `TWAPBuyOrder`. Maximum total source the user is willing to spend." }
+ }
+ },
+ "BuiltOrderV2": {
+ "type": "object",
+ "properties": {
+ "toSign": {
+ "type": "object",
+ "properties": {
+ "domain": {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "version": { "type": "string" },
+ "chainId": { "type": "integer" },
+ "verifyingContract": { "type": "string" }
+ }
+ },
+ "types": { "type": "object", "description": "EIP-712 typed-data field definitions." },
+ "value": { "type": "object", "description": "The on-chain Order struct values, ready to be signed and submitted." }
+ }
+ },
+ "orderHash": { "type": "string", "description": "EIP-712 hash. Use for status lookup before the order id is assigned." }
+ }
+ },
+ "SubmitOrderV2Request": {
+ "type": "object",
+ "required": ["chainId", "order", "signature", "partner"],
+ "properties": {
+ "chainId": { "type": "integer" },
+ "order": { "type": "object", "description": "The `toSign.value` returned by `POST /delta/v2/orders/build`, sent verbatim." },
+ "signature": { "type": "string", "description": "EIP-712 signature over `order`." },
+ "type": { "type": "string", "enum": ["MARKET", "LIMIT"], "default": "MARKET" },
+ "partner": { "type": "string", "example": "my-app-name" },
+ "referrerAddress": { "type": "string" },
+ "partiallyFillable": { "type": "boolean", "default": false },
+ "includeAgents": { "type": "array", "items": { "type": "string" } },
+ "excludeAgents": { "type": "array", "items": { "type": "string" } }
+ }
+ },
+ "DeltaAuction": {
+ "type": "object",
+ "description": "V2 order shape returned by every order endpoint (reads and posts). `input` and `output` carry the *expected* + *executed* amounts so you don't need to compute fill-percent yourself. `onChainOrderType` selects the family the `order` struct belongs to.",
+ "properties": {
+ "id": { "type": "string", "format": "uuid" },
+ "status": { "type": "string", "enum": ["PENDING", "AWAITING_SIGNATURE", "ACTIVE", "SUSPENDED", "CANCELLING", "BRIDGING", "COMPLETED", "FAILED", "EXPIRED", "CANCELLED", "REFUNDED"] },
+ "side": { "type": "string", "enum": ["SELL", "BUY"] },
+ "type": { "type": "string", "enum": ["MARKET", "LIMIT"] },
+ "onChainOrderType": { "type": "string", "enum": ["Order", "FillableOrder", "ProductiveOrder", "ExternalOrder", "TWAPOrder", "TWAPBuyOrder"] },
+ "input": {
+ "type": "object",
+ "description": "Source-side token movement. SELL: `{ chainId, token, amount }`. BUY: `{ chainId, token, expectedAmount, executedAmount }`.",
+ "properties": {
+ "chainId": { "type": "integer" },
+ "token": { "type": "string" },
+ "amount": { "type": "string" },
+ "expectedAmount": { "type": "string", "nullable": true },
+ "executedAmount": { "type": "string", "nullable": true }
+ }
+ },
+ "output": {
+ "type": "object",
+ "description": "Destination-side token movement. SELL: `{ chainId, token, expectedAmount, executedAmount }`. BUY: `{ chainId, token, amount }`.",
+ "properties": {
+ "chainId": { "type": "integer" },
+ "token": { "type": "string" },
+ "amount": { "type": "string" },
+ "expectedAmount": { "type": "string", "nullable": true },
+ "executedAmount": { "type": "string", "nullable": true }
+ }
+ },
+ "owner": { "type": "string" },
+ "beneficiary": { "type": "string" },
+ "orderHash": { "type": "string" },
+ "partner": { "type": "string" },
+ "order": { "type": "object", "description": "The signed on-chain Order struct." },
+ "transactions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "originTx": { "type": "string" },
+ "destinationTx": { "type": "string", "nullable": true, "description": "Set for crosschain orders once the fill lands on `destChainId`." },
+ "filledPercent": { "type": "number", "description": "0–100." },
+ "spentAmount": { "type": "string", "nullable": true },
+ "receivedAmount": { "type": "string", "nullable": true }
+ }
+ }
+ },
+ "createdAt": { "type": "string", "format": "date-time" },
+ "updatedAt": { "type": "string", "format": "date-time" },
+ "expiresAt": { "type": "string", "format": "date-time" }
+ }
+ }
+ }
+ }
+}
diff --git a/api-reference/specs/delta.json b/api-reference/specs/delta.json
index 815720e..f1ee8c1 100644
--- a/api-reference/specs/delta.json
+++ b/api-reference/specs/delta.json
@@ -1,65 +1,475 @@
{
"openapi": "3.0.3",
"info": {
- "title": "Velora Delta API",
+ "title": "Velora Delta API V1",
"version": "1.0.0",
- "description": "Velora Delta API — intent-based quoting with optional Market fallback."
- },
- "servers": [
- { "url": "https://api.velora.xyz", "description": "Production" }
- ],
- "externalDocs": {
- "description": "Delta — how it works (quote → build → sign → submit → poll).",
- "url": "https://new-docs.velora.xyz/delta/how-it-works"
+ "description": "Velora Delta API V1 — intent-based quoting and order lifecycle. Local EIP-712 order building; flat order list; supports the same on-chain contracts as V2."
},
+ "servers": [{ "url": "https://api.velora.xyz", "description": "Production" }],
"paths": {
"/quote": {
"get": {
"summary": "Retrieve a Delta price, with optional fallback to Market",
"operationId": "deltaQuote",
"parameters": [
- { "name": "srcToken", "in": "query", "required": true, "schema": { "$ref": "#/components/schemas/Address" }, "example": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "description": "Source token address. Example uses ETH." },
- { "name": "srcDecimals", "in": "query", "required": true, "schema": { "type": "integer" }, "example": 18, "description": "Source token decimals." },
- { "name": "destToken", "in": "query", "required": true, "schema": { "$ref": "#/components/schemas/Address" }, "example": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "description": "Destination token address. For cross-chain quotes, the destination token on the destination chain. Example uses USDC." },
- { "name": "destDecimals", "in": "query", "required": true, "schema": { "type": "integer" }, "example": 6, "description": "Destination token decimals." },
- { "name": "amount", "in": "query", "required": true, "schema": { "$ref": "#/components/schemas/TokenAmount" }, "example": "1000000000000000000", "description": "srcToken amount (SELL) or destToken amount (BUY), in WEI/raw units." },
- { "name": "side", "in": "query", "required": false, "schema": { "type": "string", "enum": ["SELL", "BUY"], "default": "SELL" } },
- { "name": "chainId", "in": "query", "required": true, "schema": { "$ref": "#/components/schemas/ChainId" }, "example": 1, "description": "Source chain ID. Supported values: 1 (Mainnet), 10 (Optimism), 56 (BSC), 137 (Polygon), 8453 (Base), 42161 (Arbitrum), 43114 (Avalanche), 100 (Gnosis)." },
- { "name": "mode", "in": "query", "required": false, "schema": { "type": "string", "enum": ["ALL", "DELTA", "MARKET"], "default": "ALL" }, "description": "Controls which execution path Velora returns. `ALL` (default) lets Velora pick the winner server-side and returns exactly one of a `delta` or `market` block — never both. `DELTA` / `MARKET` request a specific path; if no route exists for the requested mode, the API may return the other path's block as fallback. See /integrate/trading-modes for full semantics including the 400 PricingError fallback envelope." },
- { "name": "userAddress", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/Address" }, "example": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "description": "End-user wallet address." },
- { "name": "partner", "in": "query", "required": false, "schema": { "type": "string", "default": "anon" }, "example": "my-app-name", "description": "Partner string. Defaults to `anon` which charges 1bps fee for all swaps." },
- { "name": "destChainId", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/ChainId" }, "description": "Destination chain ID for cross-chain quotes. Omit for same-chain quotes." }
+ {
+ "name": "srcToken",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "example": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
+ },
+ "description": "Source token address. Example uses ETH."
+ },
+ {
+ "name": "srcDecimals",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "integer", "example": 18 },
+ "description": "Source token decimals."
+ },
+ {
+ "name": "destToken",
+ "in": "query",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "example": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
+ },
+ "description": "Destination token address. For cross-chain quotes, the destination token on the destination chain. Example uses USDC."
+ },
+ {
+ "name": "destDecimals",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "integer", "example": 6 },
+ "description": "Destination token decimals."
+ },
+ {
+ "name": "amount",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "string", "example": "1000000000000000000" },
+ "description": "srcToken amount (SELL) or destToken amount (BUY), in WEI/raw units."
+ },
+ {
+ "name": "side",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "enum": ["SELL", "BUY"],
+ "default": "SELL"
+ }
+ },
+ {
+ "name": "chainId",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "integer", "example": 1 },
+ "description": "Source chain ID. Supported values: 1 (Mainnet), 10 (Optimism), 56 (BSC), 137 (Polygon), 8453 (Base), 42161 (Arbitrum), 43114 (Avalanche), 100 (Gnosis)."
+ },
+ {
+ "name": "mode",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "enum": ["ALL", "DELTA", "MARKET"],
+ "default": "ALL"
+ },
+ "description": "Controls which execution path Velora returns. `ALL` (default) lets Velora pick the winner server-side and returns exactly one of a `delta` or `market` block — never both. `DELTA` / `MARKET` request a specific path; if no route exists for the requested mode, the API may return the other path's block as fallback. See /integrate/trading-modes for full semantics including the 400 PricingError fallback envelope."
+ },
+ {
+ "name": "userAddress",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "example": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
+ },
+ "description": "End-user wallet address."
+ },
+ {
+ "name": "partner",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "default": "anon",
+ "example": "my-app-name"
+ },
+ "description": "Partner string. Defaults to `anon` which charges 1bps fee for all swaps."
+ },
+ {
+ "name": "destChainId",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "integer" },
+ "description": "Destination chain ID for cross-chain quotes. Omit for same-chain quotes."
+ }
],
"responses": {
"200": {
"description": "Delta quote, optionally with a Market block depending on `mode`.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/DeltaQuoteResponse" }
+ "schema": {
+ "type": "object",
+ "properties": {
+ "delta": {
+ "$ref": "#/components/schemas/DeltaPriceWithHmac"
+ },
+ "market": {
+ "type": "object",
+ "description": "Market route block. Same shape as the GET /prices `priceRoute` field. Present when `mode` is ALL or MARKET."
+ },
+ "deltaAddress": {
+ "type": "string",
+ "description": "The Delta settlement contract address for the source chain."
+ },
+ "fallbackReason": {
+ "type": "object",
+ "description": "Set when Delta couldn't price and the response fell back to Market.",
+ "properties": {
+ "errorType": { "type": "string" },
+ "details": { "type": "string" }
+ }
+ }
+ }
+ }
}
}
},
- "400": {
- "description": "Invalid parameters. Documented examples: `InvalidInput`, `PricingError` (no route for requested mode — see /integrate/trading-modes).",
+ "400": { "description": "Invalid parameters" },
+ "422": { "description": "Unsupported chain or token" }
+ }
+ }
+ },
+ "/delta/prices": {
+ "get": {
+ "summary": "Get a Delta V1 price (same-chain or crosschain)",
+ "description": "Returns a single best route plus the Delta contract address. Same-chain quotes set `bridge` to the all-zero `DEFAULT_BRIDGE`; crosschain quotes populate `bridge` and add `bridgeInfo` / `availableBridges`.",
+ "operationId": "deltaPrices",
+ "parameters": [
+ {
+ "name": "chainId",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "integer", "example": 1 }
+ },
+ {
+ "name": "srcToken",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "destToken",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "string" },
+ "description": "Destination token. For crosschain quotes, the destination token on `destChainId`."
+ },
+ {
+ "name": "amount",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "srcDecimals",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "integer" }
+ },
+ {
+ "name": "destDecimals",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "integer" }
+ },
+ {
+ "name": "side",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "enum": ["SELL", "BUY"],
+ "default": "SELL"
+ }
+ },
+ {
+ "name": "destChainId",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "integer" }
+ },
+ {
+ "name": "userAddress",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "beneficiary",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "partner",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "default": "anon",
+ "example": "my-app-name"
+ }
+ },
+ {
+ "name": "partnerFeeBps",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "integer", "minimum": 0, "maximum": 200 }
+ },
+ {
+ "name": "maxImpact",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "number" }
+ },
+ {
+ "name": "maxUSDImpact",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "number" }
+ },
+ {
+ "name": "includeAgents",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "excludeAgents",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "includeBridges",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "excludeBridges",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "allowBridgeAndSwap",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "boolean", "default": true }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Delta price envelope. The `price.hmac` must be passed verbatim to `POST /delta/orders/build`.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "type": "object",
+ "properties": {
+ "price": {
+ "$ref": "#/components/schemas/DeltaPriceWithHmac"
+ },
+ "deltaAddress": { "type": "string" }
+ }
+ }
}
}
},
- "422": {
- "description": "Unsupported chain or token.",
+ "400": { "description": "Invalid parameters or no route" },
+ "422": { "description": "Unsupported chain or token" }
+ }
+ }
+ },
+ "/delta/prices/is-token-supported": {
+ "get": {
+ "summary": "Check whether a token is supported for Delta on a chain",
+ "operationId": "deltaIsTokenSupported",
+ "parameters": [
+ {
+ "name": "chainId",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "integer", "example": 1 }
+ },
+ {
+ "name": "token",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "string" }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Token support flag.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "type": "object",
+ "properties": { "supported": { "type": "boolean" } }
+ }
}
}
+ }
+ }
+ }
+ },
+ "/delta/prices/bridge-info": {
+ "get": {
+ "summary": "List the crosschain (srcChainId, destChainId, tokens) lanes",
+ "description": "Returns a nested map of supported bridge lanes. Useful for building a 'supported chains' picker before quoting.",
+ "operationId": "deltaBridgeInfo",
+ "parameters": [
+ {
+ "name": "bridges",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string" },
+ "description": "Comma-separated bridge protocol names. Omit for every active bridge."
},
- "500": {
- "description": "Internal server error.",
+ {
+ "name": "allowBridgeAndSwap",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "boolean", "default": true }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Supported lanes grouped by source then destination chain.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "type": "object",
+ "properties": {
+ "supportedTokens": {
+ "type": "object",
+ "description": "`Record>`. Token addresses are on the source chain.",
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": { "type": "string" }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/delta/prices/bridge-protocols": {
+ "get": {
+ "summary": "List active bridge protocols",
+ "description": "Display catalogue of every bridge protocol active in the relayer's `BridgeApi`. Use the `protocol` slug for `includeBridges` / `excludeBridges` filters.",
+ "operationId": "deltaBridgeProtocols",
+ "responses": {
+ "200": {
+ "description": "Active bridge protocols.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "bridgeProtocols": {
+ "type": "array",
+ "items": { "$ref": "#/components/schemas/BridgeProtocol" }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/delta/prices/strategies/{chainId}": {
+ "get": {
+ "summary": "List Delta yield strategies (with APR) for a chain",
+ "description": "Returns the Delta-token vaults wired for Productive orders, keyed by underlying token address. APRs are refreshed server-side every 3 hours; `apr` is `null` when the strategy is too new to compute.",
+ "operationId": "deltaStrategies",
+ "parameters": [
+ {
+ "name": "chainId",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "integer", "example": 1 }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Map of `underlyingTokenAddress → { address, strategies }`.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/DeltaTokenWithStrategies"
+ }
+ }
+ }
+ }
+ },
+ "400": { "description": "Unsupported chain" }
+ }
+ }
+ },
+ "/prices/partnerfee/{chainId}": {
+ "get": {
+ "summary": "Resolve the registered partner-fee config",
+ "description": "Returns the partner-fee config registered against a partner key. Shared between Market and Delta — the same key drives fees on both flows.",
+ "operationId": "deltaPartnerFee",
+ "parameters": [
+ {
+ "name": "chainId",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "integer", "example": 1 }
+ },
+ {
+ "name": "partner",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "string", "example": "my-app-name" }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Resolved partner-fee config.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "partnerFee": {
+ "type": "number",
+ "description": "Fee in percent (e.g. `0.12` = 0.12%)."
+ },
+ "partnerAddress": { "type": "string" },
+ "takeSurplus": { "type": "boolean" }
+ }
+ }
}
}
}
@@ -68,278 +478,684 @@
},
"/delta/orders/build": {
"post": {
- "summary": "Build a signable Delta order from a quote",
+ "summary": "Build a signable Delta V1 order from a quote",
+ "description": "Compose EIP-712 typed data from a `/delta/prices` (or `/quote`) response. Pass the `delta` block verbatim as `price` along with its `hmac`.",
"operationId": "deltaOrdersBuild",
"requestBody": {
"required": true,
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/DeltaOrderBuildRequest" }
+ "schema": {
+ "type": "object",
+ "required": ["chainId", "owner", "price"],
+ "properties": {
+ "chainId": { "type": "integer" },
+ "owner": { "type": "string" },
+ "beneficiary": {
+ "type": "string",
+ "description": "Defaults to `owner`."
+ },
+ "side": {
+ "type": "string",
+ "enum": ["SELL", "BUY"],
+ "default": "SELL"
+ },
+ "onChainOrderType": {
+ "type": "string",
+ "enum": [
+ "Order",
+ "ProductiveOrder",
+ "ExternalOrder",
+ "TWAPOrder",
+ "TWAPBuyOrder"
+ ],
+ "default": "Order"
+ },
+ "price": {
+ "$ref": "#/components/schemas/DeltaPriceWithHmac"
+ },
+ "deadline": {
+ "type": "integer",
+ "description": "Unix seconds. Defaults to now + 1 hour."
+ },
+ "nonce": { "type": "string" },
+ "permit": {
+ "type": "string",
+ "description": "Permit / Permit2 payload, or `0x` if approved on-chain."
+ },
+ "slippage": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 10000,
+ "default": 100,
+ "description": "Slippage in basis points."
+ },
+ "partiallyFillable": { "type": "boolean", "default": false },
+ "partnerAddress": { "type": "string" },
+ "partnerFeeBps": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200,
+ "default": 0
+ },
+ "partnerTakesSurplus": {
+ "type": "boolean",
+ "default": false
+ },
+ "capSurplus": { "type": "boolean", "default": true },
+ "metadata": { "type": "string" },
+ "handler": {
+ "type": "string",
+ "description": "Required for `ExternalOrder`."
+ },
+ "data": {
+ "type": "string",
+ "description": "Required for `ExternalOrder`."
+ },
+ "strategy": {
+ "type": "string",
+ "description": "Required for `ProductiveOrder`."
+ },
+ "useShares": { "type": "boolean", "default": true },
+ "interval": {
+ "type": "integer",
+ "minimum": 60,
+ "description": "TWAP slice interval in seconds."
+ },
+ "numSlices": {
+ "type": "integer",
+ "minimum": 2,
+ "description": "TWAP slice count."
+ },
+ "totalSrcAmount": {
+ "type": "string",
+ "description": "Required for `TWAPOrder`."
+ },
+ "totalDestAmount": {
+ "type": "string",
+ "description": "Required for `TWAPBuyOrder`."
+ },
+ "maxSrcAmount": {
+ "type": "string",
+ "description": "Required for `TWAPBuyOrder`."
+ }
+ }
+ }
}
}
},
"responses": {
"200": {
- "description": "Order with EIP-712 typed data ready to sign.",
+ "description": "EIP-712 typed data ready to sign.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/DeltaOrderBuildResponse" }
+ "schema": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "object",
+ "description": "On-chain `Order` struct values, ready to be signed and submitted."
+ },
+ "orderHash": { "type": "string" },
+ "domain": {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string", "example": "Portikus" },
+ "version": { "type": "string", "example": "2.0.0" },
+ "chainId": { "type": "integer" },
+ "verifyingContract": { "type": "string" }
+ }
+ },
+ "types": { "type": "object" }
+ }
+ }
}
}
},
- "400": {
- "description": "Invalid input or stale price. Documented examples: `InvalidInput`, `StalePriceRoute`.",
+ "400": { "description": "Invalid input or stale price" }
+ }
+ }
+ },
+ "/delta/orders": {
+ "post": {
+ "summary": "Submit a signed Delta V1 order",
+ "operationId": "deltaOrdersSubmit",
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": ["chainId", "order", "signature", "partner"],
+ "properties": {
+ "chainId": { "type": "integer" },
+ "order": {
+ "type": "object",
+ "description": "The `data` returned by `POST /delta/orders/build`, sent verbatim."
+ },
+ "signature": {
+ "type": "string",
+ "description": "EIP-712 signature over `order`."
+ },
+ "type": {
+ "type": "string",
+ "enum": ["MARKET", "LIMIT"],
+ "default": "MARKET"
+ },
+ "partner": { "type": "string", "example": "my-app-name" },
+ "referrerAddress": { "type": "string" },
+ "partiallyFillable": { "type": "boolean", "default": false },
+ "includeAgents": {
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "excludeAgents": {
+ "type": "array",
+ "items": { "type": "string" }
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Order accepted.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": { "$ref": "#/components/schemas/DeltaAuction" }
}
}
},
- "500": {
- "description": "Internal server error.",
+ "400": { "description": "Invalid signature or order shape" }
+ }
+ },
+ "get": {
+ "summary": "List a user's Delta V1 orders (flat array)",
+ "description": "Returns a flat array of orders. V1 paginates by `page` + `limit` but does NOT wrap the response in an envelope — use the array length as a soft total. For a paginated envelope, see [Delta V2 → List orders](/api-reference/delta-v2/orders-list).",
+ "operationId": "deltaOrdersList",
+ "parameters": [
+ {
+ "name": "userAddress",
+ "in": "query",
+ "required": true,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "page",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "integer", "minimum": 1, "default": 1 }
+ },
+ {
+ "name": "limit",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 1000,
+ "default": 100
+ }
+ },
+ {
+ "name": "chainId",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "type",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string", "enum": ["MARKET", "LIMIT"] }
+ },
+ {
+ "name": "status",
+ "in": "query",
+ "required": false,
+ "schema": { "type": "string" },
+ "description": "Comma-separated `DeltaAuctionStatus` values: `NOT_STARTED`, `AWAITING_PRE_SIGNATURE`, `RUNNING`, `EXECUTING`, `EXECUTED`, `FAILED`, `EXPIRED`, `CANCELLED`, `CANCELLING`, `SUSPENDED`, `REFUNDED`."
+ },
+ {
+ "name": "onChainOrderType",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "string",
+ "enum": ["Order", "ProductiveOrder", "ExternalOrder"]
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Flat array of orders.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "type": "array",
+ "items": { "$ref": "#/components/schemas/DeltaAuction" }
+ }
}
}
}
}
}
},
- "/delta/orders": {
+ "/delta/orders/cancel": {
"post": {
- "summary": "Submit a signed Delta order",
- "operationId": "deltaOrdersSubmit",
+ "summary": "Cancel one or more Delta V1 orders",
+ "description": "Sign-and-post cancellation. Only succeeds for orders still open in the auction.",
+ "operationId": "deltaOrdersCancel",
"requestBody": {
"required": true,
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/DeltaOrderSubmitRequest" }
+ "schema": {
+ "type": "object",
+ "required": ["orderIds", "signature"],
+ "properties": {
+ "orderIds": {
+ "type": "array",
+ "items": { "type": "string", "format": "uuid" },
+ "minItems": 1,
+ "maxItems": 100
+ },
+ "signature": { "type": "string" }
+ }
+ }
}
}
},
"responses": {
"200": {
- "description": "Order accepted; returns order id and status URL.",
+ "description": "Cancellation accepted.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "cancelled": {
+ "type": "array",
+ "items": { "type": "string", "format": "uuid" }
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": { "description": "Invalid signature or order already settled" }
+ }
+ }
+ },
+ "/delta/orders/{orderId}": {
+ "get": {
+ "summary": "Get a Delta V1 order by ID",
+ "operationId": "deltaOrderById",
+ "parameters": [
+ {
+ "name": "orderId",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "string", "format": "uuid" }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Order details.",
+ "content": {
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/DeltaAuction" }
+ }
+ }
+ },
+ "404": { "description": "Order not found" }
+ }
+ }
+ },
+ "/delta/orders/hash/{hash}": {
+ "get": {
+ "summary": "Get a Delta V1 order by EIP-712 hash",
+ "operationId": "deltaOrderByHash",
+ "parameters": [
+ {
+ "name": "hash",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "string" }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Order details.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/DeltaOrderSubmitResponse" }
+ "schema": { "$ref": "#/components/schemas/DeltaAuction" }
}
}
},
- "400": {
- "description": "Invalid signature or order shape. Documented examples: `InvalidSignature`, `InvalidInput`.",
+ "404": { "description": "Order not found" }
+ }
+ }
+ },
+ "/delta/orders/fillablebalance/{chainId}/{userAddress}/{tokenAddress}": {
+ "get": {
+ "summary": "Compute a user's fillable balance for limit orders",
+ "description": "Returns the user's wallet balance **minus** any source-token amounts already committed to open limit orders.\n\n`tokenAddress` is an optional trailing path segment — omit it (`/delta/orders/fillablebalance/{chainId}/{userAddress}`) to get balances for every committed token.",
+ "operationId": "deltaFillableBalance",
+ "parameters": [
+ {
+ "name": "chainId",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "integer", "example": 1 }
+ },
+ {
+ "name": "userAddress",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "string" }
+ },
+ {
+ "name": "tokenAddress",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "string" }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Map of `tokenAddress → fillableBalance`.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "type": "object",
+ "additionalProperties": { "type": "string" }
+ }
}
}
+ }
+ }
+ }
+ },
+ "/delta/orders/orderbook/{chainId}/{agent}": {
+ "get": {
+ "summary": "Get pending orders for a specific agent (agent operators only)",
+ "description": "Returns the orderbook slice the auction would feed to one agent for a given chain. **Not intended for end-user integrations** — used by agent operators to introspect their fill queue.",
+ "operationId": "deltaOrderbook",
+ "parameters": [
+ {
+ "name": "chainId",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "integer" }
},
- "500": {
- "description": "Internal server error.",
+ {
+ "name": "agent",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "string" },
+ "description": "Agent name from `GET /delta/agents/list/{chainId}`."
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Pending-order slice.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "type": "array",
+ "items": { "$ref": "#/components/schemas/DeltaAuction" }
+ }
}
}
}
}
}
+ },
+ "/delta/agents/list/{chainId}": {
+ "get": {
+ "summary": "List active agents competing in the auction for a chain",
+ "operationId": "deltaAgentsList",
+ "parameters": [
+ {
+ "name": "chainId",
+ "in": "path",
+ "required": true,
+ "schema": { "type": "integer", "example": 1 }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Array of agent names.",
+ "content": {
+ "application/json": {
+ "schema": { "type": "array", "items": { "type": "string" } }
+ }
+ }
+ },
+ "400": { "description": "Unsupported chain" }
+ }
+ }
}
},
"components": {
"schemas": {
- "Address": {
- "type": "string",
- "description": "EVM address (20 bytes, hex-encoded with `0x` prefix). Use the mixed-case placeholder `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native ETH.",
- "pattern": "^0x[a-fA-F0-9]{40}$",
- "example": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
- },
- "ChainId": {
- "type": "integer",
- "description": "EVM chain ID. Supported values today include 1 (Mainnet), 10 (Optimism), 56 (BSC), 137 (Polygon), 8453 (Base), 42161 (Arbitrum), 43114 (Avalanche), 100 (Gnosis). The set is open — call GET /chains for the live list.",
- "example": 1
- },
- "TokenAmount": {
- "type": "string",
- "description": "Token amount in WEI / raw units (no decimal point). Serialized as a string to preserve precision for amounts that exceed JavaScript Number range.",
- "example": "1000000000000000000"
- },
- "ErrorCode": {
- "type": "string",
- "description": "Documented Velora error code (e.g. `PricingError`, `InvalidInput`, `UnsupportedChain`, `StalePriceRoute`, `InvalidSignature`). The set is open — handle codes you recognize and fall back to a generic error path for everything else. See /api-reference/troubleshooting for known codes.",
- "example": "PricingError"
- },
- "ErrorResponse": {
+ "Bridge": {
"type": "object",
- "description": "Standard Velora error envelope.",
- "required": ["errorType"],
+ "description": "On-chain bridge tuple. For same-chain orders, every field is the all-zero `DEFAULT_BRIDGE`.",
"properties": {
- "errorType": { "$ref": "#/components/schemas/ErrorCode" },
- "details": { "type": "string", "description": "Human-readable description of the failure." }
- },
- "example": {
- "errorType": "PricingError",
- "details": "Error getting price data"
+ "protocolSelector": { "type": "string", "description": "bytes4." },
+ "destinationChainId": {
+ "type": "integer",
+ "description": "uint64. `0` for same-chain."
+ },
+ "outputToken": { "type": "string" },
+ "scalingFactor": { "type": "integer" },
+ "protocolData": { "type": "string" }
}
},
- "Eip712TypedData": {
+ "BridgeInfo": {
"type": "object",
- "description": "EIP-712 typed data ready to sign. See /delta/eip-712-typed-data-reference for the Velora-specific Order primaryType.",
- "required": ["domain", "types", "primaryType", "message"],
"properties": {
- "domain": {
- "type": "object",
- "properties": {
- "name": { "type": "string", "example": "Velora Delta" },
- "version": { "type": "string", "example": "1.0" },
- "chainId": { "$ref": "#/components/schemas/ChainId" },
- "verifyingContract": { "$ref": "#/components/schemas/Address" }
- }
- },
- "types": {
- "type": "object",
- "description": "Type definitions keyed by struct name. Each value is an array of `{ name, type }` fields.",
- "additionalProperties": {
- "type": "array",
- "items": {
- "type": "object",
- "required": ["name", "type"],
- "properties": {
- "name": { "type": "string" },
- "type": { "type": "string" }
- }
- }
- }
- },
- "primaryType": { "type": "string", "example": "Order" },
- "message": {
- "type": "object",
- "description": "Order field values matching the `primaryType` struct."
- }
+ "protocolName": { "type": "string" },
+ "destAmountAfterBridge": { "type": "string" },
+ "destUSDAfterBridge": { "type": "string" },
+ "estimatedTimeMs": { "type": "integer" },
+ "fees": { "type": "array", "items": { "type": "object" } }
}
},
- "MarketPriceRoute": {
+ "BridgeProtocol": {
"type": "object",
- "description": "Market route block. Calldata-ready against Augustus v6.2 when `version=6.2`. Same shape as the `priceRoute` field returned by GET /prices on the Market API.",
"properties": {
- "blockNumber": { "type": "integer" },
- "network": { "$ref": "#/components/schemas/ChainId" },
- "srcToken": { "$ref": "#/components/schemas/Address" },
- "srcDecimals": { "type": "integer" },
- "srcAmount": { "$ref": "#/components/schemas/TokenAmount" },
- "destToken": { "$ref": "#/components/schemas/Address" },
- "destDecimals": { "type": "integer" },
- "destAmount": { "$ref": "#/components/schemas/TokenAmount" },
- "bestRoute": { "type": "array", "items": { "type": "object" } },
- "gasCostUSD": { "type": "string" },
- "gasCost": { "type": "string" },
- "side": { "type": "string", "enum": ["SELL", "BUY"] },
- "version": { "type": "string" },
- "contractAddress": { "$ref": "#/components/schemas/Address" },
- "tokenTransferProxy": { "$ref": "#/components/schemas/Address" },
- "contractMethod": { "type": "string" },
- "partnerFee": { "type": "number" },
- "srcUSD": { "type": "string" },
- "destUSD": { "type": "string" },
- "partner": { "type": "string" },
- "maxImpactReached": { "type": "boolean" },
- "hmac": { "type": "string" }
+ "protocol": {
+ "type": "string",
+ "description": "Stable slug used in `includeBridges` / `excludeBridges`."
+ },
+ "displayName": { "type": "string" },
+ "icon": {
+ "type": "string",
+ "description": "Absolute URL to a 1:1 SVG icon hosted on cdn.velora.xyz."
+ }
}
},
- "DeltaQuote": {
+ "DeltaPriceWithHmac": {
"type": "object",
- "description": "Delta intent block. Sign and submit via POST /delta/orders/build then POST /delta/orders. Pass the block verbatim — including `hmac` — on the build call.",
+ "description": "Flat Delta price object. Same-chain quotes return `DeltaPrice`; crosschain quotes set `bridge` and add `bridgeInfo` and `availableBridges`. Pass this object verbatim (including `hmac`) to `POST /delta/orders/build`.",
"properties": {
- "srcToken": { "$ref": "#/components/schemas/Address" },
- "destToken": { "$ref": "#/components/schemas/Address" },
- "srcAmount": { "$ref": "#/components/schemas/TokenAmount" },
- "destAmount": { "$ref": "#/components/schemas/TokenAmount" },
- "destAmountBeforeFee": { "$ref": "#/components/schemas/TokenAmount" },
- "gasCostUSD": { "type": "string" },
+ "srcToken": { "type": "string" },
+ "destToken": { "type": "string" },
+ "srcAmount": { "type": "string" },
+ "srcAmountBeforeFee": {
+ "type": "string",
+ "description": "BUY side only."
+ },
+ "destAmount": { "type": "string" },
+ "destAmountBeforeFee": {
+ "type": "string",
+ "description": "SELL side only."
+ },
+ "receivedDestAmount": { "type": "string" },
+ "receivedDestUSD": { "type": "string" },
"gasCost": { "type": "string" },
+ "gasCostBeforeFee": { "type": "string" },
+ "gasCostUSD": { "type": "string" },
+ "gasCostUSDBeforeFee": { "type": "string" },
"srcUSD": { "type": "string" },
"destUSD": { "type": "string" },
"destUSDBeforeFee": { "type": "string" },
- "gasCostBeforeFee": { "type": "string" },
- "gasCostUSDBeforeFee": { "type": "string" },
"partner": { "type": "string" },
"partnerFee": { "type": "number" },
- "bridge": {
- "type": "object",
- "properties": {
- "outputToken": { "$ref": "#/components/schemas/Address" },
- "protocolData": { "type": "string" },
- "scalingFactor": { "type": "string" },
- "destinationChainId": { "$ref": "#/components/schemas/ChainId" },
- "protocolSelector": { "type": "string" }
- }
+ "bridge": { "$ref": "#/components/schemas/Bridge" },
+ "bridgeInfo": { "$ref": "#/components/schemas/BridgeInfo" },
+ "availableBridges": {
+ "type": "array",
+ "items": { "type": "object" },
+ "description": "Crosschain only. Each entry mirrors a `BridgePrice` with its own `bridge` + `bridgeInfo`."
},
- "bridgeInfo": {
- "type": "object",
- "properties": {
- "protocolName": { "type": "string" },
- "destAmountAfterBridge": { "$ref": "#/components/schemas/TokenAmount" },
- "destUSDAfterBridge": { "type": "string" },
- "estimatedTimeMs": { "type": "integer" },
- "fees": { "type": "array", "items": { "type": "object" } }
- }
- },
- "availableBridges": { "type": "array", "items": { "type": "object" } },
- "hmac": { "type": "string", "description": "Server-signed integrity envelope; pass back verbatim on POST /delta/orders/build." }
+ "hmac": {
+ "type": "string",
+ "description": "Server-signed integrity tag. Must be passed verbatim to `/delta/orders/build`."
+ }
}
},
- "DeltaQuoteResponse": {
+ "DeltaTokenWithStrategies": {
"type": "object",
- "description": "GET /quote envelope. Under `mode=ALL` Velora returns exactly one of `delta` or `market`; under `mode=DELTA` or `mode=MARKET`, the other block may be present as fallback (see /integrate/trading-modes).",
"properties": {
- "delta": { "$ref": "#/components/schemas/DeltaQuote" },
- "market": { "$ref": "#/components/schemas/MarketPriceRoute" },
- "deltaAddress": {
- "allOf": [{ "$ref": "#/components/schemas/Address" }],
- "description": "The Delta settlement contract address for the source chain."
- },
- "fallbackReason": {
- "allOf": [{ "$ref": "#/components/schemas/ErrorResponse" }],
- "description": "Set when the requested mode couldn't price and the response fell back to the other path. Same shape as a 400 PricingError envelope."
+ "address": {
+ "type": "string",
+ "description": "Delta token (dToken) wrapper address."
+ },
+ "strategies": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "vault": {
+ "type": "string",
+ "description": "ERC-4626 vault address. Pass as `strategy` on Productive order builds."
+ },
+ "name": { "type": "string" },
+ "apr": {
+ "type": "object",
+ "nullable": true,
+ "properties": {
+ "gross": {
+ "type": "string",
+ "description": "Gross APR as a decimal string."
+ },
+ "net": {
+ "type": "string",
+ "description": "Net APR after fees."
+ }
+ }
+ }
+ }
+ }
}
}
},
- "DeltaOrderBuildRequest": {
+ "DeltaAuctionTransaction": {
"type": "object",
- "required": ["price", "hmac"],
+ "description": "On-chain transaction that filled (part of) the order. One entry per fill; multiple entries for `partiallyFillable` orders or per-slice TWAPs.",
"properties": {
- "price": {
- "allOf": [{ "$ref": "#/components/schemas/DeltaQuote" }],
- "description": "The `delta` block returned by GET /quote, passed verbatim — do not recompute or re-encode amounts."
- },
- "hmac": {
+ "id": { "type": "string" },
+ "hash": { "type": "string" },
+ "orderId": { "type": "string" },
+ "bidId": { "type": "string", "nullable": true },
+ "blockNumber": { "type": "integer" },
+ "blockHash": { "type": "string" },
+ "blockTimestamp": {
"type": "string",
- "description": "The `hmac` value from the `delta` block, passed verbatim."
- }
+ "format": "date-time",
+ "nullable": true
+ },
+ "index": { "type": "integer" },
+ "status": { "type": "integer" },
+ "from": { "type": "string" },
+ "to": { "type": "string" },
+ "receivedAmount": { "type": "string" },
+ "receivedAmountUSD": { "type": "number" },
+ "spentAmount": { "type": "string" },
+ "spentAmountUSD": { "type": "number" },
+ "filledPercent": {
+ "type": "integer",
+ "description": "Basis points (10000 = 100%)."
+ },
+ "protocolFee": { "type": "string" },
+ "partnerFee": { "type": "string" },
+ "agent": { "type": "string" },
+ "auctionId": { "type": "string" },
+ "bridgeMetadata": { "type": "object", "nullable": true },
+ "bridgeStatus": { "type": "string", "nullable": true },
+ "bridgeProtocol": { "type": "string", "nullable": true }
}
},
- "DeltaOrderBuildResponse": {
+ "DeltaAuction": {
"type": "object",
- "description": "Order with EIP-712 typed data ready to sign. See /delta/eip-712-typed-data-reference for the Order primaryType shape."
- },
- "DeltaOrderSubmitRequest": {
- "type": "object",
- "required": ["order", "signature"],
+ "description": "V1 order shape returned by every order endpoint. Status uses the legacy `DeltaAuctionStatus` enum; crosschain orders set `bridgeMetadata` and `bridgeStatus`.",
"properties": {
- "order": {
- "type": "object",
- "description": "The order body returned by POST /delta/orders/build."
+ "id": { "type": "string", "format": "uuid" },
+ "deltaVersion": { "type": "string", "description": "`1.0` for V1." },
+ "user": { "type": "string" },
+ "status": {
+ "type": "string",
+ "enum": [
+ "NOT_STARTED",
+ "AWAITING_PRE_SIGNATURE",
+ "RUNNING",
+ "EXECUTING",
+ "EXECUTED",
+ "FAILED",
+ "EXPIRED",
+ "CANCELLED",
+ "CANCELLING",
+ "SUSPENDED",
+ "REFUNDED"
+ ]
},
- "signature": {
+ "orderHash": { "type": "string", "nullable": true },
+ "transactions": {
+ "type": "array",
+ "items": { "$ref": "#/components/schemas/DeltaAuctionTransaction" }
+ },
+ "chainId": { "type": "integer" },
+ "partner": { "type": "string" },
+ "referrerAddress": { "type": "string", "nullable": true },
+ "expiresAt": { "type": "string", "format": "date-time" },
+ "createdAt": { "type": "string", "format": "date-time" },
+ "updatedAt": { "type": "string", "format": "date-time" },
+ "partiallyFillable": { "type": "boolean" },
+ "excludeAgents": {
+ "type": "array",
+ "items": { "type": "string" },
+ "nullable": true
+ },
+ "includeAgents": {
+ "type": "array",
+ "items": { "type": "string" },
+ "nullable": true
+ },
+ "bridgeMetadata": { "type": "object", "nullable": true },
+ "bridgeStatus": { "type": "string", "nullable": true },
+ "type": { "type": "string", "enum": ["MARKET", "LIMIT"] },
+ "onChainOrderType": {
"type": "string",
- "description": "EIP-712 signature of the typed data — hex-encoded with `0x` prefix."
+ "enum": [
+ "Order",
+ "FillableOrder",
+ "ProductiveOrder",
+ "ExternalOrder",
+ "TWAPOrder",
+ "TWAPBuyOrder"
+ ],
+ "description": "`FillableOrder` is what the server reports for a `partiallyFillable` Standard `Order`; the `order` struct shape is identical to `Order`."
+ },
+ "order": {
+ "type": "object",
+ "description": "The signed on-chain Order struct (shape varies by `onChainOrderType`)."
}
}
- },
- "DeltaOrderSubmitResponse": {
- "type": "object",
- "description": "Order acceptance envelope. Returns an order id and status URL."
}
}
}
diff --git a/api-reference/troubleshooting.mdx b/api-reference/troubleshooting.mdx
index 605ea9e..2625e47 100644
--- a/api-reference/troubleshooting.mdx
+++ b/api-reference/troubleshooting.mdx
@@ -17,6 +17,10 @@ import MarketTransactionsFailureModes from "/snippets/failure-modes/market-trans
import DeltaQuoteFailureModes from "/snippets/failure-modes/delta-quote.mdx";
import DeltaOrdersBuildFailureModes from "/snippets/failure-modes/delta-orders-build.mdx";
import DeltaOrdersFailureModes from "/snippets/failure-modes/delta-orders.mdx";
+import DeltaV2PricesFailureModes from "/snippets/failure-modes/delta-v2-prices.mdx";
+import DeltaV2OrdersBuildFailureModes from "/snippets/failure-modes/delta-v2-orders-build.mdx";
+import DeltaV2OrdersSubmitFailureModes from "/snippets/failure-modes/delta-v2-orders-submit.mdx";
+import DeltaV2OrdersCancelFailureModes from "/snippets/failure-modes/delta-v2-orders-cancel.mdx";
Each table covers a single endpoint and is updated from support tickets at each release. Jump straight to the endpoint you're calling.
@@ -34,7 +38,25 @@ Each table covers a single endpoint and is updated from support tickets at each
-## Delta API
+## Delta V2 API
+
+### GET /delta/v2/prices
+
+
+
+### POST /delta/v2/orders/build
+
+
+
+### POST /delta/v2/orders
+
+
+
+### POST /delta/v2/orders/cancel
+
+
+
+## Delta V1 API
### GET /quote
diff --git a/docs.json b/docs.json
index 9f5e2b7..6c468bd 100644
--- a/docs.json
+++ b/docs.json
@@ -86,7 +86,8 @@
"sdk/install",
"sdk/choose-a-variant",
"sdk/simple-sdk",
- "sdk/composable-sdk",
+ "sdk/full-sdk",
+ "sdk/partial-sdk",
{
"group": "Modules",
"pages": [
@@ -261,12 +262,44 @@
]
},
{
- "group": "Delta API",
+ "group": "Delta API V2",
+ "pages": [
+ "api-reference/delta-v2/overview",
+ "api-reference/delta-v2/prices",
+ "api-reference/delta-v2/bridge-routes",
+ "api-reference/delta-v2/bridge-protocols",
+ "api-reference/delta-v2/strategies",
+ "api-reference/delta-v2/is-token-supported",
+ "api-reference/delta-v2/orders-build",
+ "api-reference/delta-v2/orders-submit",
+ "api-reference/delta-v2/orders-cancel",
+ "api-reference/delta-v2/orders-list",
+ "api-reference/delta-v2/orders-get-by-id",
+ "api-reference/delta-v2/orders-get-by-hash",
+ "api-reference/delta-v2/orders-fillable-balance",
+ "api-reference/delta-v2/agents-list"
+ ]
+ },
+ {
+ "group": "Delta API V1",
"pages": [
"api-reference/delta/overview",
"api-reference/delta/quote",
+ "api-reference/delta/prices",
+ "api-reference/delta/bridge-info",
+ "api-reference/delta/bridge-protocols",
+ "api-reference/delta/strategies",
+ "api-reference/delta/is-token-supported",
+ "api-reference/delta/partner-fee",
"api-reference/delta/orders-build",
- "api-reference/delta/orders"
+ "api-reference/delta/orders",
+ "api-reference/delta/orders-cancel",
+ "api-reference/delta/orders-list",
+ "api-reference/delta/orders-get-by-id",
+ "api-reference/delta/orders-get-by-hash",
+ "api-reference/delta/orders-fillable-balance",
+ "api-reference/delta/orderbook",
+ "api-reference/delta/agents-list"
]
},
{
@@ -310,6 +343,7 @@
"group": "Migrations",
"pages": [
"resources/migrations/index",
+ "resources/migrations/delta-v1-to-v2",
"resources/migrations/market-to-delta-parallel",
"resources/migrations/market-to-delta-replace",
"resources/migrations/augustus-v5-to-v6-2",
diff --git a/resources/migrations/delta-v1-to-v2.mdx b/resources/migrations/delta-v1-to-v2.mdx
new file mode 100644
index 0000000..0434c04
--- /dev/null
+++ b/resources/migrations/delta-v1-to-v2.mdx
@@ -0,0 +1,271 @@
+---
+title: "Delta V1 → V2 (HTTP API)"
+description: "Endpoint-by-endpoint migration for direct HTTP integrators. Server-built orders, route-based pricing, paginated history, unified status model."
+keywords: ["migration", "delta", "delta v1", "delta v2", "api"]
+---
+
+This page is for integrators calling the Velora Delta HTTP API directly. If you're on the [Velora SDK](/sdk/modules/delta), the SDK-level migration walks the same path with TypeScript snippets — see [SDK → Migrate from V1 to V2](/sdk/modules/delta#migrate-from-v1-to-v2).
+
+## What breaks if you do nothing
+
+Nothing. Delta V1 (`/delta/*`) remains fully supported and shares on-chain contracts with V2. Your existing integration keeps working as-is.
+
+## Why migrate
+
+V2 keeps the same on-chain settlement model but cleans up the protocol surface:
+
+- **Server-built orders.** `POST /delta/v2/orders/build` returns EIP-712 typed data ready to sign. You stop composing `domain`, `types`, and `value` on the client.
+- **Route-based pricing.** `GET /delta/v2/prices` returns a recommended `route` plus `alternatives` — let users pick a different bridge, and stop juggling the `bridge` / `bridgeInfo` / `availableBridges` triple V1 returns.
+- **Paginated order history.** `GET /delta/v2/orders` returns `{ data, total, page, limit, hasMore }`. V1 returns a flat array with no total.
+- **Unified status model.** Eleven values (`PENDING`, `AWAITING_SIGNATURE`, `ACTIVE`, `SUSPENDED`, `CANCELLING`, `BRIDGING`, `COMPLETED`, `FAILED`, `EXPIRED`, `CANCELLED`, `REFUNDED`) collapse V1's `status` + `bridgeStatus` columns into one.
+- **Server-resolved partner fee.** Pass `partner` / `partnerAddress` / `partnerFeeBps` directly on every call — the server validates and encodes them. No more separate `GET /prices/partnerfee/{chainId}` round-trip.
+- **No more `hmac`.** V2 doesn't sign the price payload, so there's no opaque blob to thread from `/prices` into `/orders/build`.
+
+## Endpoint mapping
+
+| V1 | V2 | Notes |
+|---|---|---|
+| `GET /delta/prices` | [`GET /delta/v2/prices`](/api-reference/delta-v2/prices) | Response carries `route` + `alternatives`; `price.hmac` removed |
+| `GET /delta/prices/bridge-info` | [`GET /delta/v2/prices/bridge-routes`](/api-reference/delta-v2/bridge-routes) | Flat `routes[]` array instead of nested `srcChainId → destChainId → tokens[]` map |
+| `GET /delta/prices/bridge-protocols` | [`GET /delta/v2/prices/bridge-protocols`](/api-reference/delta-v2/bridge-protocols) | Same shape |
+| `GET /delta/prices/strategies/{chainId}` | [`GET /delta/v2/prices/strategies/{chainId}`](/api-reference/delta-v2/strategies) | Same shape |
+| `GET /delta/prices/is-token-supported` | [`GET /delta/v2/prices/is-token-supported`](/api-reference/delta-v2/is-token-supported) | Same shape |
+| `GET /prices/partnerfee/{chainId}` | _Not needed_ | Pass `partner` / `partnerAddress` / `partnerFeeBps` raw on every V2 call |
+| `POST /delta/orders/build` | [`POST /delta/v2/orders/build`](/api-reference/delta-v2/orders-build) | Different body — pass `route` (not `price` + `hmac`); response wraps typed data in `toSign` |
+| `POST /delta/orders` | [`POST /delta/v2/orders`](/api-reference/delta-v2/orders-submit) | Submit `order: built.toSign.value` instead of `data` from V1 build |
+| `POST /delta/orders/cancel` | [`POST /delta/v2/orders/cancel`](/api-reference/delta-v2/orders-cancel) | Same shape |
+| `GET /delta/orders` | [`GET /delta/v2/orders`](/api-reference/delta-v2/orders-list) | Wraps array in `{ data, total, page, limit, hasMore }` |
+| `GET /delta/orders/{orderId}` | [`GET /delta/v2/orders/{orderId}`](/api-reference/delta-v2/orders-get-by-id) | New response shape — `input` / `output` carry expected + executed amounts |
+| `GET /delta/orders/hash/{hash}` | [`GET /delta/v2/orders/hash/{hash}`](/api-reference/delta-v2/orders-get-by-hash) | Same as above |
+| `GET /delta/orders/fillablebalance/...` | [`GET /delta/v2/orders/fillablebalance/...`](/api-reference/delta-v2/orders-fillable-balance) | Same shape |
+| `GET /delta/agents/list/{chainId}` | [`GET /delta/v2/agents/list/{chainId}`](/api-reference/delta-v2/agents-list) | Same shape |
+| `GET /quote` (mode=ALL) | _No V2 equivalent_ | If you rely on the Delta-or-Market fallback, stay on V1 `/quote` |
+
+## Steps
+
+### 1. Pricing
+
+V1 returns a flat price object with a server-signed `hmac`. V2 returns a structured route plus alternatives.
+
+```diff
+- GET /delta/prices?chainId=1&srcToken=0x...&destToken=0x...&amount=...&partner=my-app-name
++ GET /delta/v2/prices?chainId=1&srcToken=0x...&destToken=0x...&amount=...&partner=my-app-name
+```
+
+V1 response:
+
+```json
+{
+ "price": {
+ "srcToken": "0x...", "destToken": "0x...",
+ "srcAmount": "...", "destAmount": "...",
+ "partner": "my-app-name", "partnerFee": 0.05,
+ "bridge": { "destinationChainId": 0, "protocolSelector": "0x00000000", ... },
+ "hmac": "0x..."
+ },
+ "deltaAddress": "0x..."
+}
+```
+
+V2 response:
+
+```json
+{
+ "id": "req_...",
+ "side": "SELL",
+ "inputToken": { "chainId": 1, "address": "0x..." },
+ "outputToken": { "chainId": 1, "address": "0x..." },
+ "route": {
+ "origin": { "input": { ... }, "output": { ... } },
+ "destination": { "input": { ... }, "output": { ... } },
+ "bridge": null,
+ "fees": { "gas": { ... }, "bridge": [] }
+ },
+ "alternatives": [],
+ "partner": { "name": "my-app-name", "feePercent": 0.05 },
+ "spender": "0x..."
+}
+```
+
+Three things to handle:
+
+- **`price.hmac` is gone.** Don't thread it into `/orders/build`.
+- **`deltaAddress` moved to `spender`.** Approve `spender` as the ERC-20 spender (the on-chain Delta contract address — unchanged).
+- **Bridge detection changed.** V1 used `bridge.destinationChainId !== 0`. V2 sets `route.bridge` to `null` for same-chain and populates it for crosschain. Read `route.origin.input.token.chainId` vs `route.destination.output.token.chainId` if you need a direct check.
+
+### 2. Build
+
+V1 takes the price object + hmac. V2 takes the route plus order params on top.
+
+```diff
+ POST /delta/orders/build
+ {
+- "chainId": 1,
+- "owner": "0x...",
+- "price": { /* the full delta price object including hmac */ },
+- "slippage": 100
++ /* request goes to /delta/v2/orders/build instead */
+ }
+
++ POST /delta/v2/orders/build
++ {
++ "owner": "0x...",
++ "route": { /* the route from /delta/v2/prices, verbatim */ },
++ "side": "SELL",
++ "slippage": 100,
++ "partner": "my-app-name",
++ "partnerFeeBps": 25
++ }
+```
+
+> The chain ID is no longer part of the build request — V2 derives it from the `route`.
+
+V1 returned `{ data, orderHash, domain, types }` — `data` was the on-chain Order struct.
+
+V2 returns `{ toSign: { domain, types, value }, orderHash }` — `value` is the on-chain Order struct, wrapped one level deeper.
+
+```diff
+ // V1 response
+- {
+- "data": { /* on-chain Order struct */ },
+- "orderHash": "0x...",
+- "domain": { ... },
+- "types": { ... }
+- }
+
+ // V2 response
++ {
++ "toSign": {
++ "domain": { ... },
++ "types": { ... },
++ "value": { /* on-chain Order struct, same shape as V1's `data` */ }
++ },
++ "orderHash": "0x..."
++ }
+```
+
+### 3. Sign
+
+The EIP-712 domain (`name: "Portikus"`, `version: "2.0.0"`, `chainId`, `verifyingContract`) is **unchanged**. The signature you compute over V2's `toSign` is the same string V1 would produce over its `data`/`domain`/`types` triple.
+
+### 4. Submit
+
+V1 took `{ order, signature, partner, ... }`. V2 is the same shape — only the source of `order` changes.
+
+```diff
+- POST /delta/orders
++ POST /delta/v2/orders
+ {
+ "chainId": 1,
+- "order": /* V1 build response's `data` */,
++ "order": /* V2 build response's `toSign.value` */,
+ "signature": "0x...",
+ "type": "MARKET",
+ "partner": "my-app-name"
+ }
+```
+
+V2 doesn't accept `referrerAddress` differently — same field, same semantics.
+
+### 5. Poll for status
+
+V1 status (`DeltaAuctionStatus`) splits into `status` + `bridgeStatus`. V2 collapses both into one `status` field.
+
+```diff
+- GET /delta/orders/{orderId}
++ GET /delta/v2/orders/{orderId}
+```
+
+Status mapping you'll need on the client when migrating queries:
+
+| V1 (`status` + `bridgeStatus`) | V2 (`status`) |
+|---|---|
+| `NOT_STARTED` | `PENDING` |
+| `AWAITING_PRE_SIGNATURE` | `AWAITING_SIGNATURE` |
+| `RUNNING`, `EXECUTING` | `ACTIVE` |
+| Suspension states (insufficient balance/allowance) | `SUSPENDED` |
+| `CANCELLING` | `CANCELLING` |
+| `EXECUTED` + `bridgeStatus: PENDING` | `BRIDGING` |
+| `EXECUTED` + (same-chain OR `bridgeStatus: FILLED`) | `COMPLETED` |
+| `FAILED`, `INVALIDATED` | `FAILED` |
+| `EXPIRED` (or `bridgeStatus: EXPIRED`) | `EXPIRED` |
+| `CANCELLED` | `CANCELLED` |
+| `REFUNDED` (or `bridgeStatus: REFUNDED`) | `REFUNDED` |
+
+The V2 response also restructures order details: `input` and `output` each carry `{ chainId, token, amount }` (SELL: input has `amount`, output has `expectedAmount` + `executedAmount`; BUY: vice versa). V1 returned `order.srcToken` / `order.destToken` plus a separate `transactions[]` array — V2 keeps both, but the headline numbers move to `input` / `output`.
+
+### 6. List orders
+
+```diff
+- GET /delta/orders?userAddress=0x...&page=1&limit=100
++ GET /delta/v2/orders?userAddress=0x...&page=1&limit=100
+```
+
+V1 returns a plain array; V2 wraps it:
+
+```diff
+- [ { "id": "...", "status": "...", ... }, ... ]
++ {
++ "data": [ { "id": "...", "status": "...", ... }, ... ],
++ "total": 1234,
++ "page": 1,
++ "limit": 100,
++ "hasMore": true
++ }
+```
+
+You now know how many pages remain — useful for "load more" UIs without falling back to "fetch until you get fewer than `limit`".
+
+### 7. Cancel
+
+No semantic change — same path under `/v2`, same request body.
+
+```diff
+- POST /delta/orders/cancel
++ POST /delta/v2/orders/cancel
+ {
+ "orderIds": ["..."],
+ "signature": "0x..."
+ }
+```
+
+### 8. Partner fee
+
+V1: integrators called `GET /prices/partnerfee/{chainId}?partner=...` to look up the registered config, then encoded it into the order locally.
+
+V2: just pass `partner` on every call (`/delta/v2/prices`, `/delta/v2/orders/build`, `/delta/v2/orders`). The server resolves the registered config, validates the fee, and encodes it into the on-chain order. To override per call, pass `partnerAddress` and `partnerFeeBps` (and/or `partnerTakesSurplus`) on the same call.
+
+```diff
+- // V1: separate round-trip, then re-encode in build params
+- const { partnerAddress, partnerFee, takeSurplus } =
+- await fetch(`/prices/partnerfee/${chainId}?partner=${key}`).then(r => r.json());
+- POST /delta/orders/build { ..., partnerAddress, partnerFeeBps: partnerFee * 100, ... }
+
++ // V2: server resolves; just pass `partner`
++ POST /delta/v2/orders/build { ..., partner: "my-app-name" }
+```
+
+`GET /prices/partnerfee/{chainId}` still exists — keep using it if you need the resolved config for your UI (e.g., to show "0.25% fee" alongside the quote).
+
+## Breaking changes you might miss
+
+- **`price.hmac` is gone in V2.** Existing code that re-attaches `hmac` to the build payload will fail validation.
+- **`bridge.destinationChainId !== 0` check breaks.** V2 sets `route.bridge = null` for same-chain; the V1 sentinel is no longer present in V2 responses.
+- **`bridge-info` shape changed.** Nested object → flat `routes[]` array. The replacement endpoint is `bridge-routes` (different name).
+- **Status enum changed.** Your status-handling code needs the mapping table above. Don't rely on `EXECUTED` alone — V2 reports `COMPLETED` for executed-and-finalized orders and `BRIDGING` while the destination leg is still pending.
+- **Order list response changed.** V1 returned `Order[]`; V2 returns `{ data: Order[], total, page, limit, hasMore }`. Code that does `orders.length` or `orders.map(...)` on the response needs to unwrap `.data` first.
+
+## End-state check
+
+1. `GET /delta/v2/prices` returns a `route` and a non-empty `spender`.
+2. `POST /delta/v2/orders/build` returns `{ toSign, orderHash }`.
+3. The signature your wallet produces over `toSign` is accepted by `POST /delta/v2/orders` (status `200`, response carries the new order shape with `id` and `status: "PENDING"`).
+4. `GET /delta/v2/orders/{id}` polls through `ACTIVE` → `COMPLETED` (or `BRIDGING` → `COMPLETED` for crosschain).
+5. `grep -r "partnerfee\|/delta/prices\b\|/delta/orders\b" your-codebase/` — every hit is intentional (e.g., `/prices/partnerfee` for UI lookup; `/delta/orders` only if you intentionally stayed on V1 for an order family that V2 doesn't cover for you yet).
+
+## Related pages
+
+- [Delta V2 API overview](/api-reference/delta-v2/overview) — the recommended surface.
+- [Delta V1 API overview](/api-reference/delta/overview) — the surface you're migrating from.
+- [SDK → Migrate from V1 to V2](/sdk/modules/delta#migrate-from-v1-to-v2) — same migration at the TypeScript SDK level.
+- [Order lifecycle and status codes](/delta/order-lifecycle-and-status-codes) — full V2 status reference.
diff --git a/resources/migrations/index.mdx b/resources/migrations/index.mdx
index e7ed5cf..d52e2aa 100644
--- a/resources/migrations/index.mdx
+++ b/resources/migrations/index.mdx
@@ -9,6 +9,9 @@ These pages are for engineers already shipping on Velora. They cover the only ki
## Available migrations
+
+ Endpoint-by-endpoint migration: server-built orders, route-based pricing, unified status model.
+
Keep Market wired, add Delta via `mode=ALL`, branch per response shape.
diff --git a/sdk/choose-a-variant.mdx b/sdk/choose-a-variant.mdx
index b59dfee..60b0df9 100644
--- a/sdk/choose-a-variant.mdx
+++ b/sdk/choose-a-variant.mdx
@@ -1,15 +1,47 @@
---
title: "Choose a variant"
-description: "Pick between Simple SDK (one-call entry point) and Composable SDK (tree-shakeable modules) based on bundle size and flexibility needs."
-keywords: ["sdk","simple","composable"]
+description: "Pick between Simple, Full, and Partial SDK constructors based on bundle size, API shape, and how much wiring you want to do."
+keywords: ["sdk", "simple", "full", "partial", "tree-shaking"]
---
-This page is a stub. Content coming soon.
+The SDK ships three constructors that wrap the same per-method `construct*` primitives. They differ in how much of the SDK comes pre-wired and what the resulting API surface looks like.
-## When to use this
+## At a glance
-## Quickstart
+| | Simple | Full | Partial |
+| ---------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
+| Constructor | `constructSimpleSDK` | `constructFullSDK` | `constructPartialSDK` |
+| API shape | Flat namespaces — `sdk.swap.getRate(...)`, `sdk.delta.submitDeltaOrder(...)`, `sdk.quote.getQuote(...)` | Same namespaces, typed against your transaction-response generic — `sdk.swap.*`, `sdk.delta.*` | Flat — `sdk.getRate(...)`, `sdk.approveToken(...)`. Whatever you import is what you get. |
+| Bundle size | Includes every module | Includes every module | Tree-shaken to the constructors you import |
+| Provider wiring | Pass `{ axios }` or `{ fetch }` and (optionally) `providerOptions`; SDK builds the fetcher and contract caller for you | You build `fetcher` and `contractCaller` and pass them in | You build `fetcher` and `contractCaller` and pass them in |
+| `` generic | Returns `TxHash` (string) for write calls | You choose — viem `Hex`, `ethers.ContractTransaction`, etc. | Inherits from the `contractCaller` you pass |
+| Best for | Quickstarts, server-side scripts, integrators who want one import | Apps that use most modules and want typed transaction responses | Bundle-size-sensitive front-ends |
-## Examples
+## Pick by use case
+
+- **"I just want a quote and a swap."** Use the **Simple SDK** — one constructor, ready to call.
+- **"I have a Node service that does Delta orders, market swaps, and price polling."** Use the **Full SDK** — namespaced access plus a typed `` so your code knows what `approveToken` returns.
+- **"I'm shipping a front-end and only sign Delta orders."** Use the **Partial SDK** — import `constructBuildDeltaOrder`, `constructSignDeltaOrder`, `constructPostDeltaOrder` and tree-shake the rest.
+- **"I want a custom HTTP client (got, undici, superagent…)."** All three variants accept a custom `fetcher` — see [Configure providers](/sdk/configure-providers#custom-fetcher).
+
+## What stays the same
+
+Every variant ultimately calls the same `construct*` factories under [`@velora-dex/sdk` `src/methods/`](https://github.com/VeloraDEX/sdk/tree/master/src/methods). That means:
+
+- Same method signatures across variants — `getRate`, `buildDeltaOrder`, `submitDeltaOrder`, etc. behave identically.
+- Same partner-fee handling — see [Monetize](/sdk/monetize).
+- Same retries, errors, and `FetcherError` semantics regardless of constructor.
## Related pages
+
+
+
+ `constructSimpleSDK` — one constructor, sensible defaults.
+
+
+ `constructFullSDK` — namespaced, typed transaction responses.
+
+
+ `constructPartialSDK` — cherry-pick constructors, tree-shake the rest.
+
+
diff --git a/sdk/composable-sdk.mdx b/sdk/composable-sdk.mdx
deleted file mode 100644
index db65d0d..0000000
--- a/sdk/composable-sdk.mdx
+++ /dev/null
@@ -1,15 +0,0 @@
----
-title: "Composable SDK"
-description: "Use the tree-shakeable, modular SDK when bundle size matters."
-keywords: ["sdk","composable","tree-shaking"]
----
-
-This page is a stub. Content coming soon.
-
-## When to use this
-
-## Quickstart
-
-## Examples
-
-## Related pages
diff --git a/sdk/configure-providers.mdx b/sdk/configure-providers.mdx
index b31d8c0..6a9e0ef 100644
--- a/sdk/configure-providers.mdx
+++ b/sdk/configure-providers.mdx
@@ -1,15 +1,194 @@
---
title: "Configure providers"
-description: "Wire your own RPC providers, signer, and chain config into the SDK."
-keywords: ["sdk","providers","rpc"]
+description: "Wire your wallet library (viem, ethers v5/v6, web3) and HTTP client (axios, fetch, custom) into the SDK."
+keywords:
+ ["sdk", "providers", "viem", "ethers", "web3", "axios", "fetch", "wagmi"]
---
-This page is a stub. Content coming soon.
+The SDK separates **what** (the Velora methods) from **how it talks to the chain and the API**. You wire two things:
-## When to use this
+- A **contract caller** — bridges between the SDK's `transactCall` / `signTypedDataCall` / `staticCall` interface and your wallet library.
+- A **fetcher** — bridges between the SDK's `FetcherFunction` and your HTTP client.
-## Quickstart
+[Simple SDK](/sdk/simple-sdk) builds both for you from a single options object. [Full SDK](/sdk/full-sdk) and [Partial](/sdk/partial-sdk) SDKs take them as constructor arguments.
-## Examples
+## Contract callers
+
+### viem
+
+```ts
+import { createWalletClient, custom } from "viem";
+import { mainnet } from "viem/chains";
+import { constructViemContractCaller } from "@velora-dex/sdk";
+
+const walletClient = createWalletClient({
+ chain: mainnet,
+ transport: custom(window.ethereum!),
+});
+const [account] = await walletClient.getAddresses();
+
+const contractCaller = constructViemContractCaller(walletClient, account);
+```
+
+Write methods resolve to a viem `Hex` (the transaction hash).
+
+
+For sending the result of `sdk.swap.buildTx` via viem, the SDK exports `txParamsToViemTxParams` to cast all string-numbers to `BigInt`:
+
+```ts
+import { txParamsToViemTxParams } from "@velora-dex/sdk";
+
+const tx = await sdk.swap.buildTx({
+ /* ... */
+});
+const viemTx = txParamsToViemTxParams(tx);
+const hash = await walletClient.sendTransaction({ ...viemTx, account });
+```
+
+
+
+### ethers v5
+
+```ts
+import { ethers } from "ethers";
+import { constructEthersContractCaller } from "@velora-dex/sdk";
+
+const contractCaller = constructEthersContractCaller(
+ {
+ ethersProviderOrSigner: signer, // JsonRpcProvider, Wallet, or Web3Provider
+ EthersContract: ethers.Contract,
+ },
+ account,
+);
+```
+
+Write methods resolve to `ethers.ContractTransaction`. You can call `.wait()` directly on the result.
+
+### ethers v6
+
+```ts
+import { ethers } from "ethers";
+import { constructEthersV6ContractCaller } from "@velora-dex/sdk";
+
+const contractCaller = constructEthersV6ContractCaller(
+ {
+ ethersV6ProviderOrSigner: signer,
+ EthersV6Contract: ethers.Contract,
+ },
+ account,
+);
+```
+
+Write methods resolve to ethers v6's `ContractTransactionResponse`.
+
+### web3.js
+
+```ts
+import Web3 from "web3";
+import { constructWeb3ContractCaller } from "@velora-dex/sdk";
+
+const web3 = new Web3(Web3.givenProvider);
+const contractCaller = constructWeb3ContractCaller(web3, account);
+```
+
+Write methods resolve to web3's `PromiEvent`. Listen on `transactionHash` for early notification:
+
+```ts
+const eventfulTx = await sdk.swap.approveToken(amount, DAI);
+eventfulTx.once("transactionHash", (hash: string) =>
+ console.log("tx sent:", hash),
+);
+```
+
+## Fetchers
+
+### axios
+
+```ts
+import axios from "axios";
+import { constructAxiosFetcher } from "@velora-dex/sdk";
+
+const fetcher = constructAxiosFetcher(axios);
+```
+
+### fetch (Node 18+ and the browser)
+
+```ts
+import { constructFetchFetcher } from "@velora-dex/sdk";
+
+const fetcher = constructFetchFetcher(fetch);
+```
+
+### Custom fetcher
+
+Any HTTP client works — implement `FetcherFunction` and pass it through. Useful for adding retries, logging, header injection, or wrapping an unusual transport.
+
+```ts
+import { constructSimpleSDK, type FetcherFunction } from "@velora-dex/sdk";
+
+const customFetcher: FetcherFunction = async (options) => {
+ // requestParams may include AbortSignal — honor it for cancellation
+ const res = await myHttpClient(options.url, {
+ method: options.method,
+ headers: options.headers,
+ body: options.method === "POST" ? options.data : undefined,
+ signal: options.requestParams?.signal,
+ });
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
+ return res.body;
+};
+
+const sdk = constructSimpleSDK({
+ chainId: 1,
+ fetcher: customFetcher,
+});
+```
+
+For richer error semantics, throw a `FetcherError` and the SDK will re-throw it untouched so calling code can `isFetcherError(err)` and inspect the response.
+
+## wagmi recipe
+
+If your app already uses [wagmi](https://wagmi.sh), reuse the viem wallet client it manages:
+
+```ts
+import axios from "axios";
+import { useAccount, useWalletClient } from "wagmi";
+import {
+ constructPartialSDK,
+ constructAxiosFetcher,
+ constructViemContractCaller,
+ constructGetRate,
+ constructBuildTx,
+ constructApproveToken,
+} from "@velora-dex/sdk";
+
+function useVeloraSDK() {
+ const { address } = useAccount();
+ const { data: walletClient } = useWalletClient();
+
+ if (!walletClient || !address) return null;
+
+ const fetcher = constructAxiosFetcher(axios);
+ const contractCaller = constructViemContractCaller(walletClient, address);
+
+ return constructPartialSDK(
+ {
+ chainId: walletClient.chain.id,
+ fetcher,
+ contractCaller,
+ },
+ constructGetRate,
+ constructBuildTx,
+ constructApproveToken,
+ );
+}
+```
+
+Memoize the result (with `useMemo` on the wallet client and address) to avoid rebuilding the SDK on every render.
## Related pages
+
+- [Install](/sdk/install) — peer dependencies for each wallet library.
+- [Simple SDK](/sdk/simple-sdk) — uses these callers and fetchers via a single options object.
+- [Full SDK](/sdk/full-sdk) — takes the caller and fetcher you construct here.
+- [Partial SDK](/sdk/partial-sdk) — same wiring, smallest bundle.
diff --git a/sdk/full-sdk.mdx b/sdk/full-sdk.mdx
new file mode 100644
index 0000000..4a3d6f5
--- /dev/null
+++ b/sdk/full-sdk.mdx
@@ -0,0 +1,112 @@
+---
+title: "Full SDK"
+description: "constructFullSDK gives you every namespace (sdk.swap, sdk.delta, sdk.deltaV2, sdk.quote) over a fetcher and contract caller you construct yourself, with a typed transaction-response generic."
+keywords: ["sdk", "full", "constructFullSDK"]
+---
+
+`constructFullSDK` returns the same namespaced API as the [Simple SDK](/sdk/simple-sdk) — `sdk.swap.*`, `sdk.delta.*`, `sdk.quote` — but you construct the fetcher and contract caller yourself. That extra wiring buys you a typed `` generic and the freedom to share one caller across multiple SDK instances or chains.
+
+## When to use this
+
+- You want write methods to return your wallet library's native response type (e.g., viem `Hex` or `ethers.ContractTransaction`) instead of a bare transaction hash.
+- You need one `contractCaller` to back several SDKs — for example, the same signer on mainnet (`chainId: 1`) and on Optimism (`chainId: 10`).
+- You're building infrastructure that abstracts the fetcher (custom retry, caching, logging) and don't want the Simple SDK to wrap it.
+
+If none of those apply, prefer the [Simple SDK](/sdk/simple-sdk) — fewer moving parts.
+
+## Construct it
+
+```ts
+import axios from "axios";
+import { createWalletClient, custom } from "viem";
+import { mainnet } from "viem/chains";
+import {
+ constructFullSDK,
+ constructAxiosFetcher,
+ constructViemContractCaller,
+} from "@velora-dex/sdk";
+
+const walletClient = createWalletClient({
+ chain: mainnet,
+ transport: custom(window.ethereum!),
+});
+const [account] = await walletClient.getAddresses();
+
+const contractCaller = constructViemContractCaller(walletClient, account);
+const fetcher = constructAxiosFetcher(axios);
+
+const sdk = constructFullSDK({
+ chainId: 1,
+ fetcher,
+ contractCaller,
+});
+```
+
+Swap the contract-caller line for `constructEthersContractCaller`, `constructEthersV6ContractCaller`, or `constructWeb3ContractCaller` to use a different wallet library — see [Configure providers](/sdk/configure-providers) for each variant.
+
+## Typed transaction responses
+
+The `` generic is the type that every write method returns. It's inferred from the contract caller you pass.
+
+| Contract caller | `` |
+| ------------------------------------ | ---------------------------------------- |
+| `constructViemContractCaller` | viem `Hex` (the transaction hash) |
+| `constructEthersContractCaller` (v5) | `ethers.ContractTransaction` |
+| `constructEthersV6ContractCaller` | ethers v6 `ContractTransactionResponse` |
+| `constructWeb3ContractCaller` | web3.js `PromiEvent` |
+
+So with the viem caller above:
+
+```ts
+// type Promise
+const hash = await sdk.swap.approveToken("1000000000000000000", DAI);
+console.log("approval submitted:", hash);
+```
+
+## What's available
+
+The namespaces are identical to [Simple SDK](/sdk/simple-sdk#available-methods):
+
+- `sdk.deltaV2` — **recommended.** Full Delta V2 lifecycle: `getDeltaPrice`, `submitDeltaOrder`, build/sign/post split, `getDeltaOrders` (paginated), `cancelDeltaOrders`, plus reused approve/preSign.
+- `sdk.delta` — Delta V1. Same lifecycle, locally-built orders.
+- `sdk.quote` — `getQuote`
+- `sdk.swap` — rate, build, approve, balances, spender, tokens, adapters, swapTx
+- `sdk.limitOrders` — deprecated; see [Limit orders module](/sdk/modules/limit-orders)
+
+See [Modules → Swap](/sdk/modules/swap) and [Modules → Delta](/sdk/modules/delta) for end-to-end flows.
+
+## Sharing one caller across chains
+
+Because you own the caller, you can reuse it:
+
+```ts
+const baseConfig = { fetcher, contractCaller };
+
+const mainnet = constructFullSDK({ ...baseConfig, chainId: 1 });
+const optimism = constructFullSDK({ ...baseConfig, chainId: 10 });
+```
+
+## Related pages
+
+
+
+ Drop unused modules entirely with `constructPartialSDK`.
+
+
+ All four contract callers and both fetchers, with examples.
+
+
+ The full Delta order lifecycle, including the split build/sign/post flow.
+
+
+ Market-swap walkthrough using the namespaced SDK.
+
+
diff --git a/sdk/install.mdx b/sdk/install.mdx
index 5c68e90..e0f498c 100644
--- a/sdk/install.mdx
+++ b/sdk/install.mdx
@@ -1,15 +1,101 @@
---
title: "Install & quick example"
description: "Install @velora-dex/sdk and fetch your first quote in under five minutes."
-keywords: ["sdk","install","quickstart"]
+keywords: ["sdk", "install", "quickstart", "typescript"]
---
-This page is a stub. Content coming soon.
+The Velora SDK is published as [`@velora-dex/sdk`](https://www.npmjs.com/package/@velora-dex/sdk). It has no required runtime dependencies — `viem`, `ethers`, `web3`, and `axios` are all optional peers that the SDK detects at construction time.
-## When to use this
+## Install the package
-## Quickstart
+
-## Examples
+```bash pnpm
+pnpm add @velora-dex/sdk
+```
-## Related pages
+```bash npm
+npm install @velora-dex/sdk
+```
+
+```bash yarn
+yarn add @velora-dex/sdk
+```
+
+
+
+### Peer dependencies
+
+Pick whichever wallet library and HTTP client you already use. All of these are optional peers — install only the ones you need.
+
+| Package | Version | When you need it |
+| -------- | -------------------- | --------------------------------------------------------------------------------------- |
+| `viem` | `^2.21.0` | If you sign and submit transactions with viem. |
+| `ethers` | `^5.5.0` or `^6.0.0` | If you sign and submit transactions with ethers. |
+| `web3` | `^4.14.0` | If you sign and submit transactions with web3.js. |
+| `axios` | `>=0.25.0 <2.0.0` | If you wire the SDK fetcher to axios. (Use the built-in `fetch` instead to avoid this.) |
+
+
+You can use the SDK in **read-only mode** without any of these. Pass `{ chainId, fetch }` (or `{ chainId, axios }`) and the SDK can call every API method — quotes, prices, order status — but cannot sign or submit transactions.
+
+
+## Your first call
+
+The smallest possible setup — quote DAI → USDC on mainnet using native `fetch`:
+
+```ts
+import { constructSimpleSDK } from "@velora-dex/sdk";
+
+const simpleSDK = constructSimpleSDK({ chainId: 1, fetch });
+
+const priceRoute = await simpleSDK.swap.getRate({
+ srcToken: "0x6B175474E89094C44Da98b954EedeAC495271d0F", // DAI
+ destToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
+ amount: "1000000000000000000", // 1 DAI (18 decimals)
+ userAddress: "0x0000000000000000000000000000000000000000",
+ side: "SELL",
+ options: { partner: "my-app-name" },
+});
+
+console.log(priceRoute.srcAmount, "→", priceRoute.destAmount);
+```
+
+## Verify it works
+
+The returned `priceRoute` contains at minimum:
+
+- `srcAmount` — the input amount you passed (echoed for confirmation).
+- `destAmount` — the expected output amount in destination-token wei.
+- `bestRoute` — the resolved swap path across DEXes.
+- `gasCost` and `gasCostUSD` — estimated execution gas.
+
+If the call throws with `Network Error` or a 4xx response, double-check `chainId`, `partner`, and that your firewall allows outbound HTTPS to the Velora API.
+
+## Add a wallet to send transactions
+
+Pass a `providerOptions` argument to enable `approveToken`, `submitDeltaOrder`, and `buildTx`-then-send flows. The shape varies by library — see [Configure providers](/sdk/configure-providers) for the four supported stacks (viem, ethers v5, ethers v6, web3).
+
+## Next steps
+
+
+
+ Simple vs Full vs Partial — bundle size and API shape tradeoffs.
+
+
+ The one-constructor entry point used in this page.
+
+
+ Wire up viem, ethers, or web3 for signing and transactions.
+
+
+ Full Market-swap flow: rate → approve → build → send.
+
+
diff --git a/sdk/modules/delta.mdx b/sdk/modules/delta.mdx
index 1cfe598..4c15ec6 100644
--- a/sdk/modules/delta.mdx
+++ b/sdk/modules/delta.mdx
@@ -1,15 +1,356 @@
---
title: "Delta module"
-description: "Submit and track Delta intents from the SDK."
-keywords: ["sdk","delta","intents"]
+description: "Submit, sign, and track Delta intents from sdk.deltaV2 — gasless swaps where solvers execute on the user's behalf."
+keywords: ["sdk", "delta", "deltaV2", "DeltaV2", "intents", "gasless", "submitDeltaOrder"]
---
-This page is a stub. Content coming soon.
+The Delta module wraps the [Delta API](/delta/overview) — gasless, MEV-protected swaps where the user signs an off-chain order and a network of solvers (Portikus) competes to fill it. The user pays no gas; the solver covers execution cost out of their margin.
+
+
+**Delta V2 is recommended.** V2 is server-built (you don't compose EIP-712 typed data locally), returns richer pricing (recommended route + alternatives), and ships paginated order history. V1 remains fully supported — see [Delta V1](#delta-v1) at the bottom of this page.
+
## When to use this
-## Quickstart
+- The user shouldn't pay gas, or doesn't have gas on the source chain.
+- You want MEV protection — orders fill via private auction, not the public mempool.
+- You want a single signature to settle crosschain — see [Crosschain Delta](/delta/crosschain-delta).
+
+For swaps where the user submits the transaction themselves, see [Modules → Swap](/sdk/modules/swap).
+
+## How V2 is exposed
+
+V2 lives at two layers in the SDK:
+
+- **`sdk.deltaV2.*`** — the pre-bound bag attached to `constructSimpleSDK` / `constructFullSDK`. Methods on it are **unsuffixed**: `sdk.deltaV2.getDeltaPrice`, `sdk.deltaV2.submitDeltaOrder`, `sdk.deltaV2.signDeltaOrder`, etc. This is what most consumers use.
+- **`DeltaV2` namespace** — re-exported at the package root. Carries the raw constructors *and* types for advanced wiring (e.g., `constructPartialSDK`) and type annotations.
+
+```ts
+import { DeltaV2 } from "@velora-dex/sdk";
+
+// values: DeltaV2.constructBuildDeltaOrder, DeltaV2.constructPostDeltaOrder,
+// DeltaV2.constructSubmitDeltaOrder, DeltaV2.constructAllDeltaOrdersHandlers, ...
+// types: DeltaV2.DeltaPrice, DeltaV2.DeltaRoute, DeltaV2.BuiltDeltaOrder,
+// DeltaV2.DeltaAuction, DeltaV2.BridgeRoute, ...
+```
+
+`import type { DeltaV2 }` works the same way for type-only consumers. Types live *inside* the namespace — alias with `type DeltaPrice = DeltaV2.DeltaPrice;` if you want a short local name; you can't destructure a type at the import site.
+
+The same unsuffixed names exist for V1 at the top level of the package (`constructPostDeltaOrder`, `DeltaPrice`, etc.) — wrapping V2 in a namespace is what makes the two coexist without collision until V1 is deprecated.
+
+## The flow
+
+
+
+ Call `sdk.deltaV2.getDeltaPrice` with source/destination tokens, amount, decimals, and partner. The response includes the recommended `route` plus `alternatives` and the contract `spender` to approve.
+
+
+ Call `sdk.deltaV2.approveTokenForDelta(amount, srcToken)`, or sign a Permit / Permit2 message with the Delta contract (returned in `price.spender`) as the verifying contract. Native tokens skip this step.
+
+
+ Either call the one-shot orchestrator `sdk.deltaV2.submitDeltaOrder`, or run the three steps yourself (`buildDeltaOrder` → `signDeltaOrder` → `postDeltaOrder`) when you need control over signing.
+
+
+ Use `sdk.deltaV2.getDeltaOrderById` (or `getDeltaOrderByHash`) on a timer until status is `COMPLETED`.
+
+
+
+## One-call submit
+
+`submitDeltaOrder` runs build → sign → post in a single call. This is the recommended path for most flows.
+
+```ts
+const price = await sdk.deltaV2.getDeltaPrice({
+ srcToken: DAI,
+ destToken: USDC,
+ amount: "1000000000000000000", // 1 DAI
+ srcDecimals: 18,
+ destDecimals: 6,
+ userAddress: account,
+ partner: "my-app-name",
+});
+
+await sdk.deltaV2.approveTokenForDelta("1000000000000000000", DAI);
+
+const auction = await sdk.deltaV2.submitDeltaOrder({
+ route: price.route,
+ side: price.side,
+ owner: account,
+ partner: "my-app-name",
+ slippage: 50, // 0.5% in bps
+ // beneficiary: anotherAccount, // optional, default = owner
+ // permit: "0x...", // optional, if you signed a Permit instead of approving
+ // partiallyFillable: true, // optional, default = fill-or-kill
+});
+
+console.log("auction id:", auction.id);
+```
+
+## Split flow
+
+Use the three-step flow when you need to customize signing — for example, a hardware wallet that prompts on each call, a multisig that signs asynchronously, or batched signing across orders.
+
+```ts
+const built = await sdk.deltaV2.buildDeltaOrder({
+ route: price.route,
+ side: price.side,
+ owner: account,
+ partner: "my-app-name",
+ slippage: 50,
+});
+
+const signature = await sdk.deltaV2.signDeltaOrder(built);
+
+const auction = await sdk.deltaV2.postDeltaOrder({
+ order: built.toSign.value as any,
+ signature,
+ partner: "my-app-name",
+});
+```
+
+`buildDeltaOrder` returns `{ toSign, orderHash }` — the server has already composed the EIP-712 typed data; `signDeltaOrder` wraps your contract caller's `signTypedData` to produce the signature.
+
+If your signer is a smart contract (e.g., a multisig or 4337 wallet) that can't produce an off-chain EIP-712 signature, use `sdk.deltaV2.preSignDeltaOrder` to register the order hash on-chain instead.
+
+## Poll for execution
+
+```ts
+import { OrderHelpers } from "@velora-dex/sdk";
+
+const intervalId = setInterval(async () => {
+ const updated = await sdk.deltaV2.getDeltaOrderById(auction.id);
+ if (OrderHelpers.checks.isExecutedAuction(updated)) {
+ clearInterval(intervalId);
+ console.log("filled");
+ }
+}, 3000);
+
+// stop polling after 5 minutes
+setTimeout(() => clearInterval(intervalId), 60_000 * 5);
+```
+
+`OrderHelpers.checks.isExecutedAuction` works for both V2 and V1 auctions. It returns `true` only when same-chain orders show `status === "EXECUTED"` (or V2's `COMPLETED`), and crosschain orders also have their destination-chain leg filled.
+
+Order status codes and their meaning are documented under [Delta → Order lifecycle and status codes](/delta/order-lifecycle-and-status-codes).
+
+## List orders
+
+`getDeltaOrders` returns a paginated list filtered by user, chain, status, and order type:
+
+```ts
+const { data, page, limit, total } = await sdk.deltaV2.getDeltaOrders({
+ userAddress: account,
+ page: 1,
+ limit: 100,
+ // status: ["ACTIVE", "COMPLETED"], // optional filter
+ // chainId: [1, 10], // omit for all chains
+ // type: "MARKET", // 'MARKET' | 'LIMIT'
+});
+```
+
+Each entry is a `DeltaV2.DeltaAuction`, generic over `onChainOrderType` (the same shape as V1's `DeltaAuction`). The list may include `'ProductiveOrder'` — a family with no SDK builder; see [Productive orders](#productive-orders-read-only) below. It may also report `'FillableOrder'` for a `partiallyFillable` Standard order — treat it exactly like `'Order'` (identical shape).
+
+## Partner fee
+
+Pass `partner` (and optionally `partnerAddress`, `partnerFeeBps`, `partnerTakesSurplus`) to `getDeltaPrice`, `submitDeltaOrder`, `buildDeltaOrder`, and `postDeltaOrder`. V2 sends these directly to the server, which resolves and validates the fee — no local `getPartnerFee` round-trip needed.
+
+```ts
+const auction = await sdk.deltaV2.submitDeltaOrder({
+ route: price.route,
+ side: price.side,
+ owner: account,
+ partner: "my-app-name",
+ partnerAddress: "0xYourFeeCollector",
+ partnerFeeBps: 25, // 0.25%
+ slippage: 50,
+});
+```
+
+See [Monetize](/sdk/monetize) for the full field reference and fee-vs-surplus tradeoffs.
+
+## Cancel an order
+
+```ts
+await sdk.deltaV2.cancelDeltaOrders({ orderIds: [auction.id] });
+```
+
+This signs and posts a cancellation request. It only succeeds for orders that are still open in the auction.
-## Examples
+## Crosschain Delta
+
+Pass `destChainId` to `getDeltaPrice` to settle on a different chain than the source. The returned `route` is bridge-aware; submitting the order is identical to same-chain. See [Crosschain Delta](/delta/crosschain-delta) for the full design and [`getBridgeRoutes`](https://github.com/VeloraDEX/sdk/blob/master/src/methods/deltaV2/getBridgeRoutes.ts) for advanced route inspection.
+
+## External and TWAP orders
+
+The SDK supports two advanced order families on V2 that share the same build/sign/post pattern:
+
+- **External Delta orders** — settle through a custom handler contract. Used for Aave-style collateral/debt swaps and other DeFi compositions. Use `buildExternalDeltaOrder` / `submitExternalDeltaOrder`. See [`EXTERNAL_ORDERS.md`](https://github.com/VeloraDEX/sdk/blob/master/docs/EXTERNAL_ORDERS.md) in the SDK repo.
+- **TWAP Delta orders** — split a large order into time-weighted chunks (sell-side or buy-side). Use `buildTWAPDeltaOrder` / `submitTWAPDeltaOrder`.
+
+Both reuse the generic `signDeltaOrder` and the V2 polling endpoints.
+
+## Productive orders (read-only)
+
+Alongside the four buildable families (`Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`), the SDK surfaces a fifth `onChainOrderType` — **`ProductiveOrder`** — through the read endpoints (`sdk.deltaV2.getDeltaOrderById`, `sdk.deltaV2.getDeltaOrders`, etc.). Productive orders are produced and managed entirely by the server: there are **no `buildProductiveOrder`, `signProductiveOrder`, or `submitProductiveOrder` helpers** in the SDK. The shape is wired through `OnChainOrderType`, `OnChainOrderMap`, and `DeltaAuctionUnion` (also exported individually as `DeltaAuctionProductive`) so a consumer iterating over an order list can narrow on `onChainOrderType === 'ProductiveOrder'` and read the order safely. Productive orders carry no `OrderKind`, so the side is always `SELL`.
+
+```ts
+import { OrderHelpers, type DeltaAuctionUnion } from "@velora-dex/sdk";
+
+function describe(order: DeltaAuctionUnion) {
+ if (order.onChainOrderType === "ProductiveOrder") {
+ // order: DeltaAuctionProductive — read-only, no SDK builder
+ return `productive: ${order.order.srcToken}`;
+ }
+ // "Order" and "FillableOrder" share the same shape (DeltaAuctionFillable)
+ // ... handle Order / FillableOrder / ExternalOrder / TWAPOrder / TWAPBuyOrder
+}
+```
+
+## Migrate from V1 to V2
+
+The two paths share the same on-chain contracts and approval flow. What changes is where the EIP-712 typed data comes from (server in V2, local in V1) and the param shapes — V2 packages source/destination details inside a `route` object and takes `slippage` directly.
+
+### Pricing
+
+```diff
+- const deltaPrice = await sdk.delta.getDeltaPrice({
++ const price = await sdk.deltaV2.getDeltaPrice({
+ srcToken: DAI,
+ destToken: USDC,
+ amount,
+ srcDecimals: 18,
+ destDecimals: 6,
+ userAddress: account,
+ partner: "my-app-name",
+ });
+```
+
+V1 returns `DeltaPrice { destAmount, partner, partnerFee, srcAmount, destToken }`. V2 returns `DeltaV2.DeltaPrice { route, alternatives, partner: { name, feePercent }, spender, ... }` — swap details live under `price.route`, and `alternatives` lets you show users different bridges.
+
+### One-call submit
+
+```diff
+- const auction = await sdk.delta.submitDeltaOrder({
+- deltaPrice,
+- owner: account,
+- srcToken: DAI,
+- destToken: USDC,
+- srcAmount: amount,
+- destAmount, // you compute slippage-adjusted destAmount
+- partner: "my-app-name",
+- });
++ const auction = await sdk.deltaV2.submitDeltaOrder({
++ route: price.route, // route carries src/dest tokens and amounts
++ side: price.side,
++ owner: account,
++ partner: "my-app-name",
++ slippage: 50, // bps; SDK applies slippage for you
++ });
+```
+
+### Split flow (build → sign → post)
+
+```diff
+- const signableOrderData = await sdk.delta.buildDeltaOrder({ /* ... */ });
+- const signature = await sdk.delta.signDeltaOrder(signableOrderData);
+- const auction = await sdk.delta.postDeltaOrder({
+- order: signableOrderData.data,
+- signature,
+- partner: "my-app-name",
+- });
++ const built = await sdk.deltaV2.buildDeltaOrder({ /* ... */ });
++ const signature = await sdk.deltaV2.signDeltaOrder(built);
++ const auction = await sdk.deltaV2.postDeltaOrder({
++ order: built.toSign.value as any,
++ signature,
++ partner: "my-app-name",
++ });
+```
+
+V2 method names are the same as V1's at the property level (`buildDeltaOrder`, `signDeltaOrder`, `postDeltaOrder`) — what changes is the SDK namespace (`sdk.delta` → `sdk.deltaV2`) and the param/response shapes. `buildDeltaOrder` returns `{ toSign, orderHash }` from the server. `signDeltaOrder` is generic across all order families (Order, ExternalOrder, TWAPOrder, TWAPBuyOrder) — V1's separate `signExternalDeltaOrder` / `signTWAPDeltaOrder` collapse into one call.
+
+### Polling status
+
+```diff
+- const updated = await sdk.delta.getDeltaOrderById(auction.id);
++ const updated = await sdk.deltaV2.getDeltaOrderById(auction.id);
+```
+
+`OrderHelpers.checks.isExecutedAuction(updated)` works for both. V2 introduces a richer status set (`PENDING` / `AWAITING_SIGNATURE` / `ACTIVE` / `BRIDGING` / `COMPLETED` / `FAILED` / ...). See [Order lifecycle and status codes](/delta/order-lifecycle-and-status-codes) for the V2 mapping.
+
+### Listing orders
+
+```diff
+- const orders = await sdk.delta.getDeltaOrders({ /* filter */ });
++ const { data, page, limit, total } = await sdk.deltaV2.getDeltaOrders({
++ userAddress: account,
++ page: 1,
++ limit: 100,
++ });
+```
+
+V2 returns a `PaginatedResponse` envelope. `userAddress` is required; iterate `data` and increment `page` until you've consumed `total`.
+
+### Cancelling
+
+```diff
+- await sdk.delta.cancelLimitDeltaOrders([orderId]);
++ await sdk.deltaV2.cancelDeltaOrders({ orderIds: [orderId] });
+```
+
+### Type imports
+
+```diff
+- import type { DeltaPriceV2, BuiltDeltaOrderV2, DeltaOrderV2Response } from "@velora-dex/sdk";
++ import { DeltaV2 } from "@velora-dex/sdk";
++ // then: DeltaV2.DeltaPrice, DeltaV2.BuiltDeltaOrder, DeltaV2.DeltaAuction
+```
+
+V2 types live inside the `DeltaV2` namespace; the old `*V2`-suffixed bare names are no longer exported.
+
+### What stays the same
+
+- `sdk.deltaV2.approveTokenForDelta(amount, token)` — same as V1.
+- `sdk.deltaV2.getDeltaContract()` — same contract address.
+- `sdk.deltaV2.getPartnerFee({ partner })` — useful for showing fee info in your UI; V2 doesn't *need* this round-trip because the server resolves partner fees, but the helper is still there.
+- `sdk.deltaV2.preSignDeltaOrder` — on-chain pre-signing for smart-contract wallets.
+- The on-chain order struct and signature format are identical — V2 is a different way to assemble the same on-chain payload.
+
+## Delta V1
+
+V1 is exposed at `sdk.delta.*`. The flow is similar but the order is built locally (no server `build` call) and the response shapes differ:
+
+```ts
+const deltaPrice = await sdk.delta.getDeltaPrice({
+ srcToken: DAI,
+ destToken: USDC,
+ amount,
+ srcDecimals: 18,
+ destDecimals: 6,
+ userAddress: account,
+ partner: "my-app-name",
+});
+
+await sdk.delta.approveTokenForDelta(amount, DAI);
+
+const auction = await sdk.delta.submitDeltaOrder({
+ deltaPrice,
+ owner: account,
+ srcToken: DAI,
+ destToken: USDC,
+ srcAmount: amount,
+ destAmount: deltaPrice.destAmount, // apply your own slippage
+ partner: "my-app-name",
+});
+```
+
+Poll via `sdk.delta.getDeltaOrderById(auction.id)`. Cancel via `sdk.delta.cancelLimitDeltaOrders([auction.id])`.
+
+V2 is recommended for most flows — partner-fee resolution is server-side, the price response includes bridge alternatives, and order listing is paginated. V1 stays useful when you need local control over EIP-712 typed-data assembly (e.g., to inspect or modify the order before signing) or when you're already consuming the V1 `quote.getQuote` Delta-or-Market response.
## Related pages
+
+- [Why Delta](/delta/overview) — the protocol design.
+- [Quickstart](/overview/quickstart) — Delta end-to-end via cURL.
+- [Monetize](/sdk/monetize) — partner-fee fields.
+- [API reference → Delta](/api-reference/delta/overview) — the HTTP endpoints.
diff --git a/sdk/modules/limit-orders.mdx b/sdk/modules/limit-orders.mdx
index 890de2e..ce6adff 100644
--- a/sdk/modules/limit-orders.mdx
+++ b/sdk/modules/limit-orders.mdx
@@ -1,15 +1,41 @@
---
title: "Limit orders module"
-description: "Create, sign, and manage limit orders from the SDK."
-keywords: ["sdk","limit orders"]
+description: "The SDK limit-orders module is deprecated. New integrations should use Delta limit orders, which are gasless and MEV-protected."
+keywords: ["sdk", "limit orders", "deprecated", "delta"]
---
-This page is a stub. Content coming soon.
+
+**The SDK `limitOrders` module is deprecated** and will be removed in a future major version. New integrations should use **Delta limit orders** — they are gasless, MEV-protected, and use the same Portikus solver network as Delta market orders.
+
-## When to use this
+## Migrate to Delta
-## Quickstart
+Limit-order behavior is now expressed through Delta with a `LIMIT` order type. You sign once and the solver network competes to fill at or better than your limit price; you pay no gas.
-## Examples
+
+
+ What Delta gives you over a classic limit order — gasless, MEV-protected, crosschain.
+
+
+ Build, sign, and submit a Delta order from the SDK.
+
+
+
+## The deprecated module
+
+For existing integrations, the `sdk.limitOrders` namespace still exposes:
+
+- `buildLimitOrder` — assemble an EIP-712 typed-data payload.
+- `signLimitOrder` — sign that payload with the connected wallet.
+- `postLimitOrder` — submit the signed order to the API.
+- `cancelLimitOrder` — sign and post a cancellation.
+- `getLimitOrders` — query open and filled orders for a maker.
+- `approveTokenForLimitOrder`, `getLimitOrdersContract`, `buildLimitOrderTx`, `fillOrderDirectly` — supporting on-chain methods.
+
+Full signatures, parameter shapes, and return types are generated from source into the [SDK typedoc reference](https://github.com/VeloraDEX/sdk/tree/master/docs/md).
## Related pages
+
+- [Why Delta](/delta/overview)
+- [Modules → Delta](/sdk/modules/delta)
+- [API reference → Delta](/api-reference/delta/overview)
diff --git a/sdk/modules/swap.mdx b/sdk/modules/swap.mdx
index 98d04dd..52e2a11 100644
--- a/sdk/modules/swap.mdx
+++ b/sdk/modules/swap.mdx
@@ -1,15 +1,118 @@
---
title: "Swap module"
-description: "Build, sign, and execute swaps through the SDK swap module."
-keywords: ["sdk","swap"]
+description: "Build, approve, and execute Market swaps through sdk.swap — the user submits the transaction themselves."
+keywords: ["sdk", "swap", "market", "buildTx", "getRate"]
---
-This page is a stub. Content coming soon.
+The Swap module wraps the [Market API](/market/overview) — rates, allowances, and transaction-building for swaps that the **user** signs and submits. For gasless swaps where solvers settle on the user's behalf, see [Modules → Delta](/sdk/modules/delta).
## When to use this
-## Quickstart
+- The user has gas on the source chain and is happy to submit a transaction.
+- You need the cheapest path across DEX aggregation (no auction, no off-chain settlement).
+- You want full control over slippage, gas, and recipient.
+- You don't need crosschain or MEV-protected settlement — see [Delta module](/sdk/modules/delta) for that.
-## Examples
+## The flow
+
+
+
+ Call `sdk.swap.getRate` (or `sdk.quote.getQuote` with `mode: 'market'`) to choose source token, destination token, amount, and side. The response includes the routed path and expected output.
+
+
+ Call `sdk.swap.approveToken` so the `TokenTransferProxy` can pull the source token, or sign a Permit / Permit2 message with `TokenTransferProxy` as the verifying contract.
+
+
+ Call `sdk.swap.buildTx` with the price route, slippage (or `destAmount`), user address, and `partner`. The response is a fully-populated `TransactionRequest`.
+
+
+ Pass the result of `buildTx` to your signer's `sendTransaction`. The SDK is no longer in the loop after this — you own the broadcast.
+
+
+
+## Full example
+
+```ts
+import axios from "axios";
+import { createWalletClient, custom } from "viem";
+import { mainnet } from "viem/chains";
+import { constructSimpleSDK, txParamsToViemTxParams } from "@velora-dex/sdk";
+
+const walletClient = createWalletClient({
+ chain: mainnet,
+ transport: custom(window.ethereum!),
+});
+const [account] = await walletClient.getAddresses();
+
+const sdk = constructSimpleSDK(
+ { chainId: 1, axios },
+ { viemClient: walletClient, account }
+);
+
+const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
+const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
+const amount = "1000000000000000000"; // 1 DAI
+
+// 1. Quote
+const priceRoute = await sdk.swap.getRate({
+ srcToken: DAI,
+ destToken: USDC,
+ amount,
+ userAddress: account,
+ side: "SELL",
+ options: { partner: "my-app-name" },
+});
+
+// 2. Approve
+await sdk.swap.approveToken(amount, DAI);
+
+// 3. Build the swap transaction
+const tx = await sdk.swap.buildTx({
+ srcToken: DAI,
+ destToken: USDC,
+ srcAmount: amount,
+ slippage: 250, // 2.5% in basis points
+ priceRoute,
+ userAddress: account,
+ partner: "my-app-name",
+ // receiver: "0x..." // optional, if the recipient differs from userAddress
+});
+
+// 4. Send it
+const hash = await walletClient.sendTransaction({
+ ...txParamsToViemTxParams(tx),
+ account,
+});
+console.log("swap submitted:", hash);
+```
+
+### Sign a Permit instead of approving
+
+If the source token supports EIP-2612 (or Permit2), skip the on-chain approval and sign a typed-data message with the `TokenTransferProxy` as the verifying contract.
+
+```ts
+const tokenTransferProxy = await sdk.swap.getSpender();
+// build EIP-712 typed data with verifyingContract = tokenTransferProxy
+// pass the signature as `permit` to buildTx
+```
+
+See the [Build parameters for transaction](/api-reference/market/transactions) endpoint for the supported permit variants.
+
+## Other methods
+
+- `sdk.swap.getSpender()` — the `TokenTransferProxy` address you approve.
+- `sdk.swap.getBalances(userAddress)` — token balances and allowances in one call.
+- `sdk.swap.getTokens()` — Velora-supported tokens on the active chain.
+- `sdk.swap.getAdapters()` — the DEX adapters available to the router.
+- `sdk.swap.swapTx(params)` — one-call orchestrator: rate + build + send. Convenience over the four-step flow.
+
+## Partner fee
+
+Add `partner` (and optionally `partnerAddress`, `partnerFeeBps`, `partnerTakesSurplus`) to every `getRate`, `buildTx`, and `getQuote` call to capture revenue. See [Monetize](/sdk/monetize) for the full field reference.
## Related pages
+
+- [Modules → Delta](/sdk/modules/delta) — gasless intent-based swaps.
+- [Monetize](/sdk/monetize) — partner-fee fields and tradeoffs.
+- [Configure providers](/sdk/configure-providers) — set up your wallet library.
+- [API reference → Market](/api-reference/market/overview) — the underlying HTTP endpoints.
diff --git a/sdk/monetize.mdx b/sdk/monetize.mdx
index 61b42c9..d3a3b96 100644
--- a/sdk/monetize.mdx
+++ b/sdk/monetize.mdx
@@ -1,15 +1,91 @@
---
-title: "Monetize (fee config)"
-description: "Configure partner fees on SDK calls and collect revenue per trade."
-keywords: ["sdk","fees","monetization"]
+title: "Monetize"
+description: "Add partner fees or surplus share to every SDK call — same partner key works across Market swaps, Delta orders, and quotes."
+keywords: ["sdk", "fees", "monetization", "partner", "partnerFee", "takeSurplus"]
---
-This page is a stub. Content coming soon.
+Every quote, swap, and Delta call accepts a `partner` string and optional fee overrides. The fee is collected on-chain at settlement and routed to your partner address — no extra integration needed.
-## When to use this
+## Quick setup
-## Quickstart
+If you've registered your partner key with Velora, just pass `partner` and the server resolves the fee config:
-## Examples
+```ts
+const auction = await sdk.deltaV2.submitDeltaOrder({
+ route: price.route,
+ side: price.side,
+ owner: account,
+ partner: "my-app-name",
+ slippage: 50,
+});
+```
+
+To override the registered defaults per call, pass the fee fields directly:
+
+```ts
+const auction = await sdk.deltaV2.submitDeltaOrder({
+ route: price.route,
+ side: price.side,
+ owner: account,
+ partner: "my-app-name",
+ partnerAddress: "0xYourFeeCollector",
+ partnerFeeBps: 25, // 0.25%
+ partnerTakesSurplus: false,
+ slippage: 50,
+});
+```
+
+
+**Delta V2 vs V1.** V2 sends `partner` / `partnerAddress` / `partnerFeeBps` straight to the server, which resolves and validates them — no extra round-trip. V1 calls `getPartnerFee(partner)` locally inside `buildDeltaOrder` (response is cached per partner). Either way the fee lands on-chain at settlement; the V2 path is just one fewer network call.
+
+
+If you need to obtain the registered defaults programmatically (e.g., to show "0.25% fee" in your UI), call `getPartnerFee` directly:
+
+```ts
+const { partnerAddress, partnerFee, takeSurplus } =
+ await sdk.deltaV2.getPartnerFee({ partner: "my-app-name" });
+```
+
+## Fields
+
+| Field | Type | Description |
+|---|---|---|
+| `partner` | `string` | Your partner-key string (e.g. `"my-app-name"`). Used for attribution; required for partner features. |
+| `partnerAddress` | `string` | Optional. Ethereum address that receives the fee. Overrides the address registered for `partner`. |
+| `partnerFeeBps` | `number` | Optional. Fee in basis points. `25` = 0.25%. Max `200` (2%). |
+| `partnerTakesSurplus` | `boolean` | Optional. When `true`, you receive a share of swap surplus instead of a fixed fee. Defaults to `false`. |
+
+
+**Precedence.** If both `partnerFeeBps` and `partnerTakesSurplus` are set, `partnerFeeBps` wins. To take surplus instead, set `partnerTakesSurplus: true` and **omit** `partnerFeeBps`.
+
+
+## Fee vs surplus — which to pick
+
+| | Fixed fee (`partnerFeeBps`) | Surplus share (`partnerTakesSurplus`) |
+|---|---|---|
+| Revenue | Predictable per-trade cut | Variable — depends on routing edge |
+| User cost | Worse quotes (fee comes off the top) | Same quote as no-fee — surplus is the *better-than-quoted* portion |
+| Max | 2% (`partnerFeeBps: 200`) | 50% of surplus |
+| Best for | Mass-market integrations where a known cut matters | High-volume integrations that prioritize the user-facing rate |
+
+## Where it applies
+
+- **Delta V2** (recommended) — pass `partner` (and overrides) to `sdk.deltaV2.getDeltaPrice`, `sdk.deltaV2.submitDeltaOrder`, `sdk.deltaV2.buildDeltaOrder`, and `sdk.deltaV2.postDeltaOrder`. The server encodes the fee into the on-chain order.
+- **Delta V1** — pass `partner` to `sdk.delta.buildDeltaOrder` or `sdk.delta.submitDeltaOrder`. The SDK resolves the fee locally via `getPartnerFee` and encodes it into the signed order's `partnerAndFee` field.
+- **Market swap** — pass `partner` to `sdk.swap.getRate` (inside `options: { partner }`) and `sdk.swap.buildTx` (top-level). Fee is taken from the destination token at settlement.
+- **Quote** — pass `partner` to `sdk.quote.getQuote`. The returned `priceRoute` / `deltaPrice` already accounts for the fee, so the `destAmount` you show users is the net amount.
+
+The fee is collected on-chain at settlement; there is no off-chain accounting step on your side.
+
+## Production tips
+
+- **Load `partner` from an environment variable.** Different builds (staging, production, white-label) can use different keys without code changes.
+- **Audit `partnerAddress`.** Once a swap settles, fees pay to that address on-chain. Treat it like any treasury address.
+- **Don't ship per-call overrides** unless you genuinely vary fees by route or user tier — registering defaults with Velora keeps your client code simpler and lets you adjust fees without redeploying.
## Related pages
+
+- [Pro API accounts](/overview/pro-api-accounts) — register a partner key and set defaults.
+- [Widget → Monetize](/widget/monetize) — same fee mechanics for the embeddable widget.
+- [Modules → Delta](/sdk/modules/delta) — full Delta order flow with partner attribution.
+- [Modules → Swap](/sdk/modules/swap) — full Market-swap flow with partner attribution.
diff --git a/sdk/overview.mdx b/sdk/overview.mdx
index 2acbff5..6e2435f 100644
--- a/sdk/overview.mdx
+++ b/sdk/overview.mdx
@@ -1,15 +1,138 @@
---
title: "SDK overview"
-description: "Use @velora-dex/sdk to integrate quotes, swaps, limit orders, and Delta intents from JavaScript or TypeScript."
-keywords: ["sdk","overview"]
+description: "Use [@velora-dex/sdk](https://www.npmjs.com/package/@velora-dex/sdk) to integrate quotes, swaps, limit orders, and Delta intents from JavaScript or TypeScript."
+keywords: ["sdk", "overview", "typescript", "javascript"]
---
-This page is a stub. Content coming soon.
+`@velora-dex/sdk` is a TypeScript SDK for the Velora API. It wraps the [Market](/market/overview) and [Delta](/delta/overview) endpoints into typed methods, leaves your wallet library (`viem`, `ethers`, or `web3`) and HTTP client (`axios` or `fetch`) up to you, and ships in three construction shapes so you only pay for what you import.
-## When to use this
+## What you get
+
+
+
+ Works with [viem](https://viem.sh), [ethers](https://docs.ethers.org) (v5 or
+ v6), or [web3.js](https://web3js.readthedocs.io) — bring whichever stack you
+ already use.
+
+
+ Three entry points (Simple, Full, Partial) over the same `construct*`
+ primitives. Pick one to import only the methods you call.
+
+
+ 10 KB gzipped for the minimal variant. Tree-shake the rest at build time.
+
+
+
+## Quick example
+
+Fetch a Delta-or-market quote and submit the order in one flow:
+
+```ts
+import axios from "axios";
+import { createWalletClient, custom } from "viem";
+import { mainnet } from "viem/chains";
+import { constructSimpleSDK, txParamsToViemTxParams } from "@velora-dex/sdk";
+
+const walletClient = createWalletClient({
+ chain: mainnet,
+ transport: custom(window.ethereum!),
+});
+const [account] = await walletClient.getAddresses();
+
+const simpleSDK = constructSimpleSDK(
+ { chainId: 1, axios },
+ { viemClient: walletClient, account },
+);
+
+const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
+const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
+const amount = "1000000000000000000";
+
+const quote = await simpleSDK.quote.getQuote({
+ srcToken: DAI,
+ destToken: USDC,
+ amount,
+ userAddress: account,
+ srcDecimals: 18,
+ destDecimals: 6,
+ mode: "all", // try Delta first, fall back to Market
+ side: "SELL",
+ partner: "my-app-name",
+});
+
+if ("delta" in quote) {
+ await simpleSDK.delta.approveTokenForDelta(amount, DAI);
+ const auction = await simpleSDK.delta.submitDeltaOrder({
+ deltaPrice: quote.delta,
+ owner: account,
+ srcToken: DAI,
+ destToken: USDC,
+ srcAmount: amount,
+ destAmount: quote.delta.destAmount, // adjust for slippage in production
+ partner: "my-app-name",
+ });
+} else {
+ const tx = await simpleSDK.swap.buildTx({
+ srcToken: DAI,
+ destToken: USDC,
+ srcAmount: amount,
+ slippage: 250,
+ priceRoute: quote.market,
+ userAddress: account,
+ partner: "my-app-name",
+ });
+ const hash = await walletClient.sendTransaction({
+ ...txParamsToViemTxParams(tx),
+ account,
+ });
+}
+```
## How it works
-## Examples
+All three entry points are thin orchestrators over the same per-method `construct*` factories. Pick the shape that matches how much of the SDK you actually use:
+
+```mermaid
+graph TD
+ A["constructSimpleSDK
(flat: sdk.swap / sdk.delta / sdk.quote)"] --> C
+ B["constructFullSDK
(namespaced, full control)"] --> C
+ D["constructPartialSDK
(cherry-picked, tree-shaken)"] --> C
+ C["construct* feature factories
(GetRate, BuildTx, BuildDeltaOrder, GetQuote, ...)"]
+ C --> E["Fetcher: axios / fetch / custom"]
+ C --> F["Contract caller: viem / ethers v5 / v6 / web3"]
+```
+
+- **Simple** auto-wires the fetcher and contract caller from a single options object — best for quickstarts and server-side scripts.
+- **Full** exposes the same methods namespaced (`sdk.swap.*`, `sdk.delta.*`) but lets you construct the fetcher and caller yourself, including a custom transaction-response type.
+- **Partial** is the tree-shaken variant: pass in only the `construct*` functions you import, and TypeScript infers the resulting SDK shape from your selection.
+
+## Pick your starting point
+
+
+
+ Add `@velora-dex/sdk` and get the first quote in under five minutes.
+
+
+ Simple vs Full vs Partial — bundle size, API shape, when to pick each.
+
+
+ One constructor, sensible defaults, every method available.
+
+
+ Wire up viem, ethers, or web3 — and choose your HTTP client.
+
+
## Related pages
+
+- [Why Velora](/overview/why-velora) — when to reach for the SDK vs the API or widget.
+- [Migration from `@paraswap/sdk`](/resources/migrations/paraswap-sdk-to-velora-sdk) — legacy package → `@velora-dex/sdk`.
+- [API reference](/api-reference/introduction) — the HTTP endpoints the SDK wraps.
diff --git a/sdk/partial-sdk.mdx b/sdk/partial-sdk.mdx
new file mode 100644
index 0000000..9614365
--- /dev/null
+++ b/sdk/partial-sdk.mdx
@@ -0,0 +1,180 @@
+---
+title: "Partial SDK"
+description: "constructPartialSDK lets bundle-size-sensitive apps import only the construct* functions they call; TypeScript infers the resulting SDK shape from the selection."
+keywords:
+ ["sdk", "partial", "constructPartialSDK", "tree-shaking", "bundle-size"]
+---
+
+`constructPartialSDK` is the tree-shaken entry point. You pick which per-method `construct*` factories you care about, and the resulting SDK has only those methods on it. TypeScript infers the return type from your selection, so calls into unused modules don't compile — and the bundler drops the unused code.
+
+## When to pick this
+
+- You're shipping a browser bundle and every kilobyte counts.
+- You only use a small slice of the SDK — e.g. just `getRate` + `approveToken`, or just the Delta signing flow.
+- You want compile-time guarantees that your build doesn't accidentally call a method you didn't intend to ship.
+
+If you use most of the SDK or run server-side, prefer [Simple SDK](/sdk/simple-sdk) or [Full SDK](/sdk/full-sdk).
+
+## Example: rates and approvals only
+
+The smallest useful Partial SDK — read rates from the API, approve tokens for swaps.
+
+```ts
+import axios from "axios";
+import { createWalletClient, custom } from "viem";
+import { mainnet } from "viem/chains";
+import {
+ constructPartialSDK,
+ constructAxiosFetcher,
+ constructViemContractCaller,
+ constructGetRate,
+ constructApproveToken,
+} from "@velora-dex/sdk";
+
+const walletClient = createWalletClient({
+ chain: mainnet,
+ transport: custom(window.ethereum!),
+});
+const [account] = await walletClient.getAddresses();
+
+const fetcher = constructAxiosFetcher(axios);
+const contractCaller = constructViemContractCaller(walletClient, account);
+
+const sdk = constructPartialSDK(
+ {
+ chainId: 1,
+ fetcher,
+ contractCaller,
+ },
+ constructGetRate,
+ constructApproveToken,
+);
+
+// type is inferred from your selection — only these two methods exist
+const priceRoute = await sdk.getRate({
+ srcToken: "0x6B175474E89094C44Da98b954EedeAC495271d0F", // DAI
+ destToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
+ amount: "1000000000000000000",
+ userAddress: account,
+ side: "SELL",
+});
+const hash = await sdk.approveToken(
+ "1000000000000000000",
+ "0x6B175474E89094C44Da98b954EedeAC495271d0F",
+);
+```
+
+## Example: Delta V2 signing only
+
+A front-end that signs Delta V2 orders but does no other reads or writes. V2 constructors live under the `DeltaV2` namespace at the package root:
+
+```ts
+import {
+ constructPartialSDK,
+ constructAxiosFetcher,
+ constructViemContractCaller,
+ constructApproveTokenForDelta,
+ DeltaV2,
+} from "@velora-dex/sdk";
+
+const fetcher = constructAxiosFetcher(axios);
+const contractCaller = constructViemContractCaller(walletClient, account);
+
+const deltaSDK = constructPartialSDK(
+ { chainId: 1, fetcher, contractCaller },
+ DeltaV2.constructGetDeltaPrice,
+ DeltaV2.constructBuildDeltaOrder,
+ DeltaV2.constructSignDeltaOrder,
+ DeltaV2.constructPostDeltaOrder,
+ constructApproveTokenForDelta, // reused from V1 — same contract
+);
+
+const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
+const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
+const amount = "1000000000000000000";
+
+const price = await deltaSDK.getDeltaPrice({
+ srcToken: DAI,
+ destToken: USDC,
+ amount,
+ srcDecimals: 18,
+ destDecimals: 6,
+ userAddress: account,
+ partner: "my-app-name",
+});
+
+await deltaSDK.approveTokenForDelta(amount, DAI);
+
+const built = await deltaSDK.buildDeltaOrder({
+ route: price.route,
+ side: price.side,
+ owner: account,
+ partner: "my-app-name",
+ slippage: 50, // 0.5% in bps
+});
+
+const signature = await deltaSDK.signDeltaOrder(built);
+const auction = await deltaSDK.postDeltaOrder({
+ order: built.toSign.value as any,
+ signature,
+ partner: "my-app-name",
+});
+```
+
+The `DeltaV2` namespace doubles as a runtime object — bundlers tree-shake whichever members you don't reference, so this example pulls in only the four V2 constructors above.
+
+## Available constructors
+
+Pass any combination of these. Methods on the resulting SDK match the names listed in [Simple SDK → Available methods](/sdk/simple-sdk#available-methods). V2 constructors are accessed through the `DeltaV2` namespace (`DeltaV2.constructBuildDeltaOrder`, etc.); V1 constructors are exported bare from the package root.
+
+| Module | Constructors |
+| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **Delta V2** (recommended)| `DeltaV2.constructGetDeltaPrice`, `DeltaV2.constructBuildDeltaOrder`, `DeltaV2.constructSignDeltaOrder`, `DeltaV2.constructPostDeltaOrder`, `DeltaV2.constructSubmitDeltaOrder` (orchestrator), `DeltaV2.constructGetDeltaOrders`, `DeltaV2.constructCancelDeltaOrder`, `DeltaV2.constructGetBridgeRoutes`, `DeltaV2.constructIsTokenSupportedInDelta`, `DeltaV2.constructGetAgentsList`, plus reused from V1: `constructApproveTokenForDelta`, `constructPreSignDeltaOrder`, `constructDeltaTokenModule`, `constructGetDeltaContract`, `constructGetPartnerFee` |
+| External Delta V2 | `DeltaV2.constructBuildExternalDeltaOrder`, `DeltaV2.constructPostExternalDeltaOrder`, `DeltaV2.constructSubmitExternalDeltaOrder` |
+| TWAP Delta V2 | `DeltaV2.constructBuildTWAPDeltaOrder`, `DeltaV2.constructPostTWAPDeltaOrder`, `DeltaV2.constructSubmitTWAPDeltaOrder` |
+| Delta V1 | `constructGetDeltaPrice`, `constructBuildDeltaOrder`, `constructSignDeltaOrder`, `constructPostDeltaOrder`, `constructSubmitDeltaOrder`, `constructApproveTokenForDelta`, `constructPreSignDeltaOrder`, `constructDeltaTokenModule`, `constructGetDeltaContract`, `constructGetDeltaOrders`, `constructCancelDeltaOrder`, `constructGetPartnerFee`, `constructGetBridgeInfo`, `constructIsTokenSupportedInDelta` |
+| External Delta V1 | `constructBuildExternalDeltaOrder`, `constructSignExternalDeltaOrder`, `constructPostExternalDeltaOrder`, `constructPreSignExternalDeltaOrder` |
+| TWAP Delta V1 | `constructBuildTWAPDeltaOrder`, `constructSignTWAPDeltaOrder`, `constructPostTWAPDeltaOrder`, `constructPreSignTWAPDeltaOrder` |
+| Swap | `constructGetRate`, `constructBuildTx`, `constructApproveToken`, `constructGetBalances`, `constructGetSpender`, `constructGetTokens`, `constructGetAdapters`, `constructSwapTx` |
+| Quote | `constructGetQuote` |
+| Limit orders (deprecated) | `constructBuildLimitOrder`, `constructSignLimitOrder`, `constructPostLimitOrder`, `constructCancelLimitOrder`, `constructGetLimitOrders`, `constructApproveTokenForLimitOrder`, `constructGetLimitOrdersContract`, `constructBuildLimitOrderTx`, `constructFillOrderDirectly` |
+
+Note that V1 and V2 expose the same constructor names (`constructBuildDeltaOrder`, etc.) — V2 is just nested inside the `DeltaV2` namespace, which is what lets the two ship side-by-side without collision. The full list lives in [`src/index.ts`](https://github.com/VeloraDEX/sdk/blob/master/src/index.ts).
+
+
+ Several constructors come in pairs — for example,
+ `DeltaV2.constructBuildDeltaOrder` + `DeltaV2.constructSignDeltaOrder` +
+ `DeltaV2.constructPostDeltaOrder`, or `DeltaV2.constructSubmitDeltaOrder`
+ (which orchestrates all three). Use the orchestrator when you want one call;
+ use the individual constructors when you need custom signing (hardware
+ wallet, multisig, deferred submission).
+
+
+## Related pages
+
+
+
+ Side-by-side comparison of Simple, Full, and Partial.
+
+
+ Construct the fetcher and contract caller you'll pass in.
+
+
+ Market-swap walkthrough using individual constructors.
+
+
+ Delta order lifecycle, including the split build/sign/post flow.
+
+
diff --git a/sdk/simple-sdk.mdx b/sdk/simple-sdk.mdx
index 4c3dd08..8860dd2 100644
--- a/sdk/simple-sdk.mdx
+++ b/sdk/simple-sdk.mdx
@@ -1,15 +1,198 @@
---
title: "Simple SDK"
-description: "Use the all-in-one entry point for the common quote-and-swap flow."
-keywords: ["sdk","simple"]
+description: "constructSimpleSDK auto-wires the fetcher and contract caller so one constructor returns a working SDK for quotes, swaps, Delta orders, and approvals."
+keywords: ["sdk", "simple", "constructSimpleSDK", "quickstart"]
---
-This page is a stub. Content coming soon.
+`constructSimpleSDK` is the recommended entry point for most integrators. You pass it a `chainId`, an HTTP client, and (optionally) a wallet — it returns an SDK with every Velora method available under flat namespaces.
## When to use this
-## Quickstart
+- You want one import that exposes the whole API surface.
+- You're fine with the SDK returning transaction hashes (`string`) for write calls, instead of library-typed responses.
+- You don't need to share a single contract caller across multiple SDK instances.
-## Examples
+For tighter control over the transaction-response type or bundle size, use the [Full](/sdk/full-sdk) or [Partial](/sdk/partial-sdk) constructors instead.
+
+## Construct it
+
+Pick your HTTP client. `fetch` keeps the bundle smaller; `axios` is convenient if you already use it.
+
+
+
+```ts axios
+import axios from "axios";
+import { constructSimpleSDK } from "@velora-dex/sdk";
+
+const simpleSDK = constructSimpleSDK({ chainId: 1, axios });
+```
+
+```ts fetch
+import { constructSimpleSDK } from "@velora-dex/sdk";
+
+const simpleSDK = constructSimpleSDK({ chainId: 1, fetch });
+```
+
+
+
+Without a wallet, the SDK is **read-only** — quotes, prices, order status, supported tokens — but cannot approve, sign, or submit.
+
+## Add a wallet
+
+Pass a second argument with your provider to enable write methods (`approveToken`, `signDeltaOrder`, `submitDeltaOrder`, `buildTx`-then-send).
+
+
+
+```ts viem
+import { createWalletClient, custom } from "viem";
+import { mainnet } from "viem/chains";
+
+const walletClient = createWalletClient({
+ chain: mainnet,
+ transport: custom(window.ethereum!),
+});
+const [account] = await walletClient.getAddresses();
+
+const sdk = constructSimpleSDK(
+ { chainId: 1, axios },
+ { viemClient: walletClient, account },
+);
+```
+
+```ts ethers v5
+import { ethers } from "ethers";
+
+const sdk = constructSimpleSDK(
+ { chainId: 1, axios },
+ {
+ ethersProviderOrSigner: signer, // JsonRpcProvider or Wallet
+ EthersContract: ethers.Contract,
+ account,
+ },
+);
+```
+
+```ts ethers v6
+import { ethers } from "ethers";
+
+const sdk = constructSimpleSDK(
+ { chainId: 1, axios },
+ {
+ ethersV6ProviderOrSigner: signer,
+ EthersV6Contract: ethers.Contract,
+ account,
+ },
+);
+```
+
+```ts web3
+import Web3 from "web3";
+
+const sdk = constructSimpleSDK(
+ { chainId: 1, axios },
+ { web3: new Web3(window.ethereum), account },
+);
+```
+
+
+
+
+Write calls always resolve to a **transaction hash** (`string`). If you need the library-typed response object (viem's `Hex`, `ethers.ContractTransaction`, etc.), use [`constructFullSDK`](/sdk/full-sdk) with the `` generic.
+
+
+## Available methods
+
+The returned SDK is namespaced by feature:
+
+| Namespace | What's inside | Module page |
+| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
+| `sdk.deltaV2` | **Recommended.** `getDeltaPrice`, `buildDeltaOrder`, `signDeltaOrder`, `postDeltaOrder`, `submitDeltaOrder`, `approveTokenForDelta`, `preSignDeltaOrder`, `getDeltaContract`, `getDeltaOrderById`, `getDeltaOrderByHash`, `getDeltaOrders`, `cancelDeltaOrders`, `getBridgeRoutes`, `isTokenSupportedInDelta` | [Delta module](/sdk/modules/delta) |
+| `sdk.delta` | Delta V1. Same lifecycle, locally-built orders. See [Delta V1](/sdk/modules/delta#delta-v1). | [Delta module](/sdk/modules/delta#delta-v1) |
+| `sdk.quote` | `getQuote` — V1 Delta-with-fallback-to-Market price (no V2 equivalent yet) | [API → Delta /quote](/api-reference/delta/quote) |
+| `sdk.swap` | `getRate`, `buildTx`, `approveToken`, `getSpender`, `getBalances`, `getTokens`, `getAdapters`, `swapTx` | [Swap module](/sdk/modules/swap) |
+| `sdk.limitOrders` | Deprecated. Build/sign/post/cancel limit orders. | [Limit orders module](/sdk/modules/limit-orders) |
+
+## End-to-end example
+
+Quote, approve, and submit a Delta order in one flow. (Falls back to a Market swap if Delta isn't available for the pair.)
+
+```ts
+import axios from "axios";
+import { createWalletClient, custom } from "viem";
+import { mainnet } from "viem/chains";
+import { constructSimpleSDK, txParamsToViemTxParams } from "@velora-dex/sdk";
+
+const walletClient = createWalletClient({
+ chain: mainnet,
+ transport: custom(window.ethereum!),
+});
+const [account] = await walletClient.getAddresses();
+
+const sdk = constructSimpleSDK(
+ { chainId: 1, axios },
+ { viemClient: walletClient, account },
+);
+
+const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
+const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
+const amount = "1000000000000000000"; // 1 DAI
+
+const quote = await sdk.quote.getQuote({
+ srcToken: DAI,
+ destToken: USDC,
+ amount,
+ userAddress: account,
+ srcDecimals: 18,
+ destDecimals: 6,
+ mode: "all",
+ side: "SELL",
+ partner: "my-app-name",
+});
+
+if ("delta" in quote) {
+ await sdk.delta.approveTokenForDelta(amount, DAI);
+
+ const slippagePercent = 0.5;
+ const destAmount = BigInt(
+ +(+quote.delta.destAmount * (1 - slippagePercent / 100)).toFixed(0),
+ ).toString(10);
+
+ const auction = await sdk.delta.submitDeltaOrder({
+ deltaPrice: quote.delta,
+ owner: account,
+ srcToken: DAI,
+ destToken: USDC,
+ srcAmount: amount,
+ destAmount,
+ partner: "my-app-name",
+ });
+
+ console.log("Delta auction id:", auction.id);
+} else {
+ await sdk.swap.approveToken(amount, DAI);
+
+ const tx = await sdk.swap.buildTx({
+ srcToken: DAI,
+ destToken: USDC,
+ srcAmount: amount,
+ slippage: 250, // 2.5%
+ priceRoute: quote.market,
+ userAddress: account,
+ partner: "my-app-name",
+ });
+
+ await walletClient.sendTransaction({
+ ...txParamsToViemTxParams(tx),
+ account,
+ });
+}
+```
+
+See [Modules → Delta](/sdk/modules/delta) for the split build/sign/post flow and order-status polling (including the recommended Delta V2 path), and [Modules → Swap](/sdk/modules/swap) for the full Market-swap walkthrough.
## Related pages
+
+- [Modules → Swap](/sdk/modules/swap)
+- [Modules → Delta](/sdk/modules/delta)
+- [Configure providers](/sdk/configure-providers)
+- [Monetize](/sdk/monetize)
diff --git a/sdk/testing-integration.mdx b/sdk/testing-integration.mdx
index eae687a..20e7456 100644
--- a/sdk/testing-integration.mdx
+++ b/sdk/testing-integration.mdx
@@ -1,15 +1,121 @@
---
-title: "Testing integration"
-description: "Test your SDK integration against staging endpoints and verify expected behavior."
-keywords: ["sdk","testing","staging"]
+title: "Test your integration"
+description: "Test SDK flows without burning mainnet funds — fork mainnet locally, mock the fetcher for unit tests, and verify partner attribution end-to-end."
+keywords: ["sdk", "testing", "fork", "hardhat", "anvil", "mock", "fetcher"]
---
-This page is a stub. Content coming soon.
+The SDK calls real Velora APIs and real on-chain contracts. To test integrations safely, fork mainnet for end-to-end flows and mock the fetcher for unit tests.
## When to use this
-## Quickstart
+- You're adding the SDK to a project for the first time and want to verify the flow before pointing it at production.
+- You're writing CI tests that should not depend on network connectivity or mainnet balances.
+- You're reproducing a bug a user reported and need a deterministic environment.
-## Examples
+## Fork mainnet for end-to-end tests
+
+Velora's contracts (Augustus router, Delta, AugustusRFQ) deploy to production networks only — there's no testnet deployment. The standard pattern is to fork mainnet (or your target chain) locally and impersonate a funded account.
+
+### Anvil (Foundry)
+
+```bash
+anvil --fork-url https://eth-mainnet.alchemyapi.io/v2/$ALCHEMY_KEY
+```
+
+Connect the SDK to the local RPC and impersonate a known DAI whale:
+
+```ts
+import { createWalletClient, createTestClient, http } from "viem";
+import { mainnet } from "viem/chains";
+import { constructSimpleSDK } from "@velora-dex/sdk";
+
+const account = "0x1111111111111111111111111111111111111111"; // a funded address
+
+const testClient = createTestClient({
+ chain: mainnet,
+ mode: "anvil",
+ transport: http("http://127.0.0.1:8545"),
+});
+await testClient.impersonateAccount({ address: account });
+
+const walletClient = createWalletClient({
+ chain: mainnet,
+ transport: http("http://127.0.0.1:8545"),
+});
+
+const sdk = constructSimpleSDK(
+ { chainId: 1, fetch },
+ { viemClient: walletClient, account },
+);
+
+// run a swap / Delta flow against the fork — real API responses, fake balances
+```
+
+### Hardhat
+
+The SDK's own tests use a Hardhat fork seeded via the `PROVIDER_URL` env var. The same approach works for your integration:
+
+```js
+// hardhat.config.ts
+networks: {
+ hardhat: {
+ forking: { url: process.env.PROVIDER_URL },
+ },
+},
+```
+
+Run with `PROVIDER_URL=https://mainnet... npx hardhat test`. The Velora SDK exposes overrides for impersonation via your provider — see the SDK's [own hardhat config](https://github.com/VeloraDEX/sdk/blob/master/hardhat.config.ts) for a reference.
+
+
+ Forking only spoofs the chain state — quotes still come from the real Velora
+ API. Account-specific endpoints (allowance lookups against the impersonated
+ address) work because the fork's RPC returns the impersonated account's
+ storage.
+
+
+## Mock the fetcher in unit tests
+
+For unit tests that shouldn't touch the network, pass a custom `FetcherFunction` that returns canned responses. The contract caller is still real, but no HTTP request leaves your process.
+
+```ts
+import { constructSimpleSDK, type FetcherFunction } from "@velora-dex/sdk";
+
+const fixtures: Record = {
+ "GET /prices": {
+ priceRoute: { srcAmount: "1000", destAmount: "999" /* ... */ },
+ },
+};
+
+const mockFetcher: FetcherFunction = async ({ url, method }) => {
+ const key = `${method.toUpperCase()} ${new URL(url).pathname}`;
+ if (key in fixtures) return fixtures[key];
+ throw new Error(`unexpected request: ${key}`);
+};
+
+const sdk = constructSimpleSDK({ chainId: 1, fetcher: mockFetcher });
+
+const rate = await sdk.swap.getRate({
+ srcToken: "0x...",
+ destToken: "0x...",
+ amount: "1000",
+ userAddress: "0x...",
+});
+expect(rate.destAmount).toBe("999");
+```
+
+This pattern is also handy in CI — every test is deterministic and runs offline.
+
+## Debugging tips
+
+- **Check `partner`.** A missing or unknown partner key surfaces as `400` on quote/order endpoints. Confirm it's set on every SDK call and matches the partner registered with Velora.
+- **Confirm `chainId` matches the connected wallet.** Mismatched chains throw on signing — the EIP-712 domain includes `chainId`.
+- **Log raw fetcher calls.** Wrap your fetcher to log `{url, method, status, durationMs}` while developing — the SDK's internal retries and partner-fee resolution can issue requests you don't expect.
+- **Watch Delta status transitions.** A Delta order goes `OPEN` → `ACCEPTED` → `EXECUTED` (or `CANCELLED` / `EXPIRED`). If it sticks at `OPEN` for more than a minute, see [Order lifecycle and status codes](/delta/order-lifecycle-and-status-codes) and [Handling stuck orders](/guides/handling-stuck-orders).
+- **Verify the spender.** For Market swaps the user approves `getSpender()` (`TokenTransferProxy`). For Delta the user approves `getDeltaContract()`. Approving the wrong contract is the most common cause of `INSUFFICIENT_ALLOWANCE`.
## Related pages
+
+- [Troubleshooting](/api-reference/troubleshooting) — known failure modes per endpoint.
+- [Debug failed transactions](/guides/debug-failed-transactions) — generic on-chain debugging.
+- [Handling stuck orders](/guides/handling-stuck-orders) — Delta-specific recovery.
+- [Configure providers](/sdk/configure-providers) — fetcher and caller setup.
diff --git a/snippets/failure-modes/delta-v2-orders-build.mdx b/snippets/failure-modes/delta-v2-orders-build.mdx
new file mode 100644
index 0000000..4acb2de
--- /dev/null
+++ b/snippets/failure-modes/delta-v2-orders-build.mdx
@@ -0,0 +1,10 @@
+| Symptom | Root cause | Fix |
+|---|---|---|
+| 400 `route` validation failed | `route` object was mutated, re-stringified, or had numeric fields cast to numbers (they're strings) | Pass `route` from [GET /delta/v2/prices](/api-reference/delta-v2/prices) **verbatim** — don't normalize, sort, or re-encode amounts |
+| 400 `InvalidTWAPParams` / `InvalidTWAPBuyParams` | TWAP / TWAPBuy without `interval`, `numSlices`, and a totals field | Provide all four: `interval` (seconds, ≥ 60), `numSlices` (≥ 2), `totalSrcAmount` (TWAP), or `totalDestAmount` + `maxSrcAmount` (TWAPBuy) |
+| 400 `InvalidTWAPSrcAmount` / `InvalidTWAPBuyDestAmount` | Slice amount in `route.origin` doesn't equal `floor(total / numSlices)` | Re-quote per slice with `amount = floor(total / numSlices)` and pass the totals separately; non-divisible remainders are intentional and you can't ship slice×n |
+| 400 `InvalidExternalOrderParams` | `orderType: ExternalOrder` without `handler` and `data` | Encode handler-specific bytes into `data` and pass the on-chain handler address as `handler` |
+| 400 `InvalidProductiveOrderParams` | `orderType: ProductiveOrder` without `strategy` | Pass the on-chain strategy address as `strategy` |
+| `slippage` results in much worse fills than expected | Slippage is in **basis points**, not percent: `100` = 1.00%, not 100% | Convert mental percent to bps: 0.5% → `50`, 1% → `100`, 5% → `500` (max `10_000` = 100%) |
+
+Updated from support tickets at each release. Last updated: 2026-05-27.
diff --git a/snippets/failure-modes/delta-v2-orders-cancel.mdx b/snippets/failure-modes/delta-v2-orders-cancel.mdx
new file mode 100644
index 0000000..8741acc
--- /dev/null
+++ b/snippets/failure-modes/delta-v2-orders-cancel.mdx
@@ -0,0 +1,8 @@
+| Symptom | Root cause | Fix |
+|---|---|---|
+| 400 `Invalid signature` | Cancellation EIP-712 typed data assembled wrong (wrong chainId or wrong domain) | Sign the relayer's cancel payload — the SDK's `signCancelDeltaOrderRequest` handles this for you |
+| 400 `Order already settled` | One or more `orderIds` are in a terminal state (`COMPLETED`, `FAILED`, `EXPIRED`, `CANCELLED`) | Pre-filter `orderIds` to those with status in `PENDING` / `AWAITING_SIGNATURE` / `ACTIVE` / `SUSPENDED` |
+| 200 OK but order doesn't move to `CANCELLING` | An auction had already started for that order — cancellation queues but won't kill an in-flight fill | Wait one polling interval; the order moves to `CANCELLED` once the relayer confirms |
+| 400 `orderIds.length > 100` | Tried to batch-cancel too many in one call | Chunk into batches of ≤ 100 |
+
+Updated from support tickets at each release. Last updated: 2026-05-27.
diff --git a/snippets/failure-modes/delta-v2-orders-submit.mdx b/snippets/failure-modes/delta-v2-orders-submit.mdx
new file mode 100644
index 0000000..1e8485c
--- /dev/null
+++ b/snippets/failure-modes/delta-v2-orders-submit.mdx
@@ -0,0 +1,10 @@
+| Symptom | Root cause | Fix |
+|---|---|---|
+| 400 `Invalid signature` | Signed payload doesn't match `order` byte-for-byte | Sign `toSign` from `POST /delta/v2/orders/build` exactly; pass `order: toSign.value` to submit (not the whole `toSign` object) |
+| 400 `Order expired` | Long pause between build and submit; `deadline` already passed when relayer validated | Rebuild on submit-time, or pass a longer `deadline` (seconds since epoch) at build |
+| 400 `InsufficientAllowance` | User approved the wrong spender — usually the Augustus router instead of the Delta contract | Approve `route.spender` (returned by `GET /delta/v2/prices`) — the Delta contract, not Augustus |
+| 400 `InsufficientBalance` | Source-token balance dropped between price and submit | Re-quote and rebuild; show the user a fresh balance before signing |
+| 200 OK then stuck at `PENDING` | No agent bid the auction (size, pair, or chain) within the window | Poll [GET /delta/v2/orders/{orderId}](/api-reference/delta-v2/orders-get-by-id); cancel via [POST /delta/v2/orders/cancel](/api-reference/delta-v2/orders-cancel) and re-quote if past your SLA |
+| Order transitions to `SUSPENDED` | Allowance was revoked or balance moved post-submission | Re-approve and the relayer will pick the order back up; see [Order lifecycle](/delta/order-lifecycle-and-status-codes) |
+
+Updated from support tickets at each release. Last updated: 2026-05-27.
diff --git a/snippets/failure-modes/delta-v2-prices.mdx b/snippets/failure-modes/delta-v2-prices.mdx
new file mode 100644
index 0000000..f740fca
--- /dev/null
+++ b/snippets/failure-modes/delta-v2-prices.mdx
@@ -0,0 +1,10 @@
+| Symptom | Root cause | Fix |
+|---|---|---|
+| 400 `No route` for a same-chain pair | Token pair has no liquidity, or `srcDecimals` / `destDecimals` are wrong | Re-check decimals against the token contract; try `mode=ALL` on [GET /quote](/api-reference/delta/quote) to see whether Market can route it |
+| 400 `No route` for a crosschain pair | `destChainId` lane not supported by any active bridge for this token | Call [GET /delta/v2/prices/bridge-routes](/api-reference/delta-v2/bridge-routes) to see which lanes + tokens are supported |
+| `route.bridge` is `null` on a crosschain quote | `srcToken` and `destToken` happen to be the same address on different chains and the bridge collapsed | Compare `route.origin.input.token.chainId` vs `route.destination.output.token.chainId` directly; don't infer crosschain from `bridge !== null` alone |
+| `alternatives` is empty | Same-chain quotes never return alternatives — only crosschain | Use `route` directly for same-chain; check `alternatives.length > 0` before showing a bridge picker |
+| `partner.feePercent` higher than expected | Registered partner fee + `partnerFeeBps` override compounded | Set `partnerFeeBps=0` (or omit) to use the registered fee only; passing both stacks them |
+| 400 `Token not supported` | One of `srcToken` / `destToken` isn't whitelisted on `chainId` | Call [GET /delta/v2/prices/is-token-supported](/api-reference/delta-v2/is-token-supported) before quoting |
+
+Updated from support tickets at each release. Last updated: 2026-05-27.