Source:
oceanid/cluster/docs/LABEL_STUDIO_API.md| ✏️ Edit on GitHub
Label Studio API Authentication
Overview
Label Studio 1.21.0 uses JWT-based Personal Access Tokens (PAT) for API authentication. The PAT acts as a refresh token that must be exchanged for short-lived access tokens.
Authentication Flow
PAT (Refresh Token)
→ /api/token/refresh
→ Access Token (5 min expiry)
→ API Requests
Step-by-Step Guide
1. Get Your PAT
- Log into Label Studio:
https://label.boathou.se - Navigate to: User Account → Personal Access Token
- Copy the JWT token (starts with
eyJ...) - Store in 1Password:
Development/Label Studio PAT
2. Exchange PAT for Access Token
# Get PAT from 1Password
PAT=$(op read "op://Development/Label Studio PAT/credential")
# Exchange for access token
curl -X POST https://label.boathou.se/api/token/refresh \
-H "Content-Type: application/json" \
-d "{\"refresh\": \"$PAT\"}" | jq -r '.access'
Response:
{
"access": "eyJhbGci...short-lived-token"
}
3. Use Access Token with API
ACCESS_TOKEN="eyJhbGci...from-step-2"
# Make API request
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
https://label.boathou.se/api/projects/
Helper Function
Add to your shell profile:
ls_token() {
PAT=$(op read "op://Development/Label Studio PAT/credential")
curl -s -X POST https://label.boathou.se/api/token/refresh \
-H "Content-Type: application/json" \
-d "{\"refresh\": \"$PAT\"}" | jq -r '.access'
}
# Usage
curl -H "Authorization: Bearer $(ls_token)" \
https://label.boathou.se/api/projects/
Python SDK Example
import requests
# Get PAT from environment or 1Password
PAT = "your-pat-token"
# Exchange for access token
response = requests.post(
"https://label.boathou.se/api/token/refresh",
json={"refresh": PAT}
)
access_token = response.json()["access"]
# Use with Label Studio SDK
from label_studio_sdk import Client
client = Client(
url="https://label.boathou.se",
api_key=access_token # Use access token, not PAT
)
# Now you can use the SDK
projects = client.list_projects()
Important Notes
Token Lifetime
- PAT (Refresh Token): Long-lived, store securely
- Access Token: ~5 minutes, refresh when expired
Authentication Scheme
- Correct:
Authorization: Bearer <access-token> - Incorrect:
Authorization: Token <pat>(won't work)
Token Storage
- PAT: Store in 1Password, never commit to git
- Access Token: Generate on-demand, don't store
Error Handling
401 Unauthorized
{"detail": "Given token not valid for any token type"}
Solution: Your access token expired. Get a new one from PAT.
400 Bad Request
{"refresh": ["This field may not be blank."]}
Solution: PAT not provided or empty. Check your environment variable.
API Endpoints
Token Management
POST /api/token/refresh- Exchange PAT for access tokenPOST /api/token/verify- Verify access token validity
Common Endpoints
GET /api/projects/- List projectsPOST /api/projects/- Create projectGET /api/projects/{id}/tasks/- List tasksPOST /api/projects/{id}/tasks/- Create task
Full API reference: https://api.labelstud.io
Troubleshooting
"Authentication credentials were not provided"
- Check Authorization header format:
Bearer <token> - Ensure you're using access token, not PAT
- Verify token isn't expired
"Invalid token"
- PAT cannot be used directly with API
- Must exchange PAT for access token first
- Access token expires after 5 minutes
Shell Variable Issues
- Avoid
$()in zsh - use xargs or temp files - Use
op readinstead ofop item getfor simplicity - Quote tokens properly to avoid special char issues
Related Documentation
S3 Storage
Label Studio is configured with S3 persistent storage. Files uploaded via API will be automatically stored in s3://labelstudio-goldfish-uploads/.
ML Backend Integration
The ML backend at http://ls-triton-adapter.apps.svc.cluster.local:9090 can be accessed from within the cluster. For external access, it should also use PAT-based authentication.