---
name: trickroom
description: Call the Trickroom API to run AI agent jobs for the users of your product, follow them, read their results, connect users' Google, GitHub or Slack accounts, and decide what jobs ask to do. Use when writing code that talks to Trickroom.
---

# Trickroom API

Trickroom runs AI agents for the users of your product. Your backend registers
each user, submits **jobs** (one task each) for them, and reads what the jobs
did. Every call below is relative to the API base URL.

## Setup

- **Base URL:** `TRICKROOM_API_URL`, for example `https://www.trickroom.xyz/v1`.
- **Key:** `TRICKROOM_API_KEY`, an application key starting with `tak_`.
  Send it as `Authorization: Bearer $TRICKROOM_API_KEY`.
- **Server-side only.** Never put the key in browser or mobile code, in a
  repository, or in a job's task.
- Requests and responses are JSON. A failed call returns a non-2xx status and
  `{"error": {"code": "…", "message": "…"}}`; include the response's
  `x-request-id` header when reporting a problem.
- The key from the dashboard's getting-started guide can `users:read`,
  `users:write`, `jobs:read` and `jobs:write`. Other routes need a key
  with more capabilities; the error's `code` says when one is missing.

## Run a task for a user

1. **Register the user.** `POST /users` with `{"external_id": "<your user
   ID>"}`. The same `external_id` always returns the same user, so call it
   on every sign-in rather than storing Trickroom IDs first. The response's
   `id` (`usr_…`) is the Trickroom user.
2. **Submit a job.** `POST /jobs` with an `Idempotency-Key` header (reuse
   it when retrying, so a retry returns the first job):

   ```json
   {
     "user_id": "usr_…",
     "task": "Find this month's invoices and list their totals.",
     "execution_mode": "tools",
     "connection_ids": [],
     "web_access": false
   }
   ```

   - `"tools"`: no computer. The agent works with the model and the tools the
     job is given: accounts in `connection_ids`, and web search and page
     reading when `web_access` is true and the application allows the web.
   - `"computer"` (the default): the agent uses the user's own hosted
     computer. Assign it once with `POST /users/{id}/computer`. Computers
     are billed for their time and for each day they are kept.
3. **Wait for it.** `GET /jobs/{id}` every 2 seconds or slower until
   `status` is `completed`, `failed`, `cancelled` or `timed_out`.
   While it works, the status is `queued`, `provisioning`, `running` or
   `waiting_approval`.
4. **Read the result.** The job has `result_json` when it completes and
   `error` when it fails, `cost_nano.total` (nanodollars billed so far) and
   `viewer_url` to watch it in the dashboard.
   - Files it saved: `GET /jobs/{id}/artifacts`.
   - Its steps (model turns, tool calls, approvals): `GET
     /jobs/{id}/events?after=0`, then pass the response's `next_cursor` as
     `after` for the next page. Lists return `{"data": [...]}`.
   - Stop it: `POST /jobs/{id}/cancel`.

## Use the user's accounts

A job can act only in accounts the user connected and the job lists in
`connection_ids`.

- **Gmail, Google Drive, Google Calendar:** `POST
  /users/{id}/connect-links` with `{"provider": "gmail", "return_url":
  "https://your-app.example/settings"}` (or `"drive"`, `"calendar"`).
  Send the user to the returned `url`; Google sends them back to
  `return_url` with `status` and `connection_id`. Needs
  `connections:write`.
- **GitHub, Slack, Figma:** `GET /application` for the key's application
  `id`, then `POST /applications/{application_id}/plugins/{provider}/token`
  with `{"user_id": "usr_…", "token": "…"}`.
- **List a user's accounts:** `GET /users/{id}/connections`.

## Approvals

By default a job asks before it writes (sends, changes or pays for
something): it waits in `waiting_approval` until a person decides. List
them with `GET /approvals` and decide with `POST /approvals/{id}/approve`
or `POST /approvals/{id}/reject`. Deciding needs a separate key with
`approvals:decide`; let a person make the decision.

## Reference

Every route, with its fields and errors: https://www.trickroom.xyz/docs/api
