# API Best Practices

Best practices for building reliable integrations with the TeamDay API — authentication, error handling, agent design, and performance.

# API Best Practices

Guidelines for building reliable, secure, and efficient integrations with the TeamDay API.

---

## Authentication

### Token Management

- **One token per integration** — easier to track and revoke if compromised
- **Use environment variables** — never hardcode tokens in source code
- **Rotate regularly** — 30-90 days depending on environment sensitivity
- **Revoke immediately** if a token is exposed in logs, commits, or error messages

```bash
# Good: environment variable
export TEAMDAY_TOKEN="td_your-actual-token-here"

# Bad: hardcoded in script
curl -H "Authorization: Bearer td_AbCdEfGh..."  # Don't do this
```

### Token Security

- Store in environment variables or secret managers (AWS Secrets Manager, Vault, etc.)
- Add `.env` to `.gitignore`
- Never log tokens — redact from application logs
- Never send tokens in URL parameters — use the `Authorization` header only
- Use separate tokens for dev/staging/production

See [Authentication docs](https://docs.teamday.ai/api/authentication) for token generation and rotation strategies.

---

## Error Handling

### Retry Strategy

Retry **server errors (5xx)** with exponential backoff. Don't retry **client errors (4xx)** — fix the request instead.

```javascript
async function apiCall(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options)

    if (response.ok) return response.json()

    // Client errors: don't retry
    if (response.status >= 400 && response.status < 500) {
      const error = await response.json()
      throw new Error(`${response.status}: ${error.message}`)
    }

    // Server errors: retry with backoff
    if (attempt < maxRetries - 1) {
      const delay = Math.pow(2, attempt) * 1000 // 1s, 2s, 4s
      await new Promise(resolve => setTimeout(resolve, delay))
    }
  }
  throw new Error('Max retries exceeded')
}
```

### Common Error Codes

| Code | Meaning | Action |
|------|---------|--------|
| 400 | Bad Request | Fix request body — check required fields and types |
| 401 | Unauthorized | Check token — may be expired or malformed |
| 403 | Forbidden | Agent or resource belongs to a different organization |
| 404 | Not Found | Verify resource ID — it may have been deleted |
| 500 | Server Error | Retry with backoff — report if persistent |

See [Error Reference](https://docs.teamday.ai/api/errors) for the complete list.

---

## Agent Design

### System Prompts

The system prompt is the most important part of your agent. A well-written prompt dramatically improves output quality.

**Do:**
- Be specific about the agent's role and boundaries
- Include examples of desired output format
- Set clear rules for what the agent should and shouldn't do
- Keep under 2000 characters for best performance

**Don't:**
- Include API keys or credentials in prompts
- Write vague instructions like "be helpful"
- Overload a single agent with unrelated responsibilities

```json
{
  "systemPrompt": "You are a code review assistant for Python projects.\n\nFor each review:\n1. Check for security vulnerabilities (SQL injection, XSS, etc.)\n2. Flag performance issues\n3. Suggest readability improvements\n\nFormat: use ## Critical, ## Important, ## Minor sections.\nBe specific — reference line numbers and suggest fixes."
}
```

### Agent Granularity

- **One agent per domain** — a "Code Reviewer" agent, a "Data Analyst" agent
- **Reuse agents with different messages** rather than creating a new agent per task
- **Use Spaces** to give the same agent different tools and context for different projects

### Naming Conventions

- Use descriptive, action-oriented names: "Python Code Reviewer", "Weekly Analytics Reporter"
- Avoid generic names: "Agent 1", "My Agent", "Test"
- Include the domain or specialty in the name

---

## Execution Patterns

### Session Continuity

Pass `sessionId` from previous responses to continue conversations with full context:

```bash
# First message
RESULT=$(curl -s -X POST https://cc.teamday.ai/api/v1/agents/$AGENT_ID/execute \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message": "Analyze our Q4 revenue data"}')

SESSION_ID=$(echo $RESULT | jq -r '.sessionId')

# Follow-up with context
curl -X POST https://cc.teamday.ai/api/v1/agents/$AGENT_ID/execute \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"message\": \"Now compare with Q3\", \"sessionId\": \"$SESSION_ID\"}"
```

### Space-Scoped Execution

Execute agents within a Space to give them access to tools, files, and secrets:

```bash
curl -X POST https://cc.teamday.ai/api/v1/agents/$AGENT_ID/execute \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Review the latest pull requests",
    "spaceId": "your-space-id"
  }'
```

The agent will have access to all MCP servers, skills, and secrets configured in that Space.

---

## Scheduling with Missions

### Choose the Right Schedule Type

| Type | Use Case | Example |
|------|----------|---------|
| `once` | One-time task, run immediately | Ad-hoc data analysis |
| `cron` | Recurring on a schedule | Daily reports, weekly reviews |
| `continuous` | Run continuously (agent stays active) | Monitoring, real-time processing |
| `none` | Manual trigger only | Template missions |

### Mission Design

- **Clear goals** — write `goal` as a complete instruction the agent can act on independently
- **Pair with a Space** — set `spaceId` so the agent has access to tools and context
- **Link an agent** — set `characterId` (the agent's ID) so the mission uses the right system prompt and model

> **Note:** The `characterId` field is the agent's ID. This field name is preserved for API compatibility.

```json
{
  "title": "Weekly SEO Report",
  "goal": "Analyze this week's search performance. Compare organic traffic, top queries, and ranking changes vs last week. Highlight any pages that dropped more than 5 positions. Save the report as weekly-seo-report.md.",
  "icon": "📊",
  "characterId": "your-agent-id",
  "spaceId": "your-space-id",
  "schedule": { "type": "cron", "value": "0 9 * * 1" }
}
```

---

## Performance Tips

- **Cache responses** when appropriate — don't re-execute for the same query
- **Use reasonable request rates** — stay under 100 requests/minute
- **Be specific in messages** — vague prompts produce longer, more expensive responses
- **Use `sessionId`** for multi-turn conversations instead of repeating context in each message
- **Set visibility to `private`** for experimental agents to keep your agent list clean

---

## Security Checklist

Before going to production:

- [ ] Tokens stored in environment variables or secret manager
- [ ] `.env` files added to `.gitignore`
- [ ] No credentials in agent system prompts
- [ ] Separate tokens for dev/staging/production environments
- [ ] Token rotation schedule documented
- [ ] Error responses don't leak sensitive information in logs

---

## Related Resources

- [Authentication](https://docs.teamday.ai/api/authentication) — Token management and security
- [API Examples](https://docs.teamday.ai/api/examples) — Quick-start code snippets
- [Error Reference](https://docs.teamday.ai/api/errors) — Complete error code documentation
- [Code Review Bot](https://docs.teamday.ai/examples/code-review-bot) — Full tutorial example

---

**Last Updated:** February 19, 2026
