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

Authentication

Turbine supports two types of authentication: SIWE and EIP-712

Session-Based SIWE Authentication

Turbine authenticates users with sessions. The session ID arrives in a Set-Cookie response header. Send id=<SESSION_ID> as a cookie with each subsequent request.

Check Authentication Status

Make a GET request to /api/me (see the Swagger UI). Include the session ID in a Cookie header if you have one.

curl 'https://staging-api.turbine.exchange/api/me' \
  -H 'content-type: application/json' \
  -b 'id=<SESSION_ID>'

A 200 OK response means you are authenticated.

A 401 Unauthorized response means you must authenticate.

Authenticate

1

Get nonce

Make a POST request to /api/nonce (see the Swagger UI).

curl 'https://staging-api.turbine.exchange/api/nonce' \
  -X 'POST'

The response contains a nonce, for example:

"uE6LoICEKw01JjApm"
2

Sign a SIWE message

Turbine uses the Sign-In With Ethereum (SIWE) standard.

Sign a specific message containing the nonce with your Ethereum wallet.

The message format is:

app.turbine.exchange wants you to sign in with your Ethereum account:
<YOUR_WALLET_ADDRESS>

Sign in to Turbine with your Ethereum wallet

URI: https://api.turbine.exchange/api
Version: 1
Chain ID: 1
Nonce: <YOUR_NONCE>
Issued At: <TIMESTAMP>
3

Verify the signature

Make a POST request to /api/verify (see the Swagger UI).

The body must contain the signed message and the signature:

{
    "message": "...message with newlines represented as \n...",
    "signature": {
        "r": "0x...",
        "s": "0x...",
        "yParity": "0x...",
        "v": "0x..."
    }
}

If verification passes, the response includes a Set-Cookie header with session ID id=....

Make an Authenticated Request

Include a Cookie header with id=<YOUR_SESSION_ID> in subsequent requests. For example, check your authentication status again with /api/me.

Session Expiration

A session is valid for 5 minutes.

Keep it active by making authenticated requests before it expires, for example by calling /api/me. Each call before expiration extends the session by another 5 minutes.

EIP-712 Authentication

Authenticate by signing each message according to EIP-712 standard. No session, no cookies. Useful for automated workflows.

Endpoints supporting EIP-712

Endpoints that support EIP-712 authentication have an /api/eip712/ prefix.

Each endpoint that requires authentication has an EIP-712 sibling. E.g. there is /api/add_order that supports SIWE authentication and /api/eip712/add_order that supports EIP-712 authentication.

See API Specification for the list of all endpoints.

Construct a Request Body

Body of a request to each EIP-712 endpoint has the following structure:

What to put in `signature`?

For each EIP-712 endpoint, there is a specific struct to sign.

In most cases, the signed struct consists of all payload's fields + deadline and nonce.

The exact structs are defined in a Solidity code snippet below.

Signed Types definitions
endpoint
struct to sign

add_order

AddOrder

add_orders

sign one AddOrder per submitted order

cancel_order

CancelOrder

orders

QueryOrders

add_liquidity

AddLiquidityEip712

remove_liquidity

RemoveLiquidityEip712

liquidity_intents

QueryLiquidityIntents

Examples

The Typescript SDK handles EIP-712 authentication for you. These examples show how to do it manually.

Submitting an Order

Submit an order via /api/eip712/add_order using Typescript and viem.

The response contains the order hash (yours will be different):

Listing Orders

Look up your orders via /api/eip712/orders using only shell tools: Foundry's cast, curl and jq.

In this example, we'll request just a single order by its hash.

Build the QueryOrders typed data. The domain comes from /api/config (field eip712Domain):

Sign it and split the 65-byte signature into r, s and yParity:

Send the envelope. The payload must match the signed message exactly, minus nonce and deadline, which move to auth:

The response contains the matching orders, including their details:

auth.nonce is a decimal string on the wire, but a uint64 number in the signed message — both must hold the same value.

Last updated

Was this helpful?