API Key Scopes
Endpoint-level permissions for live API keys, least-privilege integrations, and fail-closed access checks.
Section
12 / 27
Live API examples
Jump from the docs to real public pages that use the same read models.
Endpoints
/v1/results/latestRequires results:read.
/v1/lotteriesRequires lotteries:read.
/v1/statusPublic status smoke; status:read is optional for issued monitor keys.
Why scopes exist
Live keys use endpoint scopes so result workers, status monitors, and catalog tools can hold separate least-privilege credentials. A denied request returns an explicit error instead of silently returning partial data.
Scope matrix
Each protected /v1 endpoint documents its required scope in OpenAPI through x-required-scopes. Sandbox lf_sandbox_* keys and the documented legacy demo token return deterministic fixtures; persisted development keys use lf_dev_ and normal scope checks. Production integrations should use an issued lf_live_* key with only the scopes they need.
{
"scopes": [
{
"scope": "results:read",
"label": "Results data",
"description": "Read latest results, date history, checker, draw years, and frequency/statistics endpoints.",
"endpoints": [
"GET /v1/results/latest",
"GET /v1/results/latest/{game_code}",
"GET /v1/results/history",
"POST /v1/results/check",
"GET /v1/lotteries/{game_code}/frequency",
"GET /v1/stats/{game_code}"
],
"examples": [
"Latest draw cards",
"History sync jobs",
"Number-check workflows",
"Statistics previews"
]
},
{
"scope": "lotteries:read",
"label": "Catalog and schedules",
"description": "Read country, state, lottery metadata, draw years, and schedule context for integration setup.",
"endpoints": [
"GET /v1/countries",
"GET /v1/states",
"GET /v1/lotteries",
"GET /v1/lotteries/{game_code}",
"GET /v1/lotteries/{game_code}/draw-years",
"GET /v1/results/years",
"GET /v1/schedules"
],
"examples": [
"Lottery picker",
"State catalog",
"Schedule-aware polling",
"Game metadata"
]
},
{
"scope": "status:read",
"label": "Status diagnostics",
"description": "Read public feed status and freshness diagnostics without raw operator source logs.",
"endpoints": [
"GET /v1/status"
],
"examples": [
"Health checks",
"Incident checks",
"Freshness monitoring"
]
}
]
}Customer key presets
The customer API key page turns the scope matrix into concrete presets before a token is created and also lets customers adjust scopes on existing keys without re-issuing the raw secret. Use Full read integration for most backend services, Results worker for draw-only jobs, and Catalog browser for setup screens that never need winning numbers.
{
"presets": [
{
"id": "full-read-integration",
"label": "Full read integration",
"description": "Best default for backend services that fetch results, metadata, schedules, and status.",
"scopes": [
"results:read",
"lotteries:read",
"status:read"
],
"recommended": true
},
{
"id": "latest-results",
"label": "Results worker",
"description": "Smallest key for a backend job that only reads draw results, history, checker, and statistics endpoints.",
"scopes": [
"results:read"
],
"recommended": false
},
{
"id": "catalog-and-schedules",
"label": "Catalog browser",
"description": "Smallest key for setup screens that list lotteries, states, countries, schedules, and draw years.",
"scopes": [
"lotteries:read"
],
"recommended": false
}
]
}Lottery allowlists
Live keys can also carry a lottery allowlist. An empty allowlist means every lottery covered by the key scopes. A non-empty allowlist narrows list endpoints and fails closed for explicit requests to any other game_code.
{
"game_code_filters": ["md-pick3-midday", "md-pick4-evening"],
"empty_allowlist": "all lotteries covered by scopes"
}403 diagnostics
When a live key is valid but missing the required endpoint scope, the gateway returns HTTP 403 with FORBIDDEN. When the scope is valid but a requested lottery is outside the key allowlist, it returns HTTP 403 with FORBIDDEN_GAME_CODE. The account API key page shows and edits each key scope set, lottery allowlist, last endpoint, client IP, daily usage, and request logs so operators can see whether the failure is permission, limit, endpoint, or lottery access related.
{
"error": {
"code": "FORBIDDEN_GAME_CODE",
"message": "API key is not allowed to access the requested lottery game_code.",
"game_code": "tx-pick3-day"
}
}Operational guidance
Use separate keys for different jobs where possible: results:read for result polling and ingestion, lotteries:read for catalog and schedule syncs, and status:read as a monitor label on issued keys. The public /v1/status smoke endpoint is intentionally readable without a bearer key, while authenticated customer monitors can still carry status:read for usage reporting and key organization. A single key can carry multiple scopes for simple integrations, but separating them makes compromise, rotation, and daily-limit debugging easier.
API documentation FAQ
Short answers for teams using api key scopes in production integrations.
What happens when a key is missing a scope?
The request fails closed with HTTP 403, code FORBIDDEN, and a clear missing-scope message. It should not be retried until the key is updated or the client switches to a key with the required scope.
Can one API key read everything?
Yes, an issued key can carry results:read, lotteries:read, and status:read together. For production systems, separate keys are still recommended for catalog syncs and result ingestion. The public /v1/status smoke endpoint does not require a bearer key, but status:read can still be used as an operational monitor label on issued keys.
Next: Freshness levels