Skip to content

Quickstart

Network & Compatibility

Resource Value
API base URL https://api.sera.cx/api/v1
Chain Ethereum mainnet (chainId 1)
Sera contract 0xB5C50C5D5f038404F85970b7f5B7259C4AC0E198
Vault contract 0xC7d4Fd2638e6630C8C61329878676b88A8A24D43
SOR contract 0xa7A0cf7cd6f043fCA23f29d8ae5aae6b46e11c18

Signing primitives. Every trading mutation is an EIP-712 typed-data signature against the Sera domain. Deposits that take the permit path use the ERC-2612 Permit extension — supported by USDC, EURC, and many modern stablecoins, not all ERC-20s; call GET /permit/metadata to check support before signing. API-key management uses an EIP-712 ManageApiKey payload.

Tested clients. Python eth_account >= 0.10 + requests; TypeScript ethers v6 (signer.signTypedData). Browser wallets confirmed working with EIP-712 typed data: MetaMask, Rabby, Frame, Coinbase Wallet, Trust, Rainbow. Safe multisigs work via EIP-1271 (the message is verified on-chain rather than via ecrecover).

Address casing. Read endpoints (/balances, /orders, /fills) treat owner_address as case-sensitive — pass the lowercase form. EIP-712 signed payloads accept EIP-55 checksum addresses.

This guide walks you through your first interaction with Sera — from querying available tokens to placing your first swap.

Prerequisites

  • An Ethereum wallet (e.g., MetaMask)
  • ETH on Ethereum mainnet for deposits, withdrawals, and limit-order settlement (swap-only flows do not require ETH).

Step 1: Explore Available Tokens

Query the token registry to see what stablecoins are available:

curl https://api.sera.cx/api/v1/tokens
import requests

response = requests.get("https://api.sera.cx/api/v1/tokens")
tokens = response.json()["tokens"]
print(tokens)
const response = await fetch("https://api.sera.cx/api/v1/tokens");
const { tokens } = await response.json();
console.log(tokens);

Step 2: Get a Swap Quote

Get a quote to swap between two tokens:

curl -X POST https://api.sera.cx/api/v1/swap/quote \
  -H "Content-Type: application/json" \
  -d '{
    "from_token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "to_token": "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
    "from_amount": "1000000000",
    "owner_address": "0xYOUR_ADDRESS",
    "recipient": "0xYOUR_ADDRESS",
    "expiration": 1735689600,
    "gas_mode": "receive_less"
  }'
import time, requests

quote = requests.post(
    "https://api.sera.cx/api/v1/swap/quote",
    json={
        "from_token":     "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",  # USDC
        "to_token":       "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",  # EURC
        "from_amount":    "1000000000",                                  # 1000 USDC (6 dec)
        "owner_address":  "0xYOUR_ADDRESS",
        "recipient":      "0xYOUR_ADDRESS",
        "expiration":     int(time.time()) + 3600,
        "gas_mode":       "receive_less",
    },
    timeout=10,
).json()
print(quote)
const response = await fetch("https://api.sera.cx/api/v1/swap/quote", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    from_token:    "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",   // USDC
    to_token:      "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",   // EURC
    from_amount:   "1000000000",                                    // 1000 USDC (6 dec)
    owner_address: "0xYOUR_ADDRESS",
    recipient:     "0xYOUR_ADDRESS",
    expiration:    Math.floor(Date.now() / 1000) + 3600,
    gas_mode:      "receive_less",
  }),
});
const quote = await response.json();
console.log(quote);

The response includes a uuid and route_params — these are the parameters you'll sign with your wallet.

Step 3: Sign and Execute the Swap

Sign the route_params using EIP-712 typed data signing, then submit:

from eth_account import Account
from eth_account.messages import encode_typed_data

# `domain` and `INTENT_TYPES` are documented under Authentication
signable  = encode_typed_data(domain, INTENT_TYPES, quote["route_params"])
signature = Account.from_key(PRIVATE_KEY).sign_message(signable).signature.hex()

submit = requests.post(
    "https://api.sera.cx/api/v1/swap",
    json={"uuid": quote["uuid"], "signature": "0x" + signature.lstrip("0x")},
    timeout=10,
).json()
// `domain` and `INTENT_TYPES` are documented under Authentication
const signature = await signer.signTypedData(domain, INTENT_TYPES, quote.route_params);

const result = await fetch("https://api.sera.cx/api/v1/swap", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ uuid: quote.uuid, signature }),
});

Quotes are single-use. If submission fails after the quote is consumed, request a fresh quote instead of retrying the same uuid.

For detailed signing instructions, see Authentication.

Step 4: Check Your Balances

Create an API key to query your balances and order history. The /balances endpoint returns both your wallet balance (tokens in your Ethereum wallet) and your Vault balance (tokens deposited for limit order trading), along with any frozen amounts locked in open orders.

balances = requests.get(
    "https://api.sera.cx/api/v1/balances",
    params={"owner_address": "0xYOUR_ADDRESS"},
    headers={"Authorization": "Bearer YOUR_API_KEY:YOUR_API_SECRET"},
    timeout=10,
).json()["balances"]

for bal in balances:
    print(f"{bal['symbol']}:")
    print(f"  Wallet:         {bal['wallet_balance']}")
    print(f"  Vault available: {bal['vault_available']}")
    print(f"  Vault frozen:    {bal['vault_frozen']}")
const response = await fetch(
  "https://api.sera.cx/api/v1/balances?owner_address=0xYOUR_ADDRESS",
  { headers: { "Authorization": "Bearer YOUR_API_KEY:YOUR_API_SECRET" } },
);
const { balances } = await response.json();

for (const bal of balances) {
  console.log(`${bal.symbol}:`);
  console.log(`  Wallet:          ${bal.wallet_balance}`);
  console.log(`  Vault available: ${bal.vault_available}`);
  console.log(`  Vault frozen:    ${bal.vault_frozen}`);
}

Using the Web App

You can also trade directly through the Sera web interface:

  1. Visit app.sera.cx
  2. Connect your wallet
  3. Select a currency pair
  4. Place a limit order or execute an instant swap
  5. Monitor your orders in the dashboard

Next Steps