Skip to main content
Skip to main content

Your first trade

This is the golden path for a taker: one manually accepted RFQ, driven over the REST API with live updates from the WebSocket API. The calls below run against the production host, rfq-api.silhouette.exchange; see Signing requests for the hmac_headers helper the REST calls below rely on.

1. Mint credentials

Follow the login flow: request a nonce with POST /v1/auth/challenge, sign the SIWE message with your wallet, and submit it to POST /v1/auth/api-keys. Keep the returned accessKey and secret; the secret is shown once.

2. Connect the socket and subscribe

Open wss://rfq-api.silhouette.exchange/v1/rfq/ws, authenticate with an auth frame (the credential pair signs a canonical GET /v1/rfq/ws), then subscribe to your RFQ statuses and the competing quotes on them:

{ "kind": "auth", "accessKey": "<access-key>", "signedAt": 1769600000000, "signature": "<base64-hmac>" }

The server confirms with { "kind": "health", ... }. Then:

{ "kind": "subscribe", "topic": "rfqStatus" }
{ "kind": "subscribe", "topic": "quotes" }

Each is acknowledged with a subscribed frame echoing the topic.

3. Submit the RFQ over REST

Buy 0.5 XTSLA for at most 1000 USDC, with a 30-second quote window:

curl https://rfq-api.silhouette.exchange/v1/rfq/requests \
--request POST \
--header "Content-Type: application/json" \
# plus the three signed headers from hmac_headers
--data '{
"instrumentId": "XTSLA-USDC-SPOT",
"side": "BUY",
"baseQty": "0.5",
"quoteLimit": "1000",
"windowMs": 30000,
"idempotencyKey": "0193b6f1-7c10-7d6c-8000-abc123456789"
}'

The 202 response carries the RFQ's identity and the auction deadline the clamp settled on:

{ "rfqId": "rfq_...", "status": "PENDING", "auctionEndsAt": 1769600030000 }

4. Watch the quotes stream in

As makers respond, the quotes subscription pushes a quoteUpdate frame per competing quote. takerTotal is the all-in amount you would pay:

{
"kind": "quoteUpdate",
"rfqId": "rfq_...",
"quoteId": "qt_...",
"status": "SUBMITTED",
"takerTotal": "992.50",
"receivedAt": 1769600005000,
"acceptableForMs": 30000
}

acceptableForMs is the maker's own window, counted from receivedAt; it is absent when the maker named none, and the quote then stands until the auction closes.

5. Accept the best quote

Before the auction ends, accept over REST:

curl https://rfq-api.silhouette.exchange/v1/rfq/requests/rfq_.../accept \
--request POST \
--header "Content-Type: application/json" \
# plus the three signed headers from hmac_headers
--data '{ "quoteId": "qt_..." }'

6. Watch it settle

The rfqStatus subscription streams each transition. Acceptance moves the RFQ to QUOTED while settlement is in progress, and settlement completes it:

{ "kind": "rfqStatus", "id": "rfq_...", "status": "SETTLED", "txHash": "0x..." }

A trade is an RFQ in SETTLED, carrying its settlement transaction hash. If nothing conforming arrived, or you let the deadline pass, the RFQ ends CANCELLED instead and any locked funds are released. The lifecycle table covers every outcome.

That is the whole loop: REST for every action, the socket for everything that happens in between. From here, read balances with GET /v1/rfq/balances (or subscribe to balances), and explore the full surface in the API Reference.