UNIFY / DEVELOPERS

Developers: quotes & integration

Integrate Unify quotes and reviewed unsigned swap plans through an authenticated API, or embed the read-only widget.

Quote-only widget

Embed indicative quotes without requesting wallet signatures. The widget cannot approve tokens, execute swaps or connect a wallet. Users open the full Unify app to review a fresh route.

<iframe src="https://unifyroutes.com/embed" title="Unify quote comparison" width="420" height="860" style="max-width:100%;border:0;border-radius:16px" loading="lazy"></iframe>

Or load the small web component:

<script type="module" src="https://unifyroutes.com/unify-widget.js"></script>
<unify-quote-widget from-chain="8453" from-token="0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" to-chain="1" to-token="0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" amount="10" preference="balanced" height="900"></unify-quote-widget>

Configure from-chain, from-token, to-chain, to-token, amount, preference and height. The widget accepts exact catalog contracts, including reviewed Base stock metadata; unknown tokens cannot be injected through its URL. Stock quantities use token base units, not share-equivalent display units. Settings never contain a wallet address or execution authorization.

No private API credential belongs in a browser or iframe URL.

Authenticated server-side API

The private API supports individual and portfolio quotes and verification. Integrator access requires an operator-issued partner credential; it is separate from the same-origin public app proxy. The internal container credential is not an integration key.

POST /v1/quotes
X-API-Key: <server-side partner credential>
Content-Type: application/json

{
  "account": "<public signing address>",
  "recipient": "<public receiving address>",
  "from": { "chainId": 8453, "address": "<exact source token>", "amountRaw": "1000000" },
  "to": { "chainId": 1, "address": "<exact destination token>" },
  "slippageBps": 50,
  "routingPolicy": "net"
}

Preferences: balanced (Smart), net, fast, simple. Smart only trades up to 0.05% and $0.01 of estimated net value for a bridge at least twice as fast; the protected floor has the same 0.05% bound. Unknown duration falls back to net ranking. Verify the selected quote before signing; do not change its recipient, spender or protected minimum. Availability and API rate limits are enforced, not a support promise for every pair.

Read-only JavaScript SDK

Import the dependency-free ESM client on your server. It supports quote, portfolioQuote, compare, sources, chains, verify and verifyPortfolio, with bounded timeouts, cancellation and exact quote binding. It never connects a wallet or submits a transaction. Partner keys require operator provisioning and are rejected in browser contexts.

import { createUnifyClient } from "./unify-sdk.js";

// In a browser, use your own server endpoint or the isolated iframe.
// On the server, download the ESM module above and keep the partner key secret.
const unify = createUnifyClient({
  baseUrl: "<operator-provided authenticated API origin>",
  apiKey: process.env.UNIFY_PARTNER_API_KEY
});
const quote = await unify.quote(request, { signal, idempotencyKey: "my-quote-0001" });
const check = await unify.verify(quote.quoteId, {
  mode: quote.winner.mode, pathKey: quote.winner.pathKey
});
// check.valid is informational, not permission to change the minimum.

Download the ESM client →

Extra market comparisons and source inventory

GET /v1/route-sources reports enabled comparison adapters, app partners and adapters requiring credentials or further integration. The public LlamaSwap source inventory informs the list; it is not a promise that every historical adapter works today.

POST /v1/route-comparisons accepts the same exact-input request as /v1/quotes, for same-network DEX pairs. KyberSwap, Velora, OpenOcean and CoW Swap are queried with bounded concurrency and provider timeouts. Optional 0x and 1inch credentials stay on the server. One provider failure does not remove other results. CoW prices require ERC-20 pairs on its documented endpoints; they are not signed orders.

Rows are price-only, unranked estimates. Missing gas or fee coverage stays unknown; there is no invented best-net winner. Issuer transfer permissions and wallet simulation are not certified. These rows contain no execution calldata and cannot replace a reviewed Unify route. Robinhood and Arc are not assumed to be supported by external providers.

Evidence and integration checklist

Test quote expiry, no-route responses, issuer restrictions, wallet rejection, partial portfolio execution and bridge recovery. Treat estimated durations as provider reports. Published scorecards are quote-only; actual delivery measurements require verified receipts.

Read status and measurement notes → · Read safeguards →

Typed integration and live quota

OpenAPI 3.1 contract → · TypeScript definitions → · ESM SDK →

Place the .d.ts beside the downloaded .js module. The SDK includes progressive quotes, immutable candidate callbacks, wallet-owned plans, exact receipt recording and current-window quota. There is no server signing or automatic wallet approval.

const quote = await unify.streamQuote(request, {
  signal,
  onCandidate: candidate => showReadOnlyEstimate(candidate)
});
// Review the final result; early estimates never authorize execution.
const usage = await unify.usage();
// usage.quota: limit, used, remaining, resetsAt, shared
// Keep partner credentials on your server; never ask users to paste them.
const saved = await unify.plans(account, { authorization: walletSession });

A server-only reference quota dashboard and integration examples are included in the repository. Current quota is request units, not historical billing; discovery and plan actions still require the matching authentication.

Signed plan progress notifications

Operators can configure one private HTTPS webhook recipient with UNIFY_PLAN_WEBHOOK_URL and UNIFY_PLAN_WEBHOOK_SECRET. Events expose plan ID, version and per-source status, not wallet addresses or balances. Verify x-unify-timestamp and the SHA-256 HMAC over timestamp + "." + the exact raw request body; reject old events and deduplicate x-unify-event-id.

Notifications coalesce to recent plan versions and may be redelivered. They never prove settlement or authorize a trade. Poll the authenticated plan endpoint for canonical state. PostgreSQL preserves notification delivery state across restarts; remote partners cannot register arbitrary callback URLs.

Reviewed unsigned swap plans

POST /v1/quotes/{quoteId}/execution-plan prepares the exact reviewed mode and pathKey after a fresh quote. Supported single-router ERC-20 swaps: V2, direct and multihop Uniswap V3, Pancake V3, Solidly and Slipstream. Native-token, bridge and split execution plans are not exposed by this endpoint; existing Convert routes remain available.

const plan = await unify.executionPlan(quote);
// Inspect plan.status, plan.checks and each unsigned transaction.
// Your wallet signs; Unify never signs or broadcasts.
// After approvals, prepare a new plan before the swap.

Keep unsigned-plan-guard.js beside unify-sdk.js when distributing the bundled SDK. Its decoder checks the sender, recipient, allowlisted router, exact input, minimum output and bounded approvals. The extra module loads only when executionPlan is requested; ordinary quotes and the widget remain read-only.

Snapshots verify deployment and pool mappings. Funded, approved accounts receive a real eth_call simulation; missing approvals or funds are explicitly not simulated. Plans expire within 30 seconds, and wallet-side simulation is required immediately before signing. Regression and read-only live tests are not a third-party security audit or a funded execution guarantee.

Portfolio distribution and stock directions

The widget supports up to eight distinct source assets and one target. Add sources interactively or pass a public sources JSON attribute with chainId, exact address and decimal amount; never put an account or private credential in this configuration.

const plans = await unify.portfolioPlans({
  account, recipient, sources, to,
  slippageBps: 50, routingPolicy: "net"
});
// plans.baseline: individual quotes
// plans.collections: optional net-improving source collections
// Advisory only; no transaction calldata or execution authorization.

const stocks = await unify.stockQuotes({
  chainId: 8453, stockAddress, account,
  buyAmountRaw: "10000000", // stablecoin input units
  sellAmountRaw, // stock token base units, not share display units
  slippageBps: 50
});

POST /v1/portfolio-plans performs additional bounded comparisons. Standard portfolio quotes stay fast and do not run these extra checks automatically. Buy/sell stock checks are separate quotes; unknown issuer availability remains an unavailable check, not proof of absent liquidity.

Independent RFQ: experimental, not live

An exact-input EIP-712 maker-order validator and a local-test ERC-20 RFQ executor are available in the source repository. GET /v1/rfq-capabilities reports its status; POST /v1/rfq-preview validates signed orders only against operator-owned manifests. No execution calldata is returned.

The new executor is unaudited and has not been deployed for live funds. RFQ is not selected by Convert and cannot be enabled by a remote quote flag. An independent security review, reviewed runtime deployment and funded makers are required before a separate production integration.

Network-specific route guides

Base · Robinhood Chain · Arbitrum · Arc

Base stock-token contracts and checks · Robinhood stock buy/sell checks

Quote, select, verify, then execute

  1. Request a fresh quote using raw integer token amounts and exact contracts. Amount strings are base units, not display amounts.
  2. Inspect the winner and alternatives, including pathKey, mode, estimatedAmountRaw, minimumAmountRaw, fees and expiresAt.
  3. Keep the selected path and the complete review context. Reuse neither an expired quote nor an unrelated recipient or amount.
  4. Verify the selected candidate before proceeding. Verification re-quotes; it does not send a wallet transaction.
  5. Use the full app and the appropriate supported executor for authorization and settlement. The quote API and widget do not execute a move for you.
POST /v1/quotes/<quoteId>/verify
X-API-Key: <server-side partner credential>
Content-Type: application/json

{ "mode": "<selected mode>", "pathKey": "<selected pathKey>" }

A successful verification does not reserve liquidity or provide a permanent execution guarantee. Keep the reviewed minimum and recheck the wallet account, network and recipient.

Portfolio quotes and partial results

POST /v1/portfolio-quotes accepts 1–8 distinct source assets, one destination, an account, optional recipient, slippageBps and routingPolicy. It quotes independent assets with bounded concurrency and reports failures per asset. A partial response is not authorization to pretend every source succeeded.

POST /v1/portfolio-quotes
X-API-Key: <server-side partner credential>
Content-Type: application/json

{
  "account": "<public signing address>",
  "recipient": "<public receiving address>",
  "sources": [
    { "chainId": 8453, "address": "<source contract>", "amountRaw": "1000000" },
    { "chainId": 1, "address": "<source contract>", "amountRaw": "2000000" }
  ],
  "to": { "chainId": 8453, "address": "<destination contract>" },
  "slippageBps": 50,
  "routingPolicy": "net"
}

Inspect status, quotedCount, failedCount, routes, failures and totals. Already-held amounts are reported separately when the signer is also the receiving wallet. POST /v1/portfolio-quotes/<quoteId>/verify rechecks a complete portfolio quote; it does not certify a partial portfolio as fully executable.

Errors, retries and idempotency

ResponseMeaningHandling
400Invalid or mismatched request.Correct the input; do not retry unchanged.
401 / 403Credentials, access or origin requirements failed.Check server-side partner configuration; never expose secrets in browser code.
404Unknown or expired verification quote.Fetch a new quote and review it.
409Protected route changed, or idempotency context conflicts.Review a new quote; do not silently relax its minimum.
422No validated route for this request.Compare another amount or destination; no path is guaranteed.
429Request limit reached.Back off and respect Retry-After when supplied.
503Quote or verification could not complete.Use bounded retries for read-only requests; do not replay a wallet submission.

Quote creation supports an Idempotency-Key of 8–128 letters, digits, underscores, colons or hyphens. The same key cannot be reused for a different request or route preference. Idempotency applies to quote requests, not an on-chain transaction guarantee.

Integration boundaries

Security checklist → · Cost semantics → · Published observations →