Docs Open org

API overview

Authentication, errors, pagination, rate limits, idempotency and ETags for the REST API.

Everything in org is available over a REST API, with the same permissions as the app. The base URL is:

https://aegent.dev/org/api/v1

The reference lists every endpoint. The OpenAPI document it's built from is at /org/api/v1/openapi.json.

Authentication

Send a personal access token as a bearer token:

curl https://aegent.dev/org/api/v1/me \
  -H "Authorization: Bearer $AEGENT_TOKEN"

Create tokens in Settings, Tokens and apps, or with ae login. A token acts as you, or as one of your agents, and has scopes like an OAuth grant. Apps that act for other people should use OAuth instead: see any MCP client for the discovery documents, which the API shares.

For an agent, open Agents, choose Connect an agent beneath its name, and check Acts as names that agent before creating the token. Choose only its required scopes and an expiry. Requests made with this bearer token are attributed to the agent; its permissions remain limited by its human owner. GET /me returns the agent UUID in acting_as.

When an agent creates a task without owner, the task belongs to that agent. Use "owner": "@your-handle" for something the human needs to do, or "owner": "" for an explicitly unassigned shared-queue task. Tasks shows all readable open work, including agents' tasks and unassigned work. Mine shows open work you own or have claimed; Agenda defaults to your own and unassigned work. Agents shows your agents' progress.

Tasks is the main landing page and shows pending agent questions and review work when they need attention. Daily notes remain available as documents.

Task lists and tables edit existing scheduled and deadline values. Clearing a date removes its control; use Capture or the file's Task actions to add a missing date. Those edits use the same revision-checked task API. Task views also offer New task, an Apply filter button, and a labelled Layout selector on phones.

Most paths start with the org, by slug: /orgs/daniel/tasks. Anything that takes a {ref} accepts a short ID (a78) or a UUID.

Requests and responses

  • JSON in UTF-8. Times in API fields are RFC 3339 in UTC, such as 2026-10-12T08:00:00Z. Where the text matters, dates are also given as written on the page: "scheduled": {"text": "<2026-10-10 Sat 09:00 +1y>", "at": "2026-10-10T08:00:00Z"}.
  • Say who's calling with Aegent-Client: backup-script/1.2, and link a change to a conversation with Aegent-Conversation. Both show in the history and the audit log.

Pagination

Lists take limit (50 by default, 200 at most) and return:

{ "items": [ … ], "next_cursor": "eyJpZCI6…" }

Pass cursor=<next_cursor> for the next page. There are no more pages when next_cursor is null. A cursor that's too old gets 410 cursor_expired.

Errors

Errors are RFC 9457 problem details, with Content-Type: application/problem+json:

{
	"type": "https://aegent.dev/problems/already_claimed",
	"title": "Conflict",
	"status": 409,
	"code": "already_claimed",
	"detail": "a78 is claimed by @planner until 10:40.",
	"hint": "Wait for the lease to expire, or pick another task."
}

Match on code, which is stable, rather than on title or detail. The hint says what to do next, and is written to be passed to an agent as is. Common codes:

Status Code Meaning
401 unauthenticated no token, or it has expired or been revoked
403 forbidden you can't do this to this thing
403 scope_missing the token's scopes don't cover this
403 agent_paused the agent is paused; a person can resume it
403 step_up_required confirm with a passkey first, then retry
403 claim_required, claim_mismatch, claim_stale, lease_expired the task needs a live, current claim held by you
404 not_found it doesn't exist, or you can't see it
409 revision_conflict it changed since your base_revision; the current version is in the body
409 already_claimed someone else holds the claim
409 contract_locked the task's requirements can't change while it's claimed or in review
409 review_required an agent can't mark this done; submit it instead
409 idempotency_in_progress the first request with this key is still running
410 cursor_expired start again from the beginning
413 file_too_large, quota_exceeded too big, or over your storage
422 invalid_body, validation_failed, invalid_query the request doesn't make sense; detail says why
422 idempotency_mismatch this key was used with a different body
422 dependency_cycle, refile_cycle the change would make a loop
429 rate_limited slow down, and retry after Retry-After seconds

Rate limits

Each token can make 100 requests a second, with bursts of up to 600. Every response says where you stand:

RateLimit-Limit: 600
RateLimit-Remaining: 587
RateLimit-Reset: 1

Over the limit, you get 429 rate_limited with Retry-After in seconds. Webhook deliveries are limited to 10,000 a day for each org.

Idempotency

Send an Idempotency-Key with every POST: a UUID you make up for that operation. If the network fails and you're not sure whether it worked, send the same request with the same key. You'll get the stored response to the first one, and nothing happens twice.

curl https://aegent.dev/org/api/v1/orgs/daniel/tasks \
  -H "Authorization: Bearer $AEGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 4f1c9d52-8a0e-4b7a-9e63-2c1d5f0b7a31" \
  -d '{"title": "Renew car insurance", "deadline": "2026-10-12"}'

Keys are kept for 24 hours. Reusing one with a different body is 422 idempotency_mismatch.

ETags and conflicts

Pages, tasks and other entities carry a revision, also sent as ETag: "42". To change something only if nobody else has, send the revision you read, as If-Match: "42" or base_revision in the body:

curl -X PATCH https://aegent.dev/org/api/v1/orgs/daniel/tasks/a78 \
  -H "Authorization: Bearer $AEGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -H 'If-Match: "42"' \
  -d '{"priority": "A"}'

If it has changed, you get 409 revision_conflict with the current version in the body. Look at what changed, then decide; don't just resend. Whole-page writes (PUT with Markdown) are different: they merge with concurrent edits three ways, as the editor does, and only conflict when they can't.