Skip to main content
An OTC trade settles a deal between two known counterparties: a maker signs an AugustusRFQ order off-chain naming a specific taker, posts it to the API, and only that taker can fill it on-chain. This page walks the whole integration end to end, both sides: the maker approves, signs, and posts; the taker approves and fills. Every REST call targets https://api.velora.xyz. OTC is for bilateral, counterparty-specific trades. For an open, target-price order that any solver can fill, gasless and MEV-protected, use a Delta limit order instead. For the conceptual model, see Product stack → OTC; for in-depth field, state, and endpoint detail, see the OTC API reference; for a typed wrapper, see SDK → OTC.

The flow

1

Maker approves AugustusRFQ

The maker approves the AugustusRFQ contract to pull the makerAsset. It’s a separate contract from the Augustus v6.2 router. Native ETH must be wrapped first.
2

Maker sizes and signs

Size against GET /ft/fillablebalance, then build the order fields and sign the EIP-712 typed data.
3

Maker posts the order

POST /ft/p2p/{chainId}/ with the order and signature. The server returns the stored order with its orderHash. See post order.
4

Deliver to the taker

Hand the signed order to the taker over any channel: your backend, the listing endpoints, or directly.
5

Taker fills on-chain

The taker approves AugustusRFQ for the takerAsset, then calls AugustusRFQ.fillOrder on-chain. This is a transaction, not a REST call.

1. Maker: approve and size

The maker approves AugustusRFQ for the makerAsset they’re selling. Then size the order against the maker’s fillable balance: the amount reserved by open orders:
curl 'https://api.velora.xyz/ft/fillablebalance/1/0xMAKER?token=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
AugustusRFQ addresses per chain are in Chains & contracts.

2. Maker: build and sign

The maker builds the order fields and signs them as EIP-712 typed data. The taker field is what makes this bilateral: name an address and only that address can fill; leave the zero address to let anyone fill. The order fields are nonceAndMeta, expiry, makerAsset, takerAsset, makerAmount, takerAmount, maker, and taker. The signing domain is:
{
  "name": "AUGUSTUS RFQ",
  "version": "1",
  "chainId": 1,
  "verifyingContract": "0x... (the AugustusRFQ address for this chain)"
}
makerAsset and takerAsset must be ERC-20s. To sell native ETH, wrap it to WETH first.

3. Maker: post the order

curl -X POST 'https://api.velora.xyz/ft/p2p/1/' \
  -H 'Content-Type: application/json' \
  -d '{
    "nonceAndMeta": "...",
    "expiry": 1893456000,
    "makerAsset": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "takerAsset": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
    "makerAmount": "10000000000",
    "takerAmount": "3000000000000000000",
    "maker": "0xMAKER",
    "taker": "0xTAKER",
    "signature": "0x..."
  }'
Posting stays off-chain, so the maker pays nothing. The response is the stored order with its orderHash and state. Pass permitMakerAsset instead of a separate approval if the makerAsset supports permit. See post order.

4. Deliver, then the taker fills

Hand the signed order to the taker over any off-chain channel, or let them find it through the listing endpoints: maker orders and orders addressed to a taker:
curl 'https://api.velora.xyz/ft/p2p/1/taker/0xTAKER'
The taker approves AugustusRFQ for the takerAsset, then fills on-chain by calling AugustusRFQ.fillOrder with the order and signature. This settles atomically; the fill reverts if the order is expired, already filled, or the caller isn’t the named taker. Always re-check expiry against the current block first. From the SDK, sdk.otcOrders.fillOTCOrder encodes and submits this transaction for you.

Cancelling

There’s no cancel endpoint. The maker cancels by sending a transaction to AugustusRFQ (cancelOrder(bytes32) or cancelOrders(bytes32[])), so cancellation costs gas. This is the one place OTC differs sharply from Delta’s gasless cancel. For a short-lived order, letting it lapse past its expiry is often cheaper than an explicit cancel. Once the cancel is indexed, the order’s state flips to CANCELLED.

Order states and detail

An order reports DRAFT, PENDING, FULFILLED, CANCELLED, SUSPENDED, or EXPIRED. Fetch one with GET /ft/order/{orderHash}. For the full field semantics, state machine, and per-chain availability, see the OTC API reference.
Last modified on June 10, 2026