Authentication
Every request to /api/v1/* must carry a bearer token. The token is a signed JWT (HS256) whose sub claim is the user id and whose tier claim drives tier-gated endpoints.
#Header shape
curl https://api.closeline.io/v1/games/today \
-H "Authorization: Bearer $CLOSELINE_API_KEY"The API also accepts the same-origin cl_sess cookie for the web UI's own requests — third-party clients should always use the Authorization header.
#Obtaining a token
Sign up at /signup and generate a key from the account dashboard. Each key is bound to a single user and inherits that user's tier. Rotating your key invalidates the old one immediately.
#Token lifetime
- Access TTL:
86,400 seconds (24 hours)by default. Configurable server-side viaJWT_ACCESS_TTL_SECONDS. - Issuer:
closeline.io(overridable viaJWT_ISSUER). - No refresh token at v1 — clients re-authenticate after expiry. Coarse revocation is done by rotating
JWT_SECRETon the server.
#From the SDK
import { Closeline } from "@closeline/sdk";
// Explicit — required in serverless envs where process.env is scrubbed.
const cl = new Closeline({ apiKey: process.env.CLOSELINE_API_KEY! });
// Or, rely on the env default:
// new Closeline() // reads process.env.CLOSELINE_API_KEY#Responses
- 401 unauthorized — missing, malformed, or expired token. Body carries
{ error: { code: "unauthorized", ... } }. - 403 tier_insufficient — valid token, but your tier doesn't cover the endpoint. See Errors.
#Every response carries
x-request-id— opaque uuid for support / tracing.x-ratelimit-limit/x-ratelimit-remaining/x-ratelimit-reset— per-tier rate-limit hints.