> For the complete documentation index, see [llms.txt](https://quote.gitbook.io/quote-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://quote.gitbook.io/quote-docs/for-developers/quickstart.md).

# API Quickstart

Mint an API key, sign your first request, and submit an order in five minutes.

This guide takes you from zero to a filled order over the API. You need a Quote account with a registered agent wallet. If you have traded in the [terminal](https://quotemarkets.xyz), you already have one.

{% stepper %}
{% step %}

#### Mint an API key

API keys are minted from a logged-in terminal session; they cannot mint each other (see [Authentication](/quote-docs/for-developers/authentication.md)). In the terminal, open **Settings → API Keys**, or call the endpoint directly with your Privy session token:

```bash
curl -X POST https://api.quotemarkets.xyz/api/keys \
  -H "Authorization: Bearer $PRIVY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-trading-bot",
    "scopes": ["orders:read", "orders:write", "agents:read"]
  }'
```

{% code title="Response" %}

```json
{
  "keyId": "qk_a1b2c3...",
  "secret": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
}
```

{% endcode %}

{% hint style="warning" %}
The `secret` is returned **once** and never again. Store it securely. It is the raw HMAC-SHA256 signing key for every request you make.
{% endhint %}
{% endstep %}

{% step %}

#### Sign a request

Every API-key request carries three headers: `X-Quote-Key`, `X-Quote-Timestamp` (milliseconds), and `X-Quote-Signature`. The signature is an HMAC-SHA256 over the canonical string `timestamp \n METHOD \n path_with_query \n body`.

{% tabs %}
{% tab title="signing.ts" %}

```typescript
import { createHmac } from "node:crypto";

const BASE_URL = "https://api.quotemarkets.xyz";
const KEY_ID = process.env.QUOTE_KEY_ID!;
const SECRET = process.env.QUOTE_SECRET!; // hex string from mint time

export async function quoteFetch(
  method: string,
  path: string, // includes query string, e.g. "/api/orders/algo"
  body?: unknown,
) {
  const timestamp = Date.now().toString();
  const rawBody = body ? JSON.stringify(body) : "";
  const canonical = `${timestamp}\n${method.toUpperCase()}\n${path}\n${rawBody}`;
  const signature = createHmac("sha256", Buffer.from(SECRET, "hex"))
    .update(canonical)
    .digest("hex");

  return fetch(`${BASE_URL}${path}`, {
    method,
    headers: {
      "Content-Type": "application/json",
      "X-Quote-Key": KEY_ID,
      "X-Quote-Timestamp": timestamp,
      "X-Quote-Signature": signature,
    },
    body: rawBody || undefined,
  });
}
```

{% endtab %}

{% tab title="signing.py" %}

```python
import hashlib, hmac, json, os, time
import requests

BASE_URL = "https://api.quotemarkets.xyz"
KEY_ID = os.environ["QUOTE_KEY_ID"]
SECRET = bytes.fromhex(os.environ["QUOTE_SECRET"])  # hex string from mint time

def quote_request(method: str, path: str, body: dict | None = None):
    timestamp = str(int(time.time() * 1000))
    raw_body = json.dumps(body, separators=(",", ":")) if body else ""
    canonical = f"{timestamp}\n{method.upper()}\n{path}\n{raw_body}"
    signature = hmac.new(SECRET, canonical.encode(), hashlib.sha256).hexdigest()

    return requests.request(
        method,
        BASE_URL + path,
        headers={
            "Content-Type": "application/json",
            "X-Quote-Key": KEY_ID,
            "X-Quote-Timestamp": timestamp,
            "X-Quote-Signature": signature,
        },
        data=raw_body or None,
    )
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The timestamp must be within 30 seconds of server time (configurable server-side). Sign the *exact* bytes you send: the path must include the query string, and the body must match byte-for-byte.
{% endhint %}
{% endstep %}

{% step %}

#### Check your agent wallet

Orders are signed by your [agent wallet](/quote-docs/getting-started/agent-wallets.md). Verify one is registered:

```typescript
const res = await quoteFetch("GET", "/api/agents");
const agent = await res.json();
// { success: true, agentAddress: "0x...", builderFeeApproved: true, ... }
```

Two things must be true before you can trade:

* an `agentAddress` is present and not `expired`: the agent signs your orders;
* `builderFeeApproved` is `true`. This is **required**: every Quote-routed order carries Quote's builder code, and Quote will not trade for a wallet that has not approved the fee.

If either is missing, complete agent setup in the terminal first (both steps require a signature from your main wallet, which API keys can't produce).
{% endstep %}

{% step %}

#### Submit an order

A limit order:

```typescript
const res = await quoteFetch("POST", "/api/orders", {
  symbol: "ETH",
  side: "buy",
  size: "0.05",
  orderType: "limit",
  limitPrice: "3200.0",
  timeInForce: "GTC",
});
const result = await res.json();
// { success: true, orderId: "...", status: "accepted", provider: "hyperliquid" }
```

Or hand the same size to the execution engine as a [TWAP](/quote-docs/execution-strategies/passive-twap.md) worked over 15 minutes:

```typescript
const res = await quoteFetch("POST", "/api/orders", {
  symbol: "ETH",
  side: "buy",
  size: "0.5",
  orderType: "limit",
  strategy: "passive_twap",
  params: { durationSecs: 900, numSlices: 15 },
});
```

{% hint style="warning" %}
A `200` response means the order was **accepted into the engine**, not that it filled. For algo strategies, `orderId` is the parent strategy ID. See [Order Lifecycle](/quote-docs/for-developers/order-lifecycle.md).
{% endhint %}
{% endstep %}

{% step %}

#### Track progress

```typescript
const res = await quoteFetch("GET", "/api/orders/algo");
const { orders } = await res.json();
// [{ orderId, symbol, side, orderQty, filledQty, status, strategy, submitTime }]
```

For live push updates, the terminal uses the [algo status WebSocket](/quote-docs/for-developers/algo-status.md).
{% endstep %}
{% endstepper %}

## Next steps

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Authentication in depth</strong></td><td>Scopes, the canonical signing string, and Privy-only endpoints.</td><td><a href="/quote-docs/for-developers/authentication.md">Authentication</a></td></tr><tr><td><strong>Choose a strategy</strong></td><td>Which execution algorithm fits your order size and urgency.</td><td><a href="/quote-docs/execution-strategies/overview.md">Strategies Overview</a></td></tr></tbody></table>
