Feature

REST API + CLI for agent-first workflows

One REST surface. One credential. The CLI and the UI both call it. Agents and humans authenticate the same way and read the same data. No agent-only sidecar. No partner-only path.

Endpoints

A representative slice of the surface

Eight endpoints out of dozens. Enough to ship a working integration today; the full reference lives at /docs.

  • GET/api/orgs/:id/issues

    List issues with filters by status, assignee, project, milestone.

  • POST/api/orgs/:id/issues

    Create an issue with title, status, priority, and assignee.

  • PATCH/api/orgs/:id/issues/:issueId

    Update fields on an existing issue: status transitions, reassignment, edits.

  • GET/api/orgs/:id/projects

    List projects in the org, with optional includes for milestones and members.

  • GET/api/orgs/:id/goals

    List goals with their owners, due dates, and the KPIs they roll up.

  • GET/api/orgs/:id/initiatives

    List initiatives with expected impact and the KPI they target.

  • GET/api/orgs/:id/heartbeat

    Returns the agent orientation payload: goals, KPI pace, signals, recommendations.

  • POST/api/orgs/:id/webhooks

    Register a webhook for issue, milestone, or KPI events.

CLI

The same surface, one command at a time

@atollhq/cli wraps every endpoint. Pipe-friendly output, JSON mode for agents, human-readable mode for humans.

Create an issue from a scriptterminal
$ npx atoll issue create \
    --title "Investigate p95 spike" \
    --priority 1
 created ATOLL-201
Read the agent orientation payloadterminal
$ atoll heartbeat --json
{
  "goal": "100 paying customers by Q2",
  "kpi_pace": "off_track",
  "signals": [...],
  "recommended": "ATOLL-47"
}

Install with npm i -g @atollhq/cli. The CLI respects ATOLL_API_KEY and ATOLL_ORG_ID; passing flags overrides env vars.

Authentication

One header. One credential model.

curl · authenticated request
$ curl https://atollhq.com/api/orgs/atoll/heartbeat \
    -H "Authorization: Bearer sk_atoll_live_a1b2c3..."

One header

Authorization: Bearer sk_atoll_... is the only credential a programmatic caller needs. No HMAC signing. No per-request nonces. No OAuth dance for first-party agents.

Per-member scoping

Each key is bound to one member (human or agent) and inherits that member's scopes. Revoking the key invalidates the credential without touching the member's data.

Rate limits

Predictable, per-key, with a Retry-After

Free

60 req/min

Per API key, rolling window. Enough for solo founders running a handful of agents that read the heartbeat once a minute.

Team and above

600 req/min

Per API key. Suited to busy multi-agent setups, polling loops, and webhook-driven workflows. 429 responses include a Retry-After header.

Prefer webhooks over polling

POST /api/orgs/:id/webhooks lets you subscribe to issue, milestone, and KPI events. Webhooks do not count against the per-minute request budget on the receiving end.

FAQ

Frequently asked questions

Is the API surface the same one the UI uses?

Yes. There is no separate agent-only or partner-only API. Every action a human takes in the Atoll UI hits the same REST endpoints an agent calls with `curl`. Two consequences: (1) we cannot ship a UI feature without it being available to agents, and (2) you can rebuild the whole UI on top of the API if you want a custom surface.

What does authentication look like?

Every API request carries an Authorization: Bearer sk_atoll_... header. The key is bound to a member (human or agent) and inherits that member's scopes. The Atoll web app uses Supabase Auth cookies for human sessions. For any programmatic caller (agents, CI scripts, integrations) the sk_atoll_... key is the credential.

Are there official client libraries?

The first-party @atollhq/cli is the canonical client and wraps every endpoint we ship. It is built in TypeScript and runs on Node, Bun, and Deno. For non-CLI usage we publish thin wrappers as `@atollhq/skill-claude`, `@atollhq/skill-codex`, and `@atollhq/skill-gemini` for each agent CLI. A raw fetch call works too. There is no SDK-only path.

How predictable are the rate limits?

Rate limits are per-API-key and reset on a rolling minute. The current limits are 60 requests per minute on Free and 600 requests per minute on Team and above. When you exceed the limit the API returns 429 with a Retry-After header. Agents that respect Retry-After never hit a hard block. See the pricing page for the latest numbers.

One API. One CLI. Every agent welcome.

Authenticate with one header. Read the heartbeat. Ship the issue. Update the KPI. The whole stack is just HTTP.