All systems normalData updated just nowStatusChangelogSupport
badmintonapi

Authentication

Every call to the API carries your key in a request header. There are no sessions, cookies or tokens to refresh: the same key works from a script, a server, a notebook or an AI assistant, and it keeps working until you replace it. Keys start bda_live_, followed by 40 random characters.

The two headers

Send the key in either header. Both are read the same way, so use whichever your HTTP library makes easiest. Most code uses Authorization: Bearer; some tools that already set their own Authorization header for something else find X-API-Key simpler.

Authorization header
curl https://api.badmintonapi.com/v1/usage \
  -H "Authorization: Bearer $BADMINTON_API_KEY"
X-API-Key header
curl https://api.badmintonapi.com/v1/usage \
  -H "X-API-Key: $BADMINTON_API_KEY"

Never in the address

A key in the address (?key= or ?api_key=) is refused with a 400 bad_request, even when the key itself is good. Addresses end up in server logs, browser history, analytics tools and links people paste into chats; headers do not. Refusing the address outright means a key can never leak that way by accident.

The answer when a key is sent in the address
HTTP/1.1 400
{
  "error": {
    "code": "bad_request",
    "message": "Send the key in a header (X-API-Key or Authorization: Bearer), never in the address.",
    "docs": "https://badmintonapi.com/documentation"
  }
}

In your language

Python
import os, requests

r = requests.get(
    "https://api.badmintonapi.com/v1/usage",
    headers={"Authorization": f"Bearer {os.environ['BADMINTON_API_KEY']}"},
    timeout=20,
)
print(r.json()["data"])
JavaScript (Node 18 or later)
const r = await fetch("https://api.badmintonapi.com/v1/usage", {
  headers: { "X-API-Key": process.env.BADMINTON_API_KEY },
});
const { data } = await r.json();
console.log(data);
PHP
$ch = curl_init('https://api.badmintonapi.com/v1/usage');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('BADMINTON_API_KEY')],
]);
$usage = json_decode(curl_exec($ch), true)['data'];

How keys are kept

A key is shown once, when it is made. We store only a one-way hash of it, so nobody here can read it back, and a key lost from your notes cannot be recovered: make a new one in your account instead. Replacing a key ends the old one at once. Your plan belongs to your account, not to the key, so when you upgrade, the key you already use sees the new endpoints straight away, with no new key and no change to your code.

When the key is wrong

No key, or a key that has been replaced, answers 401 unauthorized with a message saying which. A good key asking for an endpoint above its plan answers 403 upgrade_required, and error.plan names the plan that has it. Calling /v1/usage is the quickest way to check a key: it answers with the key's plan and today's calls, and is never counted against your limits.