# Authentication

How to authenticate with the TeamDay API using Personal Access Tokens (PAT) and Organization API Tokens (OTK).

# Authentication

The TeamDay API supports multiple authentication methods. All API requests must include a valid token in the `Authorization` header.

| Method | Prefix | Use case |
|--------|--------|----------|
| [Personal Access Token](https://docs.teamday.ai/api/tokens) | `td_` | User-level API access, CI/CD, scripts |
| [Organization API Token](https://docs.teamday.ai/api/org-tokens) | `otk_` | Org-level service integrations, webhooks, scoped access |
| OAuth (CLI) | — | Interactive CLI sessions |
| Firebase JWT | — | Browser/web app sessions |

**For programmatic access:** Use PATs for user-scoped operations (agents, spaces, executions). Use Org Tokens for service integrations (newsletter, future services) — they support scopes and aren't tied to a specific user.

---

## Getting Your Access Token

### Step 1: Generate Token

1. Log in to your TeamDay account at [cc.teamday.ai](https://cc.teamday.ai)
2. Navigate to **Settings → API Access**
3. Click **Generate New Token**
4. Optionally set a custom expiration (7-365 days, default: 90 days)
5. Copy your token immediately - you won't be able to see it again!

### Step 2: Store Securely

**Your token will look like this:**
```
td_AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AbCdE
```

**Token format:**
- Prefix: `td_` (identifies TeamDay tokens)
- Length: 43 alphanumeric characters after prefix
- Encoding: Base64url (URL-safe)

**Store in environment variables:**

```bash
# Unix/Linux/macOS
export TEAMDAY_TOKEN="td_your-actual-token-here"

# Windows (PowerShell)
$env:TEAMDAY_TOKEN="td_your-actual-token-here"

# Or in .env file (for local development)
TEAMDAY_TOKEN=td_your-actual-token-here
```

---

## Using Your Token

Include your token in the `Authorization` header with the `Bearer` scheme:

```http
Authorization: Bearer td_your-actual-token-here
```

### Example Requests

**List agents:**
```bash
curl https://cc.teamday.ai/api/v1/agents \
  -H "Authorization: Bearer $TEAMDAY_TOKEN"
```

**Create an agent:**
```bash
curl -X POST https://cc.teamday.ai/api/v1/agents \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Research Assistant",
    "role": "Research and analysis",
    "systemPrompt": "You are a helpful research assistant.",
    "visibility": "organization"
  }'
```

**Get execution details:**
```bash
curl https://cc.teamday.ai/api/v1/executions/exec-1734567890-abc \
  -H "Authorization: Bearer $TEAMDAY_TOKEN"
```

---

## Token Security Features

### Encryption at Rest

Tokens are protected with enterprise-grade security:

- **Hashing:** SHA-256 hash stored in database (irreversible)
- **Encryption:** AES-256-GCM encryption for token metadata
- **No plain-text storage:** Original token never stored after creation

### Automatic Validation

Every API request validates:

1. **Token format** - Correct prefix and length
2. **Hash lookup** - Token exists in database
3. **Expiration** - Token not expired
4. **Organization scope** - User belongs to organization
5. **Last used tracking** - Updated on each request

### Scoping

Each token is scoped to:
- **User:** Token belongs to specific user (creator)
- **Organization:** Inherits user's organization membership
- **Permissions:** Uses user's role and permissions

**Important:** Tokens inherit the permissions of the user who created them. If a user's access is revoked, their tokens stop working immediately.

---

## Token Management

### View Active Tokens

See all your active tokens in **Settings → API Access**:

- Token name (optional label)
- Creation date
- Last used timestamp
- Expiration date
- Permissions scope

### Revoke Tokens

**Immediately revoke a token:**

1. Go to **Settings → API Access**
2. Find the token in your list
3. Click **Revoke**
4. Confirm deletion

**When to revoke:**
- Token compromised or exposed
- Team member leaves organization
- Token no longer needed
- Rotating credentials (security best practice)

### Token Expiration

**Default expiration:** 90 days

**Custom expiration:**
- Minimum: 7 days
- Maximum: 365 days

**What happens when expired:**
- API requests return `401 Unauthorized`
- Error message: `"Token expired"`
- Token automatically cleaned up (soft delete)

**Auto-renewal:** Not supported. Generate a new token before expiration.

---

## Error Responses

### Missing Token

**Request:**
```bash
curl https://cc.teamday.ai/api/v1/agents
```

**Response:**
```json
{
  "error": true,
  "statusCode": 401,
  "statusMessage": "Unauthorized",
  "message": "Unauthorized. Missing or invalid Authorization header. Expected: Bearer <token>"
}
```

### Invalid Token

**Request:**
```bash
curl https://cc.teamday.ai/api/v1/agents \
  -H "Authorization: Bearer invalid_token"
```

**Response:**
```json
{
  "error": true,
  "statusCode": 401,
  "statusMessage": "Unauthorized",
  "message": "Unauthorized. Invalid or expired token"
}
```

### Expired Token

**Request:**
```bash
curl https://cc.teamday.ai/api/v1/agents \
  -H "Authorization: Bearer td_expired_token"
```

**Response:**
```json
{
  "error": true,
  "statusCode": 401,
  "statusMessage": "Unauthorized",
  "message": "Token expired"
}
```

---

## Security Best Practices

### Do's ✅

- **Store tokens in environment variables** - Never hardcode in source
- **Use separate tokens per integration** - Easier to track and revoke
- **Set appropriate expiration dates** - Shorter for high-risk environments
- **Rotate tokens regularly** - Especially for production systems
- **Revoke immediately if compromised** - Better safe than sorry
- **Use HTTPS only** - Never send tokens over plain HTTP
- **Monitor token usage** - Check "last used" timestamps regularly

### Don'ts ❌

- **Never commit tokens to Git** - Use `.gitignore` for `.env` files
- **Never share tokens** - Each integration should have its own
- **Never log tokens** - Redact from application logs
- **Never send in URL parameters** - Use headers only
- **Never reuse across environments** - Dev/staging/prod should have separate tokens
- **Never store in client-side code** - Tokens are for server-side use only

### Environment Variables Example

```bash
# .env (add to .gitignore!)
TEAMDAY_TOKEN=td_your-actual-token-here

# Usage in code
const token = process.env.TEAMDAY_TOKEN

const response = await fetch('https://cc.teamday.ai/api/v1/agents', {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  }
})
```

---

## Token Rotation Strategy

**Recommended rotation schedule:**

- **Development:** 90 days (default)
- **Staging:** 60 days
- **Production:** 30 days
- **High-security:** 7 days

**How to rotate without downtime:**

1. **Generate new token** (don't revoke old one yet)
2. **Update applications** to use new token
3. **Deploy and verify** new token works
4. **Monitor for 24-48 hours** (check old token usage)
5. **Revoke old token** once confirmed unused

---

## Rate Limiting

**Current status:** No rate limits enforced

**Best practices:**
- Implement exponential backoff for retries
- Cache responses when appropriate
- Use reasonable request rates (< 100 req/min recommended)

**Future:** Rate limits may be introduced. We'll provide advance notice and documentation.

---

## Alternative Auth Methods

In addition to PATs, the API supports:

- **Organization API Tokens (`otk_`):** Org-scoped tokens with service-level scoping. Ideal for integrations that shouldn't be tied to a specific user. See [Organization API Tokens](https://docs.teamday.ai/api/org-tokens).
- **OAuth tokens from CLI:** The TeamDay CLI uses an OAuth flow that produces tokens accepted by the API. These tokens auto-refresh but require a browser for initial authentication.
- **JWT tokens:** Authenticated web sessions produce JWT tokens that are also valid for API requests.

For server-side automation and CI/CD, PATs remain the recommended approach. For service integrations (newsletter sync, webhooks), use Org Tokens.

---

## Testing Your Token

**Quick test:**
```bash
# Should return list of agents (or empty array)
curl https://cc.teamday.ai/api/v1/agents \
  -H "Authorization: Bearer $TEAMDAY_TOKEN"

# Success response (example)
{
  "success": true,
  "agents": [
    {
      "id": "abc123def456",
      "name": "My Agent",
      "role": "Assistant",
      "createdAt": "2025-12-09T12:00:00Z"
    }
  ],
  "total": 1
}
```

**If you see `401 Unauthorized`:**
1. Verify token copied correctly (no extra spaces)
2. Check token not expired in Settings → API Access
3. Confirm user still has organization access
4. Try generating a fresh token

---

## Need Help?

**Token not working?**
- Check [error reference](https://docs.teamday.ai/api/errors) for troubleshooting
- Verify format: `td_` + 43 characters (PAT) or `otk_` + 43 characters (Org Token)
- Confirm not expired in dashboard
- For org tokens, verify the scope includes the service you're accessing

**Questions?**
- 📧 Email: support at teamday.ai
- 💬 Discord: [Join community](https://discord.gg/teamday)

---

**Last Updated:** February 19, 2026
