Authentication
The Parallel Works API supports several authentication methods. Choose the one that best fits your use case. Only one method should be used per request.
Which method should I use?
Bearer Tokens
Best for scripts, CLI tools, and short-lived automation.
- 24-hour expiration (secure)
- Easy to generate from UI
- Works with PW CLI
API Keys
Best for backend integrations and automated systems.
- Configurable expiration
- No manual refresh needed
- Requires Base64 encoding
Cookies
Automatic when using the ACTIVATE web interface.
- Zero configuration
- Handled by browser
- Not for programmatic use
Bearer Token Authentication
Bearer tokens (JWTs) are the recommended method for most programmatic access. Tokens are generated from your account settings and expire after 24 hours.
Getting a Token
- Log in to activate.parallel.works
- Navigate to Account Settings → Tokens
- Click Generate Token
- Copy the token immediately (it won't be shown again)
Usage
Include the token in the Authorization header:
HTTP HeaderAuthorization: Bearer YOUR_TOKENcURLcurl -H "Authorization: Bearer YOUR_TOKEN" \
https://activate.parallel.works/api/auth/sessionPythonimport requests
token = "YOUR_TOKEN"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(
"https://activate.parallel.works/api/auth/session",
headers=headers
)
print(response.json())JavaScriptconst token = "YOUR_TOKEN";
const response = await fetch("https://activate.parallel.works/api/auth/session", {
headers: {
"Authorization": `Bearer ${token}`,
},
});
const data = await response.json();
console.log(data);API Key Authentication (Basic Auth)
API keys are ideal for long-running integrations. They use HTTP Basic Auth with the API key as the username and an empty password.
Getting an API Key
- Log in to activate.parallel.works
- Navigate to Account Settings → API Keys
- Click Create API Key
- Set a title and optional expiration date
- Copy the key immediately (it won't be shown again)
Usage
The API key must be Base64 encoded with a trailing colon (since the password is empty):
Encoding# Your API key followed by a colon
API_KEY:
# Base64 encode it
echo -n "YOUR_API_KEY:" | base64
# Result: WU9VUl9BUElfS0VZOg==HTTP HeaderAuthorization: Basic WU9VUl9BUElfS0VZOg==cURL# Option 1: Let cURL handle encoding
curl -u "YOUR_API_KEY:" \
https://activate.parallel.works/api/auth/session
# Option 2: Manual encoding
curl -H "Authorization: Basic $(echo -n 'YOUR_API_KEY:' | base64)" \
https://activate.parallel.works/api/auth/sessionPythonimport requests
from requests.auth import HTTPBasicAuth
api_key = "YOUR_API_KEY"
response = requests.get(
"https://activate.parallel.works/api/auth/session",
auth=HTTPBasicAuth(api_key, "") # Empty password
)
print(response.json())JavaScriptconst apiKey = "YOUR_API_KEY";
const encoded = btoa(`${apiKey}:`);
const response = await fetch("https://activate.parallel.works/api/auth/session", {
headers: {
"Authorization": `Basic ${encoded}`,
},
});
const data = await response.json();
console.log(data);Gopackage main
import (
"encoding/base64"
"fmt"
"io"
"net/http"
)
func main() {
apiKey := "YOUR_API_KEY"
encoded := base64.StdEncoding.EncodeToString([]byte(apiKey + ":"))
req, _ := http.NewRequest("GET", "https://activate.parallel.works/api/auth/session", nil)
req.Header.Add("Authorization", "Basic "+encoded)
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}Cookie-based Authentication
Cookie authentication is used automatically when accessing the API through the ACTIVATE web UI. The session cookie (cloud.sso) is set after login and managed by the browser.
Not for programmatic use
Cookie authentication is only suitable for browser-based applications. For scripts, CLI tools, or backend integrations, use Bearer tokens or API keys.
Error Responses
Authentication errors return standard HTTP status codes:
| Status | Description | Solution |
|---|---|---|
401 | Unauthorized | Check your token/API key is correct and not expired |
403 | Forbidden | Your credentials are valid but you lack permission |
429 | Too Many Requests | Rate limited - wait and retry with exponential backoff |
Best Practices
Use Environment Variables
Never hardcode credentials. Store them in environment variables or a secrets manager.
Shellexport PW_API_KEY="your-api-key"
curl -u "$PW_API_KEY:" https://...Rotate Keys Regularly
Set expiration dates on API keys and rotate them periodically. Delete unused keys promptly.
Use HTTPS Only
Always use HTTPS URLs. HTTP requests will be rejected to protect your credentials.
Handle Token Refresh
For long-running scripts, implement token refresh logic or use API keys which don't require manual renewal.