Browse docs

Authentication

Overview

All API requests must include a valid bearer token in the Authorization header.

OpenAPI Specification

A machine readable OpenAPI 3.1 spec is available. You can browse it interactively or import it into tools like Postman or Insomnia.

Download openapi.yaml

The base URL for all API endpoints is https://there-there.app/api.

Creating API Tokens

Generate a personal access token from Settings > Account > API Tokens. Tokens can be scoped to one or more workspaces. If your token has access to multiple workspaces (or all workspaces), every request must include an X-Workspace-Id header identifying the workspace the request targets. See Finding your workspace ID below.

If your token is scoped to a single workspace, the header is optional and will be auto-resolved.

Each token has one of two permission levels. Read & write tokens can read data and make changes. Read-only tokens can only read data, and any request that changes something returns a 403.

Finding your workspace ID

The workspace ID is a number. You can find it in two places:

The workspace.id field in the response of GET /api/me holds the same value.

Personal vs Service Tokens

Personal access tokens are tied to your account. If you leave the workspace, any integration using your token stops working, and its activity stays attributed to you.

For integrations that should outlive any one person, create a service token instead, from Settings > Workspace > Service Tokens. A service token belongs to the workspace rather than a person, any admin can manage it, and replies or tickets it creates are attributed to the token's own name instead of a team member. It authenticates the same way as a personal token.

Making Authenticated Requests

Include your token in the Authorization header as a Bearer token.

curl https://there-there.app/api/me \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "X-Workspace-Id: 1" \
  -H "Accept: application/json"

A successful response returns your user profile and the current workspace:

{
    "data": {
        "user": {
            "id": 1,
            "name": "Jane Smith",
            "email": "jane@example.com",
            "avatar_url": "https://there-there.app/avatars/jane.jpg",
            "timezone": "America/New_York"
        },
        "workspace": {
            "id": 1,
            "ulid": "01hx9f3k2m...",
            "name": "Acme Support",
            "slug": "acme-support"
        }
    }
}

Response Format

All responses follow a consistent shape:

Single resource:

{
    "data": { "id": 1, "...": "..." }
}

Paginated collection:

{
    "data": [{ "id": 1 }, { "id": 2 }],
    "meta": {
        "current_page": 1,
        "last_page": 3,
        "per_page": 25,
        "total": 75
    },
    "links": {
        "first": "https://there-there.app/api/tickets?page=1",
        "last": "https://there-there.app/api/tickets?page=3",
        "prev": null,
        "next": "https://there-there.app/api/tickets?page=2"
    }
}

Filtering and Sorting

Filter parameters follow the pattern filter[field]=value. Sort with sort=field for ascending or sort=-field for descending. Use per_page to control page size (max 100) and page to paginate.

Rate Limits

The API enforces a rate limit of 60 requests per minute per authenticated user. When you exceed the limit, the API responds with a 429 Too Many Requests status code. The response includes a Retry-After header indicating how many seconds to wait before making another request.

Error Responses

The API uses standard HTTP status codes to indicate the outcome of a request.

Status Code Meaning
200 Success
201 Resource created
204 No content (used for deletes)
400 Bad request (missing workspace header)
401 Unauthenticated (missing or invalid token)
403 Forbidden (insufficient permissions)
404 Resource not found
422 Validation error
429 Rate limit exceeded

Validation errors return a JSON body with details about each failing field:

{
    "message": "The body field is required.",
    "errors": {
        "body": ["The body field is required."]
    }
}

Authentication failures return:

{
    "message": "Unauthenticated."
}

Request Headers

All requests should include the following headers:

Authorization: Bearer YOUR_API_TOKEN
X-Workspace-Id: YOUR_WORKSPACE_ID
Accept: application/json
Content-Type: application/json