Authentication
API key formats, scopes, and rotation.
Every request carries a bearer token. There is no session, no OAuth dance, and no per-request signing. An API key in a header is the whole scheme.
curl https://REGION.api.lararouter.com/v1/me \
-H "Authorization: Bearer $LARAROUTER_API_KEY"Key formats
Keys are prefixed so they're recognizable in logs, alerts, and secret scanners.
| Prefix | Kind | Where it belongs |
|---|---|---|
lr_sk_live_ / lr_sk_test_ | Secret key | Server-side only. The _live_ / _test_ segment is the environment. There is no environment header. |
lr_pk_live_ / lr_pk_test_ | Publishable key | Safe to expose. Can only read /v1/models and /v1/health. |
Secret keys are shown once
The full value of a secret key is returned only in the response that creates it. After that only the last four characters are visible. If you lose it, roll it.
The environment is part of the key
A lr_sk_test_ key answers from sandbox: mock completions, a simulated cost on a separate ledger, and
no accelerator. A lr_sk_live_ key spends money. Everything before the model call (scopes, region
binding, idempotency, rate limits, budgets) behaves identically in both.
There is no environment header. The key prefix selects sandbox or live. See Environments for what sandbox mirrors and what it mocks.
GET /v1/me HTTP/1.1
Host: REGION.api.lararouter.com
Authorization: Bearer lr_sk_test_9Hs4TnQ2
HTTP/1.1 200 OK
X-Lararouter-Environment: sandboxScopes
A key carries a set of scopes, and a request that needs a scope the key doesn't have returns 403
with error.code = insufficient_scope.
Prop
Type
GET /v1/me returns these values in scopes. A secret key issued from the dashboard holds every
scope above.
Keys are bound to a region
A key issued in the EU region authenticates against eu.api.lararouter.com and nowhere else. Sending
it to another host returns 401 with error.code = key_region_mismatch rather than silently routing
your data somewhere it shouldn't go. See Regions.
Rotation
Create the replacement first, deploy it, then revoke the old key in the dashboard. Revocation takes effect immediately and in-flight requests using the deleted key fail, so there is no grace period to rely on.
Issue the replacement from the dashboard, deploy it everywhere, then revoke the old key once traffic
has moved. Confirm the cutover with GET /v1/me using the new key before you
revoke the old one.
Storing keys
Read the key from the environment, never from source. In Laravel that means an entry in config/
backed by env(), so config caching still works:
// config/services.php
'lararouter' => [
'key' => env('LARAROUTER_API_KEY'),
'url' => env('LARAROUTER_URL', 'https://REGION.api.lararouter.com/v1'),
],Calling env() outside a config file breaks once you run php artisan config:cache, which is the
kind of bug that only shows up in production.