TeamDay Docs

Authentication

How to authenticate with the Teamday API using service tokens, browser sessions, and OAuth for MCP clients.

Authentication

Teamday supports three authentication paths:

MethodUse case
Service tokenServer-side scripts, CI, local operator agents, and production automation
Browser sessionTeamday web app requests from a signed-in user
OAuth 2.1MCP 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-Id and token last_used_at to audit activity.

Supported service-token scopes:

ScopePurpose
*Full access for legacy or owner-managed integrations
agents:read, agents:writeRead or mutate agents
chats:read, chats:writeRead chats or send/create chat work
jobs:read, jobs:writeRead jobs or approve/cancel/resume/iterate work
missions:read, missions:writeRead or mutate scheduled work
workspaces:read, workspaces:writeRead or mutate workspace resources
resources:read, resources:writeRead or mutate data resources and batch/query surfaces
webhooks:read, webhooks:writeRead or mutate event delivery configuration and signing secrets
tokens:read, tokens:writeRead or mutate service tokens
mcpUse 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-resource

Supported scope:

ScopePurpose
mcpUse Teamday MCP tools for the authorized organization and user

Teamday supports authorization-code OAuth with PKCE for dynamic MCP clients.

OAuth metadata advertises:

  • authorization_endpoint
  • token_endpoint
  • registration_endpoint
  • code_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-Id for 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:

  1. Create a replacement token.
  2. Deploy the replacement secret.
  3. Verify the integration works.
  4. 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.

On this page