API Usage

Integrate any AI agent with TeeckIn using the REST API.

Overview

This page covers Client Credentials authentication for AI tools that don't support browser-based OAuth (like Cursor, Copilot, Windsurf, or custom integrations).

Using Claude Code?

Claude Code supports browser-based OAuth with PKCE - you don't need API keys or secrets. See the Claude Code Setup guide instead.

Looking for the versioned API & Swagger docs?

This page covers agent authentication and the convenience endpoints. For the stable, versioned /api/v1 surface and the interactive Swagger reference, see .

When to Use Client Credentials

Use Client Credentials (API keys) when your AI tool:

  • -Does not support OAuth 2.0 with PKCE (browser-based authentication)
  • -Needs to authenticate non-interactively (CI/CD, scripts, hooks)
  • -Is a custom integration you're building yourself

Authentication

Client Credentials authentication requires a Client ID and from your agent settings in TeeckIn. These are exchanged for a short-lived access token.

1. Get Access Token

bash
curl -X POST https://teeckin.com/api/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=teeckin_agent_..." \
  -d "client_secret=tcs_..."

Returns an access token (valid for 1 hour):

json
{
  "access_token": "tat_...",
  "token_type": "Bearer",
  "expires_in": 3600
}

2. Use Access Token

bash
curl https://teeckin.com/api/timer/active \
  -H "Authorization: Bearer tat_..."

Token Refresh

Access tokens expire after 1 hour. Request a new token using the same client credentials. There's no separate refresh token flow.

Simple Agent Endpoints

These simplified endpoints are designed for shell hooks and scripts. They accept topic names (fuzzy matched) in addition to IDs, making them ideal for Claude Code SessionEnd hooks.

GET /api/agent/topics

List available topics. Returns a flat list with category names.

Response:

{
  "topics": [
    { "id": "top-456", "name": "Project Alpha", "category": "Client Work" },
    { "id": "top-789", "name": "Research", "category": "Internal" }
  ]
}
GET /api/agent/timer

Check timer status.

Response:

{
  "running": true,
  "topic": { "id": "top-456", "name": "Project Alpha", "category": "Client Work" },
  "elapsedMinutes": 45,
  "startedAt": "2026-03-30T10:00:00Z"
}
POST /api/agent/timer/start

Start a timer. Accepts topic name (fuzzy matched) or ID.

Request Body:

{ "topic": "Project Alpha" }

Response:

{
  "started": true,
  "topic": { "id": "top-456", "name": "Project Alpha", "category": "Client Work" }
}
POST /api/agent/timer/stop

Stop the active timer. Perfect for SessionEnd hooks.

Response:

{
  "stopped": true,
  "duration": 45,
  "clockedTimeId": "ct-789"
}
POST /api/agent/time

Log a completed time entry without using the timer.

Request Body:

{
  "topic": "Project Alpha",
  "duration_minutes": 30,
  "notes": "Completed code review"
}

Response:

{
  "logged": true,
  "id": "ct-abc",
  "topic": { "id": "top-456", "name": "Project Alpha", "category": "Client Work" },
  "duration": 30
}
GET /api/agent/tags

List available tags for categorizing time entries.

Response:

{
  "tags": [
    { "id": "tag-123", "name": "bug-fix" },
    { "id": "tag-456", "name": "feature" },
    { "id": "tag-789", "name": "refactoring" }
  ]
}
PATCH /api/agent/timer

Update the active timer with notes describing the work.

Request Body:

{ "notes": "Implementing user authentication module" }

Response:

{
  "updated": true,
  "clockedTimeId": "ct-789"
}
POST /api/agent/timer/tags

Add tags to the active timer. Tags are created if they don't exist.

Request Body:

{ "tags": ["refactoring", "performance"] }

Response:

{
  "added": true,
  "clockedTimeId": "ct-789",
  "tags": ["refactoring", "performance"]
}

Full API Endpoints

These are the full API endpoints with more options and detailed responses. Use these when you need more control over the request.

GET /api/topics/for-agent

List available topics with category groupings and hints for recent usage.

Response:

{
  "categories": [
    {
      "id": "cat-123",
      "name": "Client Work",
      "topics": [
        { "id": "top-456", "name": "Project Alpha", "recentlyUsed": true },
        { "id": "top-789", "name": "Research", "recentlyUsed": false }
      ]
    }
  ],
  "recentTopicIds": ["top-456"],
  "defaultTopicId": "top-456",
  "organizationGuidance": "Use Project Alpha for client deliverables..."
}
POST /api/timer/start

Start a timer on a specific topic.

Request Body:

{ "topicId": "top-456" }

Response:

{
  "clockedTime": {
    "id": "ct-789",
    "topicId": "top-456",
    "startTime": "2026-03-30T10:00:00Z"
  }
}
POST /api/timer/stop

Stop the active timer. Optionally add notes.

Request Body:

{ "notes": "Completed competitor analysis" }

Response:

{
  "clockedTime": {
    "id": "ct-789",
    "startTime": "2026-03-30T10:00:00Z",
    "endTime": "2026-03-30T10:45:00Z"
  }
}
GET /api/timer/active

Check if there's a running timer.

Response:

{
  "active": true,
  "clockedTime": {
    "id": "ct-789",
    "topicId": "top-456",
    "startTime": "2026-03-30T10:00:00Z"
  }
}
POST /api/clocked-times

Create a manual time entry (for retroactive logging).

Request Body:

{
  "topicId": "top-456",
  "startTime": "2026-03-30T09:00:00Z",
  "endTime": "2026-03-30T10:30:00Z",
  "type": "manual",
  "notes": "Drafted quarterly report"
}

Response:

{
  "id": "ct-abc",
  "topicId": "top-456",
  "startTime": "2026-03-30T09:00:00Z",
  "endTime": "2026-03-30T10:30:00Z"
}

Rate Limits

Agent API calls have rate limits to prevent abuse:

OperationLimit
Read (GET)120 per minute
Write (POST/PATCH)30 per minute
Timer operations10 per minute

Rate Limit Headers

Check the X-RateLimit-Remaining header in responses to monitor your usage.

Error Responses

Common error codes you may encounter:

401
Invalid or expired access token

Request a new token using your client credentials

403
Agent deactivated or secret revoked

Check agent status in Settings > Agents

404
Topic not found

Use /api/topics/for-agent to get valid IDs

429
Rate limit exceeded

Wait and retry after the limit resets

Best Practices

  • 1.Cache the topic list and refresh only when needed
  • 2.Always stop timers when work completes
  • 3.Include meaningful notes describing what was done
  • 4.Handle rate limits gracefully with exponential backoff
  • 5.Store client secrets securely and keep config files out of git
  • 6.Rotate secrets periodically via Settings > Agents > Secrets tab