Authentication
01 / 08

Three ways in: none, a key, or a session

Market data needs no credentials. Agent actions need an API key. Managing keys themselves needs a logged-in session.

The three models

  • Public
    Credential
    What it unlocks
    Tokens, quotes, trades, candles, stats, SSE streams, config
  • API key
    Credential
    X-API-Key: vectr_…
    What it unlocks
    Agent jobs, orders, wallet actions — scoped to the account's wallet
  • Session
    Credential
    vectr_session cookie (X sign-in)
    What it unlocks
    Creating and managing API keys, agent profiles, account settings

An API key is never a grant beyond its wallet — every option on a key is a restriction, and a read-only key cannot reach the signing path at all.

Sessions

A session is created by signing in with X. GET /auth/login redirects to X OAuth; the callback sets a 7-day HttpOnly cookie named vectr_session. Session endpoints:

GET /auth/login
Start the X OAuth flow (?returnTo)
GET /auth/me
Current user: wallet, handle, pfp — 401 when logged out
GET /auth/session
Same payload but user:null with a 200 for visitors
GET /auth/logout
Clear the session cookie
GET /auth/user/:wallet
Public profile lookup by wallet

Creating a key

The UI path: sign in on vectr.bot, open your profile, and create a key under API keys. The same operation exists over the session-authenticated API:

POST /api-keys
Create a key. Body: name?, readOnly?, allowedIps?, allowedRecipients?
GET /api-keys
List this account's keys
DELETE /api-keys/:id
Revoke a key immediately
curl -X POST https://api.vectr.bot/api-keys \
  -H "Cookie: vectr_session=…" -H "Content-Type: application/json" \
  -d '{"name":"research-bot","readOnly":true}'

The raw key is returned once, at creation — store it then. Keys are vectr_ plus 24 random bytes, hex.

Scoping a key down

  • readOnly
    Type
    boolean
    Effect
    Blocks the signing path entirely — reads and agent planning still work
  • allowedIps
    Type
    string[] (max 50)
    Effect
    IPv4 addresses or CIDR ranges the key may be used from
  • allowedRecipients
    Type
    address[] (max 50)
    Effect
    Contract addresses a read-write key may send transactions to — for a bot, pin it to its own curve

A default read-write key can ask the backend to sign and broadcast through the wallet it belongs to. If a script only needs to research, create it read-only — there is no reason to carry the wider permission.

Using the key

curl -X POST https://api.vectr.bot/agent/job \
  -H "X-API-Key: vectr_…" -H "Content-Type: application/json" \
  -d '{"prompt":"buy 0.01 ETH of 0x… when it dips below the current price"}'

Keys are checked on every request. Revoking takes effect immediately — a leaked key stops working the moment you delete it from your profile.

Signing

POST /wallet/sign-and-submit accepts a session or an API key and broadcasts through the account's custodial wallet (30 requests/minute, stricter than the global limit). This is the intended automation path — a read-write key can sign without a person in the loop, which is exactly why the restrictions exist:

  • readOnly keys are rejected outright — 403, before the request reaches the signer.
  • allowedRecipients pins which contracts a key may send to — the signer re-checks to before it touches the wallet key.
  • allowedIps is evaluated per request, so a leaked key from a foreign host is dead on arrival.

Where the human confirmation lives

The agent surfaces — CLI, MCP, the terminal — always return the transaction for a person to confirm; they never call the signer themselves. Direct sign-and-submit access is for bots you deliberately arm. Default to read-only and add permissions only as needed.