Restivity API

Quick Start

This page is the reference. The Redoc viewer below is generated from the same schemas the API validates with; the rate limits and the plan requirement in sections 5 and 6 are read from the code that enforces them. For the step-by-step connection flow see Connect an agent; for the OAuth details an agent reads on its own, /auth.md and /llms.txt.

1. Authentication — OAuth 2.0 + PKCE

Every /api/v1/* endpoint requires a Bearer token from the standard authorization_code grant with PKCE (RFC 7636). There is no API-key flow. Discover the OAuth server at /.well-known/oauth-authorization-server; register a client at POST /api/oauth/register; exchange the code at POST /api/oauth/token. Access tokens are signed JWTs (alg: ES256) verifiable with /api/oauth/jwks and expire in 1 hour. Refresh tokens rotate on each refresh; replaying a used refresh token revokes ALL of the client's tokens (RFC 6749 §10.4).

2. Scope model

Scopes are least-privilege. Each resource exposes :read and :write variants — tasks:read, tasks:write, projects:read, projects:write, pomodoro:read, pomodoro:write, profile:read, profile:write. The effective scope on a token is the intersection of (a) what the user consented to and (b) what the registered client requested. Calls outside the granted scope return 403 with WWW-Authenticate: Bearer error="insufficient_scope".

3. Pagination convention

List endpoints paginate via opaque cursor. Request: ?limit=<1-100, default 50>&cursor=<opaque>. Response wraps rows in { data: […], next_cursor: string | null }. next_cursor is null when the current page is the last one — the nullability IS the "has-more" signal, no separate boolean. Filter via documented query parameters; multiple filters AND together.

4. Error shape

Every error response is RFC 9457 problem-details (Content-Type: application/problem+json). The body has { type, title, status, detail, instance } — plus scope_required on 403 and retry_after on 429. type is the issuer origin + /errors/<slug>: 400 invalid_request, 401 invalid_token, 403 insufficient_scope, 404 not_found (also for soft-deleted), 422 unprocessable, 429 rate_limited (with Retry-After), 500 internal, 503 service_unavailable.

5. Rate limits

Per user, per UTC hour, three tiers by HTTP verb. The values below are the ones this deployment enforces.

TierRequests / hourCounts
read1000GET, HEAD
write200POST, PATCH, PUT
delete50DELETE

The token endpoint (POST /api/oauth/token) has its own gate: 60 requests per source IP per minute. Over budget it answers 429 with the OAuth error slow_down and Retry-After — wait, then retry the same request.

Every agent-authenticated response carries X-RateLimit-Tier as <tier>:<count>/<limit>. Over budget, the API answers 429 problem-details (type …/errors/rate_limited) with Retry-After (seconds to the top of the hour) and retry_after in the body. Back off until then; the counter resets every hour.

6. Plan requirement

Connecting an external agent — REST /api/v1/* and MCP /api/mcp — is a paid feature. A token is minted for any account; the entitlement is checked on every call.

PlanAgent API
FreeNot included
ProIncluded
TeamIncluded

A paid Team seat unlocks the agent API on a free personal plan too (the entitlement unions across memberships). Without it, an authenticated call gets 403 problem-details with type …/errors/upgrade_required and an upgrade_url pointing at /pricing. It is a 403, not a 401: do not restart the OAuth flow — show the upgrade link.

7. Beyond CRUD

Every resource exposes list / create / get / update / delete / restore. These operations do more; each has an MCP tool sibling with the same input and output.

  • POST /focus/finish — Finish working on a task: close the timer, comment, set the status — in one call. (tasks:write)
  • POST /focus/start — Start working on a task: in progress + one work session, in one call. (tasks:write)
  • GET /profile — Fetch the authenticated user profile. (profile:read)
  • PATCH /profile — Update writable profile fields. (profile:write)
  • DELETE /project-statuses/{id} — Delete a custom status (hard delete). (projects:write)
  • PATCH /project-statuses/{id} — Rename, recolor or recategorize a custom status. (projects:write)
  • GET /projects/{id}/statuses — List a project's custom statuses. (projects:read)
  • POST /projects/{id}/statuses — Add a custom status to a project. (projects:write)
  • POST /projects/{id}/statuses/reorder — Reorder a project's custom statuses. (projects:write)
  • POST /projects/agent-inbox — Get or create the workspace's Agent findings inbox. (projects:write)
  • PATCH /tasks/{id}/recurrence/rule — Edit a recurring master's rule (materialized model). (tasks:write)
  • POST /tasks/{id}/recurrence/skip — Skip the occurrence a reminder is on (reminder_only model). (tasks:write)
  • POST /tasks/batch-update — Apply one patch to up to 50 tasks atomically. (tasks:write)
  • POST /tasks/search — Full-text search tasks. (tasks:read)
  • GET /tasks/today — Today's focus list. (tasks:read)

Same handlers serve REST, MCP (/api/mcp), and the in-browser WebMCP read-only tools — see /.well-known/mcp/server-card.json for the MCP transport details.

Interactive OpenAPI 3.1 reference rendered with Redoc.