Authentication
June 5, 2026 · View on GitHub
Every Taskade developer surface — the REST API v1, the Action API v2, and the MCP servers — authenticates with a Bearer token. There are two kinds you can create.
Which credential should I use?
| If you are… | Use | How |
|---|---|---|
Writing a script, or using the SDK / CLI / inbound @taskade/mcp-server | Personal Access Token | Authorization: Bearer tskdp_… |
| Building a third-party app that acts on behalf of other users | OAuth 2.0 (Authorization Code + PKCE) | Redirect flow |
Connecting Claude / Cursor to the hosted MCP at taskade.com/mcp | OAuth 2.0 | Handled automatically by the MCP client |
Personal Access Tokens
The simplest way to authenticate as yourself. Best for server-to-server scripts, the inbound MCP server, and getting started.
Create a token
- Go to taskade.com/settings/api.
- Click Create new token and give it a descriptive name.
- Copy the token immediately — it is shown only once.
A personal access token starts with the prefix tskdp_. You can hold up to 5 tokens per account, and your email must be verified to create one.
{% hint style="warning" %} A personal access token grants full access to your account. Treat it like a password: never commit it to version control, never share it, and store it in an environment variable or secret manager. {% endhint %}
Use a token
Send it in the Authorization header on every request:
# REST API v1
curl -H "Authorization: Bearer tskdp_your_token" \
https://www.taskade.com/api/v1/me/projects
# Action API v2
curl -X POST https://www.taskade.com/api/v2/listMyProjects \
-H "Authorization: Bearer tskdp_your_token" \
-H "Content-Type: application/json" -d '{}'
The inbound MCP server reads it from the TASKADE_API_KEY environment variable — see Workspace MCP.
OAuth 2.0
Use OAuth 2.0 when your application acts on behalf of other users (so each user signs in and grants access), or when connecting to the hosted MCP endpoint.
Endpoints
| Purpose | URL |
|---|---|
| Authorization | https://www.taskade.com/oauth2/authorize |
| Token / Refresh | https://www.taskade.com/oauth2/token |
| Dynamic client registration | https://www.taskade.com/oauth2/register |
| Server metadata (RFC 8414) | https://www.taskade.com/.well-known/oauth-authorization-server |
Register an application
Go to taskade.com/settings/password → OAuth 2.0 Apps and register your app to obtain a Client ID and Client Secret, and to set your redirect URI(s).
Authorization Code flow (with PKCE)
Taskade supports the Authorization Code grant with PKCE (S256) — the recommended flow for both confidential and public clients.
sequenceDiagram
participant App as Your App
participant Taskade as www.taskade.com
participant User as End User
App->>Taskade: GET /oauth2/authorize?client_id&redirect_uri&code_challenge&scope
Taskade->>User: Show consent screen
User->>Taskade: Approve
Taskade->>App: Redirect with authorization code
App->>Taskade: POST /oauth2/token (code + code_verifier)
Taskade->>App: access_token (1 hour) + refresh_token
App->>Taskade: API request with Bearer access_token
- Redirect the user to
/oauth2/authorizewithclient_id,redirect_uri,response_type=code, a PKCEcode_challenge(andcode_challenge_method=S256), and anyscope. - Exchange the returned
codeat/oauth2/token(grant_type=authorization_code) along with yourcode_verifier. Confidential apps also sendclient_secret; public clients use PKCE only. - You receive an
access_token(valid for 1 hour) and arefresh_token.
Generating the PKCE pair (the step most implementations get wrong):
# code_verifier: a high-entropy random string
code_verifier=$(openssl rand -base64 96 | tr -d '\n=+/' | cut -c1-64)
# code_challenge = BASE64URL( SHA256(code_verifier) )
code_challenge=$(printf '%s' "$code_verifier" \
| openssl dgst -binary -sha256 \
| openssl base64 | tr -d '=\n' | tr '+/' '-_')
Send code_challenge (with code_challenge_method=S256) on the authorize request, then send the original code_verifier on the token exchange below.
curl -X POST https://www.taskade.com/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "code_verifier=PKCE_VERIFIER" \
-d "client_id=YOUR_CLIENT_ID" \
-d "redirect_uri=YOUR_REDIRECT_URI"
Refresh an expired token
Access tokens expire after one hour. Exchange the stored refresh token for a new one:
curl -X POST https://www.taskade.com/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=YOUR_REFRESH_TOKEN" \
-d "client_id=YOUR_CLIENT_ID"
{% hint style="info" %}
Only authorization_code and refresh_token grants are supported. password, implicit, and client_credentials are rejected.
{% endhint %}
Scopes & the hosted MCP
The hosted MCP server at taskade.com/mcp requires an OAuth token carrying the mcp scope. MCP clients (Claude Desktop, Cursor, Claude Code) perform this OAuth handshake — including dynamic client registration — automatically when you add the server URL, so you normally don't implement it yourself.
Security Best Practices
- Never expose tokens in client-side code. Personal tokens grant full account access.
- Use OAuth, not personal tokens, for any app used by more than one person.
- Store refresh tokens encrypted at rest — they're long-lived.
- Rotate personal tokens periodically; you can keep up to 5 active.
- Always use HTTPS.
Related
{% content-ref url="personal-tokens.md" %} personal-tokens.md {% endcontent-ref %}
{% content-ref url="../api-v2-reference.md" %} Action API v2 Reference {% endcontent-ref %}