Every call carries an API key as a bearer token.
curl https://api.beaconbox.eu/api/v1/credits \
-H "Authorization: Bearer $BEACONBOX_API_KEY"Keys start with bbx_live_. There is no separate test key and no sandbox mode: a key resolves to
one business, and everything it does is real. If you want somewhere to experiment, ask for a
second business rather than reaching for a mode that does not exist.
Generating and revoking
Keys are managed in the dashboard under Settings, and over the API.
curl https://api.beaconbox.eu/api/v1/keys \
-H "Authorization: Bearer $BEACONBOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "orders service"}'new_key = client.keys.create("orders service")
print(new_key.key) # the only time you will see it$newKey = $client->keys->create('orders service');
echo $newKey->key; // the only time you will see itListing keys returns them masked. Revoking takes effect immediately, on the next request.
A key created over the API with another key is revoked along with the key that created it, unless
it was created with detach: true, which is how you rotate: create a detached key, move your
systems to it, then revoke the old one. Each key in the list carries minted_by, the id of the key
that created it over the API, detached or not, and null for a key created in the dashboard. If a
key leaks, revoke it, then look for keys whose minted_by is its id: any still listed were created
detached with the leaked key, and keep working until you revoke them too.
Generate one key per system rather than sharing one. A key that leaks can then be revoked on its own, without taking down every other system you have wired up.
Nothing records which key made a given call. The name you give a key is therefore the only thing that will tell you what it was for when you come to revoke it.
What a failure looks like
A missing, malformed or revoked key is a 401 with business.invalid_api_key. A key belonging to
a business that is no longer active is a 403 with business.inactive: the credential is real, so
the refusal is about the account rather than about the key.
{ "error_code": "business.invalid_api_key" }Transport rules both SDKs enforce
Worth knowing even if you are calling the API directly, because they are the failure modes that matter rather than style preferences.
Plain http is refused for anything but localhost. A mistyped base URL must not put your key
on the wire in clear.
Redirects are never followed. An HTTP client that follows one re-sends the Authorization
header to wherever the redirect points.
A key that cannot go in a header is refused at construction. A newline inside a key would
reach the Authorization header, which on some clients is request smuggling with your own
credential as the payload. Surrounding whitespace is stripped instead, because a key read from a
file keeps its trailing newline.
A base URL carrying a query string or fragment is refused, because the path is appended to it and the request would not fail, it would go somewhere else. A path prefix is fine, for a gateway that mounts BeaconBox under one.
Keeping a key safe
- Put it in your environment or secret store, never in a repository and never in client-side code. There is no browser-safe BeaconBox key, because every key can send messages to your customers.
- Revoke immediately on any suspicion. Generating a replacement takes seconds and revocation is instant.
- Name keys after the system that holds them. “orders service” tells you what breaks when you revoke it; “key 2” does not.
