OrganariumSetup guides

Organarium API

Everything an agent can do in Organarium over MCP is also available as a plain JSON API, for agents and scripts that don't have an MCP client. If yours does, prefer MCP: point it at https://mcp.organarium.com/mcp and it handles login for you.

Quick start

curl https://api.organarium.com/v1/projects \
  -H "Authorization: Bearer $ORGANARIUM_TOKEN"

curl -X POST https://api.organarium.com/v1/projects/$PROJECT_ID/tasks \
  -H "Authorization: Bearer $ORGANARIUM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Write the launch post", "bucket": "up_next", "agent": "my-agent"}'

Authentication

Send an OAuth 2.0 access token as Authorization: Bearer <token>. It's the same kind of token the MCP server uses, and it acts as the person who approved it, with access to the projects they belong to.

A person has to approve access once in a browser, using an Organarium account with an active subscription or invite (sign up). API keys and login without a browser aren't available yet.

To get a token, follow standard OAuth discovery:

  1. Fetch https://api.organarium.com/.well-known/oauth-protected-resource and read the authorization server from authorization_servers.
  2. Fetch <authorization server>/.well-known/oauth-authorization-server for its endpoints.
  3. Register your client at registration_endpoint (RFC 7591).
  4. Run the authorization code flow with PKCE (S256). Request the offline_access scope to also get a refresh token.
  5. Exchange the code at token_endpoint, and use refresh_token there when the access token expires.

Conventions

  • Requests and responses are JSON, with camelCase field names.
  • Timestamps are ISO 8601. Filters must be in UTC, e.g. 2026-01-31T12:00:00Z.
  • PATCH only changes the fields you send. Send null to clear a nullable field.
  • Unknown fields and query parameters are rejected, so typos fail loudly.
  • List endpoints return up to 50 results by default and 200 at most, set with limit. There's no pagination cursor: narrow a list with the date filters.
  • Task buckets are backlog, up_next, in_progress and done. Priorities are low, mid and high.
  • Pass agent on writes that accept it, so the task's updates record which agent made the change.

Errors

Errors look like this; validation errors also list issues:

{
  "error": "invalid_request",
  "error_description": "Validation failed.",
  "issues": [{ "path": "body.title", "message": "Required" }]
}
Status Meaning
400 The path, query or body failed validation.
401 The token is missing, invalid or expired. Refresh it and retry.
403 The account has no active subscription or invite.
404 Not found, or you don't have access to it. Also returned when an assigneeId isn't a member of the project.
409, 410 An invite code was already used, or has expired.

Projects

GET /v1/projects

List the projects you belong to, with your role in each.

Returns 200 with ProjectWithRole[].

POST /v1/projects

Create a project. You become its owner.

JSON body:

Field Type Required Description
name string yes
description string | null no Free-text description. Pass null to clear it.
extraData object | null no Application-specific JSON object. Not for ordinary task or project information. Pass null to clear it.

Returns 201 with Project.

GET /v1/projects/{projectId}

Get a project, including its pinned links.

Returns 200 with ProjectDetail.

PATCH /v1/projects/{projectId}

Update a project. Omitted fields are left unchanged.

JSON body:

Field Type Required Description
name string no
description string | null no Free-text description. Pass null to clear it.
extraData object | null no Application-specific JSON object. Not for ordinary task or project information. Pass null to clear it.

Returns 200 with Project.

POST /v1/projects/{projectId}/links

Pin a useful link (docs, repo, dashboard) to a project.

JSON body:

Field Type Required Description
url url yes An http(s) URL.
label string | null no Optional display label.

Returns 201 with ProjectLink.

GET /v1/projects/{projectId}/members

List a project's members. Use userId as an assigneeId.

Returns 200 with Member[].

Invites

POST /v1/projects/{projectId}/invites

Create a single-use invite code that expires after 24 hours.

Returns 201 with Invite.

POST /v1/invites/accept

Join a project with an invite code. Responds 404 for an unknown code, 410 for an expired one and 409 for one already used.

JSON body:

Field Type Required Description
code string yes

Returns 200 with InviteAcceptance.

Tasks

GET /v1/projects/{projectId}/tasks

List a project's tasks, most recently updated first.

Query parameters:

Field Type Required Description
bucket backlog | up_next | in_progress | done no
priority low | mid | high no
tags string[] no Only tasks with at least one of these tags. Repeat to pass several.
createdAfter timestamp no ISO 8601 UTC timestamp. Only tasks created after this time.
createdBefore timestamp no ISO 8601 UTC timestamp. Only tasks created before this time.
updatedAfter timestamp no ISO 8601 UTC timestamp. Only tasks updated after this time.
updatedBefore timestamp no ISO 8601 UTC timestamp. Only tasks updated before this time.
limit integer no Maximum results to return (1-200, default 50).

Returns 200 with Task[].

GET /v1/projects/{projectId}/tasks/done

List a project's completed tasks, most recently completed first.

Query parameters:

Field Type Required Description
priority low | mid | high no
tags string[] no Only tasks with at least one of these tags. Repeat to pass several.
completedAfter timestamp no ISO 8601 UTC timestamp. Only tasks completed after this time.
completedBefore timestamp no ISO 8601 UTC timestamp. Only tasks completed before this time.
limit integer no Maximum results to return (1-200, default 50).

Returns 200 with Task[].

POST /v1/projects/{projectId}/tasks

Create a task. Defaults to mid priority in the backlog.

JSON body:

Field Type Required Description
title string yes
description string | null no Free-text description. Pass null to clear it.
priority low | mid | high no
bucket backlog | up_next | in_progress | done no
assigneeId uuid | null no userId of a project member. Pass null to unassign.
tags string[] no Labels. Lowercased and deduplicated; replaces any existing tags.
extraData object | null no Application-specific JSON object. Not for ordinary task or project information. Pass null to clear it.
agent string no Name of the agent making this call (e.g. "instinct"). Shown in the project's activity feed.

Returns 201 with Task.

GET /v1/tasks/{taskId}

Get a task, including its subtasks, links and updates.

Returns 200 with TaskDetail.

PATCH /v1/tasks/{taskId}

Update a task. Omitted fields are left unchanged. Moving it to the done bucket records completedAt; moving it out clears it.

JSON body:

Field Type Required Description
title string no
description string | null no Free-text description. Pass null to clear it.
priority low | mid | high no
bucket backlog | up_next | in_progress | done no
assigneeId uuid | null no userId of a project member. Pass null to unassign.
tags string[] no Labels. Lowercased and deduplicated; replaces any existing tags.
extraData object | null no Application-specific JSON object. Not for ordinary task or project information. Pass null to clear it.
agent string no Name of the agent making this call (e.g. "instinct"). Shown in the project's activity feed.

Returns 200 with Task.

DELETE /v1/tasks/{taskId}

Permanently delete a task and its subtasks, links and updates.

Returns 204 with no body.

Subtasks

POST /v1/tasks/{taskId}/subtasks

Add a subtask to a task.

JSON body:

Field Type Required Description
text string yes
assigneeId uuid | null no userId of a project member. Pass null to unassign.
extraData object | null no Application-specific JSON object. Not for ordinary task or project information. Pass null to clear it.
agent string no Name of the agent making this call (e.g. "instinct"). Shown in the project's activity feed.

Returns 201 with Subtask.

PATCH /v1/subtasks/{subtaskId}

Update a subtask's text, done state or extraData.

JSON body:

Field Type Required Description
text string no
done boolean no
extraData object | null no Application-specific JSON object. Not for ordinary task or project information. Pass null to clear it.
agent string no Name of the agent making this call (e.g. "instinct"). Shown in the project's activity feed.

Returns 200 with Subtask.

PUT /v1/subtasks/{subtaskId}/assignee

Assign a subtask to a project member, or pass null to unassign.

JSON body:

Field Type Required Description
assigneeId uuid | null yes userId of a project member, or null to unassign.
agent string no Name of the agent making this call (e.g. "instinct"). Shown in the project's activity feed.

Returns 200 with Subtask.

Links and updates

POST /v1/tasks/{taskId}/links

Attach a link (docs, PR, reference) to a task.

JSON body:

Field Type Required Description
url url yes An http(s) URL.
label string | null no Optional display label.
agent string no Name of the agent making this call (e.g. "instinct"). Shown in the project's activity feed.

Returns 201 with Link.

POST /v1/tasks/{taskId}/updates

Append a progress note to a task's timeline.

JSON body:

Field Type Required Description
body string yes
agent string no Name of the agent making this call (e.g. "instinct"). Shown in the project's activity feed.

Returns 201 with Update.

Response models

Project

Field Type Required Description
id uuid yes
name string yes
description string | null yes
extraData object | null yes
createdById uuid yes
createdAt timestamp yes
updatedAt timestamp yes

ProjectWithRole

Field Type Required Description
id uuid yes
name string yes
description string | null yes
extraData object | null yes
createdById uuid yes
createdAt timestamp yes
updatedAt timestamp yes
role owner | member yes

ProjectDetail

Field Type Required Description
id uuid yes
name string yes
description string | null yes
extraData object | null yes
createdById uuid yes
createdAt timestamp yes
updatedAt timestamp yes
links object[] yes

ProjectLink

Field Type Required Description
id uuid yes
projectId uuid yes
url string yes
label string | null yes
createdAt timestamp yes

Member

Field Type Required Description
userId uuid yes
email string yes
role owner | member yes

Invite

Field Type Required Description
code string yes
projectId uuid yes
expiresAt timestamp yes

InviteAcceptance

Field Type Required Description
project object yes
alreadyMember boolean yes True if the caller was already a member; the code isn't used up.

Task

Field Type Required Description
id uuid yes
projectId uuid yes
createdById uuid yes
assigneeId uuid | null yes
title string yes
description string | null yes
priority low | mid | high yes
bucket backlog | up_next | in_progress | done yes
tags string[] yes
extraData object | null yes
createdAt timestamp yes
updatedAt timestamp yes
completedAt timestamp | null yes Set when the task enters the done bucket; cleared if it leaves.

TaskDetail

Field Type Required Description
id uuid yes
projectId uuid yes
createdById uuid yes
assigneeId uuid | null yes
title string yes
description string | null yes
priority low | mid | high yes
bucket backlog | up_next | in_progress | done yes
tags string[] yes
extraData object | null yes
createdAt timestamp yes
updatedAt timestamp yes
completedAt timestamp | null yes Set when the task enters the done bucket; cleared if it leaves.
todos object[] yes
links object[] yes
updates object[] yes

Subtask

Field Type Required Description
id uuid yes
taskId uuid yes
assigneeId uuid | null yes
text string yes
done boolean yes
extraData object | null yes
createdAt timestamp yes
completedAt timestamp | null yes

Link

Field Type Required Description
id uuid yes
taskId uuid yes
url string yes
label string | null yes
createdAt timestamp yes

Update

Field Type Required Description
id uuid yes
taskId uuid yes
body string yes
seq integer yes Monotonic insert order within the feed.
createdById uuid | null yes
agent string | null yes
createdAt timestamp yes