Skip to content

Authentication

TokenBot supports a few authentication methods depending on which API you’re calling.

APIMethods
REST APIAPI key (primary) or signed request (CLI fast-path)
GraphQL APICLI signed request (canonical) or JWT bearer token (legacy)

Send your API key via the X-API-Key header:

Terminal window
curl https://api.tokenbot.com/v1/exchanges \
-H "X-API-Key: tb_live_your_api_key"

You can also pass the same key as a bearer token — it’s treated identically:

Terminal window
curl https://api.tokenbot.com/v1/exchanges \
-H "Authorization: Bearer tb_live_your_api_key"

Note: the REST API does not verify standalone JWTs. Authorization: Bearer <value> is interpreted as an API key.

EnvironmentFormatExample
Productiontb_live_<...>tb_live_a1b2c3...
Testtb_test_<...>tb_test_a1b2c3...

Create and manage keys with the CLI:

Terminal window
tokenbot apikey create --name "ci-bot" --env live
tokenbot apikey list
tokenbot apikey revoke <id>

Or via the REST endpoints (these require a key with ADMIN permission):

OperationEndpoint
CreatePOST /v1/api-keys
ListGET /v1/api-keys
RevokeDELETE /v1/api-keys/:id
RotatePOST /v1/api-keys/:id/rotate

The tokenbot CLI authenticates with a secp256k1 keypair instead of an API key. Each request carries four headers and a signature; no key is transmitted. The REST API verifies the signature first, and falls back to API-key auth when these headers are absent.

HeaderValue
x-tb-pubkeyYour compressed public key (hex)
x-tb-timestampUnix milliseconds
x-tb-nonce16 random bytes (hex)
x-tb-sigsecp256k1 signature (hex) of the canonical string

The canonical string that gets signed is:

${METHOD}\n${path}\n${timestamp}\n${nonce}\n${sha256(body)}

where path includes the query string and body is the raw request body (the empty string hashes to the SHA-256 of ""). Requests are accepted within a ±60-second clock-skew window, and nonces are remembered for a 10-minute replay window.

This scheme is implemented for you by @tokenbot-org/cli-core; you normally don’t construct it by hand. It’s documented here so server integrations can verify it.


The production GraphQL API is an Express server (deployed on ECS Fargate) at https://gql-api.tokenbot.com/graphql. It accepts two auth methods:

  1. CLI signed request (canonical) — the same x-tb-* signed-request scheme used by the REST API (see above). This is how the tokenbot CLI authenticates and how new integrations should authenticate. No password, OAuth, passkey, or 2FA flow is involved.
  2. JWT bearer token (legacy) — an Authorization: Bearer <access_token> token, retained only for back-compat.

Real-time subscriptions authenticate the graphql-ws handshake with the same signed-request scheme (method CONNECT, path /graphql) — see Subscriptions.

Deprecated auth surface: the password login / register, OAuth (google_auth, x_auth, apple_auth, telegram_auth), passkey / WebAuthn, and 2FA (generate_2fa, enable_2fa, verify_2fa_code, disable_2fa) mutations are dashboard-era and @deprecated — they still resolve but are slated for removal in v2.0, so they are intentionally not documented as usable endpoints here. Authenticate programmatic clients with the CLI signed-request scheme or a REST API key instead. The full deprecated list is in Mutations.

Heads-up: GraphQL previously ran on AWS AppSync with Cognito. That has been retired — there is no Cognito, AppSync API key, or x-api-key auth anymore.


  • Never commit API keys to version control.
  • Rotate keys periodically via POST /v1/api-keys/:id/rotate (or tokenbot apikey).
  • Use the minimum required permissions for each key.
  • Protect your CLI identity — choose a strong ~/.tokenbot passphrase; your secp256k1 private key never leaves your machine.