Create a new API key
const url = 'https://oddslink.app/v1/account/keys';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"label":"production server","test":false}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://oddslink.app/v1/account/keys \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "label": "production server", "test": false }'Signed-in website session only. The full secret is returned exactly once, in this response. We do not store the plaintext and cannot show it again. Key prefixes are ok_live_ for a normal key and ok_test_ for a test key, always clearly marked as test context.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Create an ok_test_-prefixed key instead of a live one.
Examples
{ "label": "production server", "test": false}Responses
Section titled “ Responses ”The new key, with its one-time secret.
object
The key’s non-secret prefix, safe to display, for example ok_live_Q3v9Tb2K: the key’s own leading ok_live_ or ok_test_, plus its first 8 characters.
The key’s last 4 characters, safe to display alongside the prefix so you can tell two of your keys apart even when their prefixes match.
True for a key created with test: true, always clearly marked as test context.
The full secret. Returned only here, only once. We do not store the plaintext.
Examples
{ "id": "8f14e45f-ceea-4c5b-9d1a-1a2b3c4d5e6f", "prefix": "ok_live_Q3v9Tb2K", "last_four": "Es9z", "key": "ok_live_Q3v9Tb2KcWHFpOjQnLqLhrLoFMtNKwR7t7NTq-8Es9z", "label": "production server", "test": false, "created_at": "2026-09-19T09:00:00Z", "last_used_at": null, "revoked_at": null}Headers
Section titled “Headers”Requests used this billing period.
Requests remaining this billing period.
What this one call cost against the allowance (0 for a free call).
This plan’s speed limit, in requests per second.
Requests left in the current one-second window.
Seconds until the speed-limit window resets.
This request’s id, for support and for matching against error.request_id.
A parameter was malformed.
object
object
403 only: the plan on the presented key.
403 only: the lowest plan that includes this request. For history, that depends on how long ago the fixture started as well as on the endpoint.
Example
{ "error": { "code": "BAD_REQUEST", "message": "commenceTimeFrom is not a valid ISO-8601 timestamp.", "docs_url": "https://oddslink.app/docs/errors/#bad-request", "request_id": "req_01hz8k3z9e2v6w1x" }}Headers
Section titled “Headers”Requests used this billing period.
Requests remaining this billing period.
What this one call cost against the allowance (0 for a free call).
This plan’s speed limit, in requests per second.
Requests left in the current one-second window.
Seconds until the speed-limit window resets.
This request’s id, for support and for matching against error.request_id.
The API key (or session) is missing or invalid.
object
object
403 only: the plan on the presented key.
403 only: the lowest plan that includes this request. For history, that depends on how long ago the fixture started as well as on the endpoint.
Examples
No X-API-Key header sent
{ "error": { "code": "MISSING_KEY", "message": "X-API-Key header is missing.", "docs_url": "https://oddslink.app/docs/errors/#missing-key", "request_id": "req_01hz8k4a1f3w7x2y" }}Key does not exist or was revoked
{ "error": { "code": "INVALID_KEY", "message": "API key is not valid.", "docs_url": "https://oddslink.app/docs/errors/#invalid-key", "request_id": "req_01hz8k4b2g4x8y3z" }}No Authorization: Bearer header sent (account endpoints only)
{ "error": { "code": "MISSING_SESSION", "message": "Sign in and try again.", "docs_url": "https://oddslink.app/docs/errors/#missing-session", "request_id": "req_01hz8k4b9h5y0z1a" }}Session is expired or invalid (account endpoints only)
{ "error": { "code": "INVALID_SESSION", "message": "Your session has expired. Sign in again.", "docs_url": "https://oddslink.app/docs/errors/#invalid-session", "request_id": "req_01hz8k4c0j6z1a2b" }}Headers
Section titled “Headers”Requests used this billing period.
Requests remaining this billing period.
What this one call cost against the allowance (0 for a free call).
This plan’s speed limit, in requests per second.
Requests left in the current one-second window.
Seconds until the speed-limit window resets.
This request’s id, for support and for matching against error.request_id.
The plan’s speed limit was exceeded; wait Retry-After seconds. A call that does not count against the allowance is never refused for a spent allowance.
object
object
403 only: the plan on the presented key.
403 only: the lowest plan that includes this request. For history, that depends on how long ago the fixture started as well as on the endpoint.
Example
{ "error": { "code": "SPEED_LIMIT", "message": "Speed limit exceeded: 10 requests/second on the Growth plan.", "docs_url": "https://oddslink.app/docs/errors/#speed-limit", "request_id": "req_01hz8k4f7m9c3d8f" }}Headers
Section titled “Headers”Requests used this billing period.
Requests remaining this billing period.
What this one call cost against the allowance (0 for a free call).
This plan’s speed limit, in requests per second.
Requests left in the current one-second window.
Seconds until the speed-limit window resets.
This request’s id, for support and for matching against error.request_id.
Seconds to wait before retrying (429 SPEED_LIMIT only).
Something failed on our side.
object
object
403 only: the plan on the presented key.
403 only: the lowest plan that includes this request. For history, that depends on how long ago the fixture started as well as on the endpoint.
Example
{ "error": { "code": "INTERNAL_ERROR", "message": "Something went wrong on our side. It has been logged.", "docs_url": "https://oddslink.app/docs/errors/#internal-error", "request_id": "req_01hz8k4h8n0d4e9f" }}Headers
Section titled “Headers”Requests used this billing period.
Requests remaining this billing period.
What this one call cost against the allowance (0 for a free call).
This plan’s speed limit, in requests per second.
Requests left in the current one-second window.
Seconds until the speed-limit window resets.
This request’s id, for support and for matching against error.request_id.