Authentication
Every request carries one of two credentials, and which one decides more than access: a partner’s client key executes writes at once, while a connected app’s token stages them for the customer to confirm. There is no session and no cookie.
| WHO YOU ARE | WHAT YOU SEND |
|---|---|
| A partnerserver-to-server | CLIENT-KEY and CLIENT-SECRET, issued by Cru to your organisation. Writes execute immediately and need a reference. |
| An app acting for a customerAI assistant, portfolio tool | Authorization: Bearer with a token the customer approved through OAuth 2.1. Writes are staged and confirmed. |
Partner credentials
CLIENT-KEY: YOUR_CLIENT_KEY CLIENT-SECRET: YOUR_CLIENT_SECRET Accept: application/json
Send both headers on every HTTPS request. CLIENT_KEY and X-CLIENT-KEY (and the same for the secret) are accepted too, but the hyphenated names are the ones to use: some servers drop header names that contain underscores.
| Client key | cru_live_ on production or cru_test_ elsewhere, then 26 characters. Not secret on its own, but keep it with the secret. |
| Client secret | cru_sk_ then 43 characters. Shown once when Cru issues it, and stored only as a hash: Cru cannot show it to you again. |
Getting access
Cru issues credentials to your organisation with the scopes you need. Each one acts as your Cru account, and can also be restricted to particular markets and IP addresses, and given an expiry date. To rotate, ask for a second credential and let the first expire.
Verify your credentials
Call GET /ping to see the account, label, market, currency, scopes and expiry the credential carries. It exposes no trading data.
What a refusal tells you
Credentials are checked in this order, and the first failure is the answer.
| CHECK | FAILURE |
|---|---|
| Both headers present; key known; secret matches | AUTH_INVALID_CREDENTIALS · 401 |
| Credential active and not expired; API access on for your account | AUTH_CLIENT_SUSPENDED · 403 |
| Calling address on the credential’s allowlist, if it has one | AUTH_IP_NOT_ALLOWED · 403 |
| The market you called is one the credential may use | AUTH_STORE_NOT_ALLOWED · 403 |
| The credential holds the endpoint’s scope | AUTH_INSUFFICIENT_SCOPE · 403 |
An unknown key and a wrong secret are deliberately indistinguishable, and a suspended credential is only reported to a caller that has proved it holds the secret.
Read credentials from environment variables. Do not embed them in frontend code, public repositories, or URLs. Copied examples use environment variable names, never the credentials entered in the console.
Bearer tokens
Authorization: Bearer cru_at_YOUR_ACCESS_TOKEN A connected app sends the customer’s access token instead — and never both: if either credential header is present, the token is ignored. Tokens last an hour, work only on the Cru sites the customer allowed, and stop working while the customer’s account is on hold (AUTH_ACCOUNT_ON_HOLD). How to get one →
Explorer credentials
Credentials entered here, or a connection made in the playground, are kept for this browser tab’s session: a reload keeps them, and closing the tab or disconnecting ends them. Every page uses the same connection, and it is redacted from anything the console prints back.
HTTPS is required
Plain HTTP is refused with AUTH_HTTPS_REQUIRED / 403, before the credentials are looked at. Use a trusted certificate, including in local development.
Request IDs
Send your own X-Request-Id — 8 to 64 letters, digits and . _ : - — and Cru uses it for the request, so your logs and Cru’s share an ID. Otherwise Cru makes one. Either way it comes back as X-Request-Id and as meta.request_id.
Secrets are displayed only at issue and stored as hashes. Contact Cru to suspend the lost credential and issue a replacement.