Authentication
How to authenticate with the Teamday API using service tokens, browser sessions, and OAuth for MCP clients.
Authentication
Teamday supports three authentication paths:
| Method | Use case |
|---|---|
| Service token | Server-side scripts, CI, local operator agents, and production automation |
| Browser session | Teamday web app requests from a signed-in user |
| OAuth 2.1 | MCP clients connecting to Teamday tools with PKCE and the mcp scope |
For most API integrations, use a service token:
Authorization: Bearer <teamday-service-token>Service Tokens
Create service tokens from Teamday's Security or API access settings, or through the API when signed in:
POST /api/service-tokens
Content-Type: application/json
{
"name": "Production support integration",
"scopes": ["agents:read", "chats:write", "jobs:read"]
}The response includes the token once. Store it in a secret manager or environment variable.
export TEAMDAY_TOKEN="<teamday-service-token>"Use it on every request:
curl https://app.teamday.ai/api/agents \
-H "Authorization: Bearer $TEAMDAY_TOKEN"Service tokens are intentionally integration-specific:
- Create one token per automation or agent runner.
- Tokens are bound to the issuing user and organization.
- Tokens can be scoped by resource family and action.
- Workspace-aware endpoints accept workspace identifiers so access stays inside the selected workspace context.
- Revoke a single token without affecting other integrations.
- Use
X-Request-Idand tokenlast_used_atto audit activity.
Supported service-token scopes:
| Scope | Purpose |
|---|---|
* | Full access for legacy or owner-managed integrations |
agents:read, agents:write | Read or mutate agents |
chats:read, chats:write | Read chats or send/create chat work |
jobs:read, jobs:write | Read jobs or approve/cancel/resume/iterate work |
missions:read, missions:write | Read or mutate scheduled work |
workspaces:read, workspaces:write | Read or mutate workspace resources |
resources:read, resources:write | Read or mutate data resources and batch/query surfaces |
webhooks:read, webhooks:write | Read or mutate event delivery configuration and signing secrets |
tokens:read, tokens:write | Read or mutate service tokens |
mcp | Use Teamday MCP tools |
When a bearer service token lacks a required scope, Teamday returns 403 insufficient_scope with required_scopes in the error details and a WWW-Authenticate scope hint.
OAuth For MCP Clients
MCP clients should discover Teamday's OAuth metadata:
https://app.teamday.ai/.well-known/oauth-authorization-server
https://app.teamday.ai/.well-known/oauth-protected-resourceSupported scope:
| Scope | Purpose |
|---|---|
mcp | Use Teamday MCP tools for the authorized organization and user |
Teamday supports authorization-code OAuth with PKCE for dynamic MCP clients.
OAuth metadata advertises:
authorization_endpointtoken_endpointregistration_endpointcode_challenge_methods_supported: ["S256"]- resource metadata through
/.well-known/oauth-protected-resource
Security Defaults
- Service tokens are hashed at rest.
- Service-token scopes are enforced before route handlers for bearer-authenticated API calls.
- Tokens can be revoked without deleting the user.
- Token plaintext is returned only once at creation.
- User-bound OAuth tokens preserve the authorizing user and organization boundary.
- MCP resource access is scoped to the authorized organization and user.
- API responses include
X-Request-Idfor audit and support correlation. - Webhook signing secrets rotate independently from API tokens.
Token Rotation
Use one token per integration so it can be revoked independently. Rotate production tokens on a schedule and immediately after exposure.
Recommended pattern:
- Create a replacement token.
- Deploy the replacement secret.
- Verify the integration works.
- Revoke the old token.
Authentication Errors
Missing or invalid credentials return 401. Include the X-Request-Id response header when debugging.
{
"code": "unauthorized",
"message": "Authentication failed.",
"status": 401,
"request_id": "req_..."
}Older endpoints may return a compact legacy body such as { "error": "not authenticated" } while the route surface is being normalized.