Most REST API and SDK access problems in Label Studio come down to the token you are using: which type it is, how it is passed in the request, and whether it is still valid. Label Studio supports two token types, and they authenticate differently, so a request that works with one will fail with the other.
This guide explains how to identify and fix the most common authentication errors.
When a request fails, Label Studio returns a JSON body with the specific
reason in the detail field, for example:
{"id":"...","status_code":401,"version":"1.22.0","detail":"Authentication credentials were not provided.","exc_info":null}
Read the detail string first — it tells you exactly which failure
you are hitting below.
Know which token type you are using
Label Studio has two kinds of API tokens, and each uses a
different Authorization header:
| Token type | How it is passed | Expires? |
|---|---|---|
| Personal Access Token (PAT) |
Used to obtain a short-lived access token, which is sent as
Authorization: Bearer <access-token>
|
Yes — the access token expires after roughly 5 minutes; the PAT itself can have an org-level TTL |
| Legacy Token (API key) |
Sent directly as Authorization: Token <token>
|
No — it does not expire and stays listed in your account settings |
Using the wrong header scheme for your token type is the single most common
cause of authentication failures. A Legacy Token must use
the word Token, and a PAT-derived access token must use the
word Bearer.
Where to find your token
- Click your user icon in the upper-right corner and select Account & Settings.
- Open the Personal Access Tokens or Legacy Tokens page.
If you do not see one of these pages, that token type has not been enabled for your organization. See Enable or disable a token type below.
Note: A Personal Access Token is only shown once, at creation time. If you did not copy it, you must generate a new one.
401 Unauthorized
A 401 means Label Studio did not accept your credentials. The
two detail messages you will see are
"Authentication credentials were not provided." and
"Invalid token.". Common causes and fixes:
-
No token was sent (
"detail": "Authentication credentials were not provided."). Confirm theAuthorizationheader is actually present on the request. This also appears when a browser-based call relies on an expired login session instead of a token. -
Wrong header scheme for the token type (
"detail": "Invalid token."). A Personal Access Token sent with theTokenscheme (or a Legacy Token sent withBearer) is rejected. Match the scheme to the token type using the table above:Bearerfor a PAT-derived access token,Tokenfor a Legacy Token. -
Malformed / unquoted header. If you run curl and see
curl: (6) Could not resolve host: TokenorURL rejected: Bad hostname, theAuthorizationheader was not quoted, so the shell split it into extra arguments. Always wrap the whole header in single quotes:-H 'Authorization: Token <token>'. - The access token expired (PAT flow). Access tokens derived from a PAT are short-lived. Per the documentation: "When that access token expires (after around 5 minutes) you'll get a 401 response, and will need to use your personal access token again." Refresh it — see Expired or rotated tokens.
-
Invalid, revoked, or wrong-instance token (
"detail": "Invalid token."). Confirm the token still exists in Account & Settings, has not been regenerated, and belongs to the instance you are calling (a token from one Label Studio instance will not work on another). - Copy/paste error. Verify there is no leading/trailing whitespace, no line break, and no truncation in the token value.
Verify a Legacy Token
curl -X GET <Label Studio URL>/api/projects \
-H 'Authorization: Token <token>'
Verify a PAT-derived access token
First exchange the PAT for a short-lived access token, then call the API with the returned value:
# 1. Get a short-lived access token from your PAT
curl -X POST <Label Studio URL>/api/token/refresh \
-H 'Content-Type: application/json' \
-d '{"refresh": "<your-personal-access-token>"}'
# Response: {"access": "<your-new-access-token>"}
# 2. Use the access token in subsequent requests
curl -X GET <Label Studio URL>/api/projects \
-H 'Authorization: Bearer <your-new-access-token>'
403 Forbidden
A 403 means your token was accepted (you are
authenticated), but the account it belongs to is
not permitted to perform that action. This is a permissions
problem, not a token problem. The response is
"detail": "You do not have permission to perform this action.".
Check the following:
- Role and membership. Confirm the user who owns the token has a role that allows the operation, and that they belong to the organization/workspace that owns the target project.
- Wrong resource. Verify the project, task, or resource ID in the URL belongs to an organization the token's user can access.
- Regenerate under the correct account. If you have multiple accounts or organizations, make sure the token was created while signed in to the correct one.
Expired or rotated tokens
-
Access token expired (PAT). The access token from
/api/token/refreshis only valid for about 5 minutes. In long-running scripts, request a fresh access token from your PAT when you receive a401, then retry the request. Do not hard-code the short-lived access token. - PAT TTL reached (Enterprise). Personal Access Tokens can have a time-to-live set at the organization level. Once the PAT itself has expired, refreshing will fail — generate a new PAT from Account & Settings > Personal Access Tokens.
-
Token rotated or deleted. If a token was deleted or
regenerated, all previously issued values stop working. Update every
script,
.envfile, CI secret, and SDK configuration with the new value.
A token type is disabled
Token types are controlled at the organization level. If PATs or Legacy Tokens suddenly stop working across your organization, the type may have been disabled.
- An organization admin goes to Organization > Settings > Access Token Settings.
- Enable the token type you need.
Important: "When a certain token type is disabled, existing tokens will not be able to authenticate to the Label Studio platform." Re-enabling the type restores authentication for existing tokens of that type.
SDK authentication errors
The Python SDK accepts either a Legacy Token or a Personal Access Token, but a PAT is recommended.
-
Set your token with the
LABEL_STUDIO_API_KEYenvironment variable (or pass it directly when initializing the client). -
If the SDK raises a
401/authentication error, confirm theLABEL_STUDIO_API_KEYvalue matches a token shown in Account & Settings, and that the base URL points to the correct Label Studio instance. A common symptom is a failure on the very first call (for example401 Client Error: Unauthorized for url: <url>/api/version), which surfaces as"detail": "Invalid token.". - A stale environment variable is a frequent cause — after rotating a token, restart the process so the new value is picked up.
ML backend returns 401 when fetching task data
If your ML backend authenticates but then fails to download task media (for
example
401 Client Error: Unauthorized for url: <url>/data/local-files/...),
the cause is almost always the token type.
ML backends support only Legacy Tokens. Personal Access Tokens are not supported and will return an Unauthorized error.
To fix it:
- Enable Legacy Tokens at the organization level (see below) and generate one for your user.
-
Set the Legacy Token as the ML backend's API key:
bash LABEL_STUDIO_API_KEY=<legacy_token> LABEL_STUDIO_URL=<Label Studio URL> # must be reachable from where the ML backend runs -
Verify the token can fetch a file from the same environment the ML backend
runs in:
bash curl -v -H 'Authorization: Token <legacy_token>' \ '<Label Studio URL>/data/local-files/?d=samples/example.png' \ --output /tmp/test.png
If you are running the ML backend in Docker, double-check the environment variable name, quoting, and that there are no stray line breaks in the value.
Webhook authentication errors
Label Studio outgoing webhooks call an external URL that
you provide. If your receiving endpoint rejects those calls (for example
with 401/403), the issue is the credentials your
endpoint expects, not your Label Studio API token.
-
In the webhook configuration, add the header(s) your endpoint requires
by clicking the + and entering the header name and value
(for example an
Authorizationheader). - Confirm the value matches what your receiving service expects and has not expired or rotated.
See Configure webhooks in Label Studio for details.
Still stuck?
If you have confirmed the token type, header scheme, validity, and permissions and still cannot authenticate, please submit a ticket with the exact request (method and endpoint), the full error response body and status code, and your Label Studio version. Do not include the token value itself.