Docs · api

Agents API

Create, manage, and execute AI agents programmatically with the TeamDay Agents API.

Agents API

Agents are AI employees with a name, role, tools, permissions, and missions. Use the Agents API to create and manage private organization agents, install Ready Agents, and inspect Teamday Agents available to your organization.

Not every agent is fully editable:

  • Ready Agents are Teamday-maintained products. Your organization configures credentials, workspace scope, schedules, and local context; Teamday manages the global prompt, tool policy, outcome rubric, and upgrade path.
  • Teamday Agents are Teamday-operated staff that can appear inside your organization, such as Daisy. You can chat with them and grant local context, but you cannot edit their core definition.
  • Private Agents are organization-owned agents. These are the editable path when you need your own prompt, integrations, and missions.

Base URL: https://cc.teamday.ai/api/v1/agents

Authentication: Personal Access Token required


Endpoints Overview

MethodEndpointDescriptionStatus
GET/agentsList all agents✅ Working
POST/agentsCreate new agent✅ Working
GET/agents/[id]Get agent details✅ Working
PATCH/agents/[id]Update agent✅ Working
DELETE/agents/[id]Delete agent✅ Working
POST/agents/[id]/executeExecute agent✅ Working

Test Results: 6/6 endpoints operational


Agent Object

Properties

{
  id: string              // Agent ID (Firestore auto-generated)
  name: string            // Display name
  role: string            // Agent role/purpose
  systemPrompt: string | null // Visible only for editable Private Agents
  ownershipType: string   // "private_agent" | "ready_agent" | "teamday_agent"
  mutability: string      // "full" | "config_only" | "none"
  visibility: string      // "private" | "organization" | "public" | "unlisted"
  organizationId: string  // Owner organization
  userId: string          // Creator user ID
  createdAt: string       // ISO 8601 timestamp
  updatedAt: string       // ISO 8601 timestamp
  archived?: boolean      // True if soft-deleted
}

Example Object

{
  "id": "abc123def456",
  "name": "Research Assistant",
  "role": "Research and data analysis",
  "systemPrompt": "You are a helpful research assistant specializing in data analysis and summarization.",
  "ownershipType": "private_agent",
  "mutability": "full",
  "visibility": "organization",
  "organizationId": "org_xyz789",
  "userId": "user_456",
  "createdAt": "2025-12-09T10:30:00Z",
  "updatedAt": "2025-12-09T10:30:00Z"
}

List Agents

Retrieve all agents for your organization.

Request

GET /api/v1/agents

Headers:

Authorization: Bearer td_xxxxx...

Query Parameters: None

Response

Success (200 OK):

{
  "success": true,
  "agents": [
    {
      "id": "abc123def456",
      "name": "Research Assistant",
      "role": "Research and analysis",
          "systemPrompt": "You are a helpful research assistant.",
          "ownershipType": "private_agent",
          "mutability": "full",
      "visibility": "organization",
      "organizationId": "org_xyz789",
      "userId": "user_456",
      "createdAt": "2025-12-09T10:30:00Z",
      "updatedAt": "2025-12-09T10:30:00Z"
    },
    {
      "id": "def456ghi789",
      "name": "Code Reviewer",
      "role": "Code review and suggestions",
          "systemPrompt": null,
          "ownershipType": "ready_agent",
          "mutability": "config_only",
      "visibility": "organization",
      "organizationId": "org_xyz789",
      "userId": "user_789",
      "createdAt": "2025-12-08T15:20:00Z",
      "updatedAt": "2025-12-09T09:15:00Z"
    }
  ],
  "total": 2
}

Empty result:

{
  "success": true,
  "agents": [],
  "total": 0
}

Error (401 Unauthorized):

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

Example

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

Create Agent

Create a new private AI agent for your organization.

Request

POST /api/v1/agents

Headers:

Authorization: Bearer td_xxxxx...
Content-Type: application/json

Body:

{
  "name": "Research Assistant",
  "role": "Research and data analysis",
  "systemPrompt": "You are a helpful research assistant specializing in data analysis and summarization.",
  "visibility": "organization"
}

Required Fields:

  • name (string) - Agent display name
  • systemPrompt (string) - System instructions for a private agent

Optional Fields:

  • role (string) - Agent role description (default: "Assistant")
  • visibility (string) - Access level: "private", "organization", "public", or "unlisted" (default: "organization")

Ready Agents and Teamday Agents are installed or exposed through Teamday product flows. Their core prompts are not writable through this endpoint.

Response

Success (200 OK):

{
  "success": true,
  "id": "abc123def456",
  "name": "Research Assistant",
  "status": "active",
  "chatUrl": "/org/spaces/spaceId/chats/chatId"
}

Error (400 Bad Request):

{
  "error": true,
  "statusCode": 400,
  "statusMessage": "Bad Request",
  "message": "Missing required field: name"
}

Error (401 Unauthorized):

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

Example

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 data analysis",
    "systemPrompt": "You are a helpful research assistant specializing in data analysis and summarization.",
    "visibility": "organization"
  }'

Get Agent

Retrieve details for a specific agent by ID.

Request

GET /api/v1/agents/[id]

Headers:

Authorization: Bearer td_xxxxx...

Path Parameters:

  • id (string) - Agent ID (Firestore auto-generated)

Response

Success (200 OK):

{
  "success": true,
  "agent": {
    "id": "abc123def456",
    "name": "Research Assistant",
    "role": "Research and data analysis",
    "systemPrompt": "You are a helpful research assistant specializing in data analysis and summarization.",
    "visibility": "organization",
    "organizationId": "org_xyz789",
    "userId": "user_456",
    "createdAt": "2025-12-09T10:30:00Z",
    "updatedAt": "2025-12-09T10:30:00Z"
  }
}

Error (404 Not Found):

{
  "error": true,
  "statusCode": 404,
  "statusMessage": "Not Found",
  "message": "Agent not found"
}

Error (401 Unauthorized):

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

Example

curl https://cc.teamday.ai/api/v1/agents/abc123def456 \
  -H "Authorization: Bearer $TEAMDAY_TOKEN"

Update Agent

Update an existing agent's editable properties. Private Agents can update their core instructions. Ready Agents and Teamday Agents accept configuration updates only; prompt and protected identity changes are rejected.

Request

PATCH /api/v1/agents/[id]

Headers:

Authorization: Bearer td_xxxxx...
Content-Type: application/json

Path Parameters:

  • id (string) - Agent ID (Firestore auto-generated)

Body (all fields optional):

{
  "name": "Updated Research Assistant",
  "role": "Advanced research and analysis",
  "systemPrompt": "You are an expert research assistant with deep knowledge of data analysis.",
  "visibility": "organization"
}

Updatable Fields:

  • name (string) - Agent display name
  • role (string) - Agent role description
  • systemPrompt (string) - System instructions for editable Private Agents only
  • visibility (string) - Access level: "private", "organization", "public", or "unlisted"

Note: Only include fields you want to update. Omitted fields remain unchanged. Protected fields on Ready Agents and Teamday Agents return an authorization error instead of mutating the product definition.

Response

Success (200 OK):

{
  "success": true,
  "message": "Agent updated successfully"
}

Error (404 Not Found):

{
  "error": true,
  "statusCode": 404,
  "statusMessage": "Not Found",
  "message": "Agent not found"
}

Error (400 Bad Request):

{
  "error": true,
  "statusCode": 400,
  "statusMessage": "Bad Request",
  "message": "Invalid visibility value. Must be: private, organization, public, or unlisted"
}

Example

curl -X PATCH https://cc.teamday.ai/api/v1/agents/abc123def456 \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Research Assistant",
    "visibility": "organization"
  }'

Delete Agent

Soft delete an agent. The agent is marked as deleted but not permanently removed from the database.

Request

DELETE /api/v1/agents/[id]

Headers:

Authorization: Bearer td_xxxxx...

Path Parameters:

  • id (string) - Agent ID (Firestore auto-generated)

Response

Success (200 OK):

{
  "success": true,
  "message": "Agent deleted successfully"
}

Error (404 Not Found):

{
  "error": true,
  "statusCode": 404,
  "statusMessage": "Not Found",
  "message": "Agent not found"
}

Error (401 Unauthorized):

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

Example

curl -X DELETE https://cc.teamday.ai/api/v1/agents/abc123def456 \
  -H "Authorization: Bearer $TEAMDAY_TOKEN"

Notes

Soft Delete Behavior:

  • Agent is marked as archived (archived: true)
  • Agent no longer appears in list results
  • Agent cannot be retrieved or updated
  • Execution history preserved
  • Cannot be undeleted via API (contact support to restore)

Alternative to deletion:

  • Consider updating visibility to "private" to hide from organization

Execute Agent

Execute an agent with a message and receive a response.

Request

POST /api/v1/agents/[id]/execute

Headers:

Authorization: Bearer td_xxxxx...
Content-Type: application/json

Path Parameters:

  • id (string) - Agent ID (Firestore auto-generated)

Body:

{
  "message": "Analyze this data and provide insights",
  "spaceId": "space_abc123",
  "sessionId": "session_abc123",
  "chatId": "chat_abc123",
  "stream": false
}

Fields:

  • message (string, required) - User message to send to agent
  • spaceId (string, optional) - Space/workspace to execute in
  • sessionId (string, optional) - Existing session to continue
  • chatId (string, optional) - Existing chat to continue
  • stream (boolean, optional) - Enable streaming response (default: false)

Response

Non-streaming response (200 OK):

{
  "success": true,
  "executionId": "exec-1234567890-abc",
  "chatId": "chat_abc123",
  "sessionId": "session_abc123",
  "result": "Based on my analysis of the data..."
}

Streaming response (stream: true):

When stream is true, the response is an SSE stream (content-type: text/event-stream). The stream starts with a meta event containing IDs, followed by message events with content, and ends with a result event:

event: meta
data: {"executionId":"exec-1234567890-abc","chatId":"chat_abc123","sessionId":"session_abc123"}

event: message
data: {"messageType":"stream_event","delta":{"type":"text_delta","text":"Based"}}

event: message
data: {"messageType":"stream_event","delta":{"type":"text_delta","text":" on my analysis..."}}

event: result
data: {"sessionId":"session_abc123","usage":{"input_tokens":856,"output_tokens":378}}

SSE event types:

  • meta — Initial metadata (executionId, chatId, sessionId). Sent first.
  • message — Content events. messageType: "stream_event" contains text deltas. messageType: "assistant" contains complete content blocks.
  • result — Final event with sessionId (for multi-turn) and token usage.
  • error — Error event with { message } payload.

Examples

Non-streaming:

curl -X POST https://cc.teamday.ai/api/v1/agents/abc123def456/execute \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Analyze this data and provide insights",
    "stream": false
  }'

Streaming:

curl -N -X POST https://cc.teamday.ai/api/v1/agents/abc123def456/execute \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "message": "Analyze this data and provide insights",
    "stream": true
  }'

Multi-turn (continue session):

curl -X POST https://cc.teamday.ai/api/v1/agents/abc123def456/execute \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Now break it down by region",
    "sessionId": "session_abc123",
    "chatId": "chat_abc123",
    "spaceId": "space_xyz",
    "stream": true
  }'

Visibility Levels

Agents support four visibility levels that control who can see and use them:

Private

Level: "private"

Access:

  • Visible only to the creator
  • Only creator can execute
  • Not visible in organization's agent list

Use cases:

  • Personal assistants
  • Experimental agents
  • Sensitive workflows

Organization

Level: "organization"

Access:

  • Visible to all organization members
  • All members can execute
  • Appears in organization's shared agents

Use cases:

  • Team collaboration
  • Shared knowledge bases
  • Company-wide tools

Public

Level: "public"

Access:

  • Visible to all authenticated users
  • Anyone can execute
  • Listed in public agent listings

Use cases:

  • Community-shared agents
  • Open-source tools
  • Public demos

Unlisted

Level: "unlisted"

Access:

  • Not shown in agent listings or search
  • Accessible only via direct link/ID
  • Only the owner can see it in their dashboard

Use cases:

  • Shared with specific people via link
  • Beta testing agents
  • Agents embedded in external tools

Best Practices

Agent Design

System Prompts:

  • Be specific about the agent's role and capabilities
  • Include examples of desired behavior
  • Set clear boundaries on what the agent should/shouldn't do
  • Keep prompts under 2000 characters for optimal performance

Example:

{
  "systemPrompt": "You are a code review assistant specializing in Python. Focus on:\n1. Code quality and readability\n2. Performance optimizations\n3. Security vulnerabilities\n4. Best practices\n\nProvide constructive feedback with specific examples."
}

Naming Conventions

Agent Names:

  • Use descriptive, action-oriented names
  • Include the agent's specialty or domain
  • Keep under 50 characters

Good examples:

  • "Python Code Reviewer"
  • "Customer Support Assistant"
  • "Data Analysis Agent"

Avoid:

  • Generic names like "Agent 1", "My Agent"
  • Very long names that truncate in UI

Security

Visibility:

  • Default visibility is "organization" for new agents
  • Use "private" for sensitive or experimental agents
  • Review Private Agent system prompts before sharing them across an organization

Sensitive Data:

  • Don't include API keys or credentials in system prompts
  • Use TeamDay's [secrets management instead
  • Agents inherit user permissions - scope tokens appropriately

Performance

Agent Updates:

  • Private Agent systemPrompt changes take effect on the next execution
  • Ready Agent and Teamday Agent behavior changes arrive through Teamday-managed product updates
  • Consider versioning by including version in agent name (e.g., "Research Assistant v2")

Rate Limiting:

  • While no formal limits exist, avoid creating 100+ agents
  • Reuse agents with different messages rather than creating duplicates
  • Delete unused agents to keep organization clean

Common Patterns

Multi-Purpose Agent

Create one agent that handles multiple related tasks:

curl -X POST https://cc.teamday.ai/api/v1/agents \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Engineering Assistant",
    "role": "Code review, documentation, and debugging",
    "systemPrompt": "You are an engineering assistant. Depending on the task:\n- Code review: Focus on quality, security, performance\n- Documentation: Write clear, concise docs with examples\n- Debugging: Analyze errors and suggest fixes\n\nAdapt your response to the user'\''s specific request.",
    "visibility": "organization"
  }'

Specialized Agent

Create focused agents for specific domains:

curl -X POST https://cc.teamday.ai/api/v1/agents \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "SQL Query Optimizer",
    "role": "SQL optimization and tuning",
    "systemPrompt": "You are an expert SQL optimizer. Analyze queries for:\n- Index usage\n- Join efficiency\n- Query plan optimization\n- Best practices for the target database (PostgreSQL, MySQL, etc.)\n\nProvide specific, actionable recommendations.",
    "visibility": "private"
  }'

Team Collaboration

Share agents across your organization:

# Create shared agent
curl -X POST https://cc.teamday.ai/api/v1/agents \
  -H "Authorization: Bearer $TEAMDAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Team Standup Helper",
    "role": "Daily standup organization",
    "systemPrompt": "Help teams organize daily standups. Format updates in a clear, concise way:\n- What was accomplished yesterday\n- Plans for today\n- Any blockers\n\nKeep responses brief and actionable.",
    "visibility": "organization"
  }'

Error Handling

Common Errors

400 Bad Request:

  • Missing required fields (name, systemPrompt)
  • Invalid visibility value
  • Malformed JSON

403 Forbidden:

  • Attempted to edit a protected Ready Agent or Teamday Agent prompt
  • Attempted to mutate a Teamday-managed identity, rubric, or tool policy

401 Unauthorized:

  • Missing Authorization header
  • Invalid or expired token
  • Token lacks required permissions

404 Not Found:

  • Agent ID doesn't exist
  • Agent was deleted
  • Wrong organization (agent belongs to different org)

500 Internal Server Error:

  • Database connectivity issues
  • Service temporarily unavailable
  • Contact support if persistent

Error Response Format

All errors follow this structure:

{
  "error": true,
  "statusCode": 400,
  "statusMessage": "Bad Request",
  "message": "Detailed error description"
}

Retry Strategy

Recommended approach:

async function createAgentWithRetry(agentData, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('https://cc.teamday.ai/api/v1/agents', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${process.env.TEAMDAY_TOKEN}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(agentData)
      })

      if (!response.ok) {
        const error = await response.json()

        // Don't retry client errors (4xx)
        if (response.status >= 400 && response.status < 500) {
          throw new Error(error.message)
        }

        // Retry server errors (5xx)
        if (i === maxRetries - 1) throw new Error(error.message)

        // Exponential backoff
        await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000))
        continue
      }

      return await response.json()

    } catch (err) {
      if (i === maxRetries - 1) throw err
    }
  }
}


Need Help?

Issues with agents?

  • Check error reference for troubleshooting
  • Verify token has correct permissions
  • Test with simple agent first

Questions?


Last Updated: February 24, 2026