REST API

Plain HTTP for the tools that speak it rather than MCP: Zapier, Make, n8n, a shell script, a scheduled job. 30 operations under https://api.roma.app/api/v1, each one of the MCP server's tools wearing an HTTP method, so what you can do here is exactly what an MCP client can do and the parameters are the same. The document that describes it is at /api/v1/openapi.json; import it into Zapier, Postman or an OpenAPI client.

How to call

  • Base URL https://api.roma.app/api/v1. JSON in, JSON out.
  • Authentication: a Roma API key or an OAuth access token as a bearer: Authorization: Bearer roma_…. Create a key in Roma under Settings, then Connections. Authentication has the details.
  • Ids are UUIDs; get them from GET /context, the list routes or GET /search. An id that belongs to someone else answers 404.
  • Query parameters are typed by the schema: limit=5, includeArchived=true, a list as taskStatus=todo,inProgress.
  • Errors are { "error": "one sentence", "code": "invalid | notFound | methodNotAllowed | unauthorized | rateLimited | toolError" } with 400, 401, 404, 405 or 429. A 429 carries Retry-After; a 405 carries Allow.
  • Rate limit: 60 requests a minute per key or token, counted before authentication, so a bad key is counted too.
  • Status codes: a route that makes something answers 201 (POST /tasks, POST /quick-add, POST /projects, POST /notes, POST /collections, POST /collections/{id}/items, POST /uploads); everything else 200. Deletes are soft: GET /trash and POST /trash/restore bring things back for about 30 days.

Quick add

The one call most automations need: a line of text becomes a task. The text is the task's title as it lands; the enrichment pass that runs a beat later tidies the wording and picks up the due date and the project the text names. POST /tasks runs the same pass, so a title is tidied either way; what you set yourself (dueAt, projectId, priority) stays as sent.

bash
curl -X POST "https://api.roma.app/api/v1/quick-add" \
  -H "Authorization: Bearer roma_…" -H "Content-Type: application/json" \
  -d '{"text": "Call the dentist tomorrow at 10"}'

At a glance

  • Context: GET /context
  • Tasks: GET /tasks, POST /tasks, POST /quick-add, GET /tasks/{id}, PATCH /tasks/{id}, DELETE /tasks/{id}
  • Projects: GET /projects, POST /projects, PATCH /projects/{id}
  • Notes and search: GET /search, GET /notes, POST /notes, GET /notes/{id}, PATCH /notes/{id}, DELETE /notes/{id}
  • Collections: GET /collections, POST /collections, PATCH /collections/{id}, DELETE /collections/{id}, GET /collections/{id}/items, POST /collections/{id}/items, PATCH /collections/{id}/items, DELETE /collections/{id}/items, POST /uploads
  • Trash: GET /trash, POST /trash/restore
  • Automations: GET /automations, GET /automations/{id}/runs, POST /automations/{id}/run

Context

GET /context

The workspace in one call · Read-only · MCP tool get_context

Use this at the start of a conversation that involves the user's Roma workspace, or when you need an overview of it. Returns, in one call: how Roma works; the user (name, timezone, today's date and local time); what they asked the AI to remember about them; their projects; overdue, due-today, in-progress and upcoming tasks; unsorted tasks; recently touched notes; their collections with columns; their automations with the last run; and the last few days of activity. Everything comes with ids for follow-up calls. It is an overview, not the full data: use search, list_tasks, get_note or get_collection_items for depth. Pass focusProjectId to scope the task sections to one project.

Query parameters

ParameterTypeRequiredDescription
focusProjectIdstringnoOptional project UUID. Scopes the task sections to that project; the rest stays workspace-wide.

Returns 200

  • about (string[])
  • user (object)
  • unavailable (string[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/context" \
  -H "Authorization: Bearer roma_…"

Tasks

GET /tasks

List and filter tasks · Read-only · MCP tool list_tasks

List, filter, and search the user's tasks — the way to find work to pick up. Returns tasks ordered by due date, then priority. Scope to the whole workspace, unsorted tasks only, or a single project. By default completed tasks are excluded.

Query parameters

ParameterTypeRequiredDescription
scopestringno"all" (default) for everything, "inbox" for unsorted items only (no project — the value keeps its legacy name), or a project UUID for that project.
querystringnoFree-text search across title and description.
taskStatus"todo" | "inProgress" | "completed"[]noFilter to these statuses. Omit to use the default active set (excludes completed).
dueAfterstringnoISO 8601 instant — only tasks due on/after this (inclusive).
dueBeforestringnoISO 8601 instant — only tasks due before this (exclusive). Today = dueAfter today 00:00 local, dueBefore tomorrow 00:00 local; overdue = dueBefore today 00:00 alone.
createdAfterstringnoISO 8601 instant — only tasks created on/after this.
createdBeforestringnoISO 8601 instant — only tasks created before this (exclusive).
updatedAfterstringnoISO 8601 instant — only tasks last changed on/after this.
updatedBeforestringnoISO 8601 instant — only tasks last changed before this (exclusive).
completedAfterstringnoISO 8601 instant — only tasks completed on/after this. Implies completed tasks unless taskStatus says otherwise.
completedBeforestringnoISO 8601 instant — only tasks completed before this (exclusive).
sort"due" | "created" | "updated" | "completed"noRow order. Default 'due' (due date, then priority); a timestamp sort returns newest first.
limitintegernoMax results (default 50). (1 to 200)

Returns 200

  • count (number)
  • tasks (object[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/tasks" \
  -H "Authorization: Bearer roma_…"

POST /tasks

Create a task · Adds data · MCP tool create_task

Create a task. Omit projectId to leave it unsorted (no project); set projectId to file it under a project. The task is enriched by AI in the background after creation, so enriched fields may appear on a subsequent read. Returns the created task.

Body (JSON)

ParameterTypeRequiredDescription
titlestringyesShort, clear task title.
descriptionstringnoOptional longer details.
projectIdstringnoProject UUID. Omit to leave it unsorted (no project).
priority"low" | "medium" | "high"no
taskStatus"todo" | "inProgress" | "completed"noDefaults to 'todo'.
dueAtstringnoISO 8601 due timestamp.

Returns 201

  • id (string)
  • title (string | null)
  • description (string | null)
  • taskStatus (string | null)
  • priority (string | null)
  • dueAt (string | null)
  • projectId (string | null)
  • createdAt (string | null)
  • updatedAt (string | null)
  • editedAt (string | null)
  • completedAt (string | null)

Example

bash
curl -X POST "https://api.roma.app/api/v1/tasks" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"title":"<title>"}'

POST /quick-add

Create a task from one line of text · Adds data · MCP tool create_task

Create a task. Omit projectId to leave it unsorted (no project); set projectId to file it under a project. The task is enriched by AI in the background after creation, so enriched fields may appear on a subsequent read. Returns the created task.

Body (JSON)

ParameterTypeRequiredDescription
textstringyesShort, clear task title.
descriptionstringnoOptional longer details.
projectIdstringnoProject UUID. Omit to leave it unsorted (no project).
priority"low" | "medium" | "high"no
taskStatus"todo" | "inProgress" | "completed"noDefaults to 'todo'.
dueAtstringnoISO 8601 due timestamp.

Returns 201

  • id (string)
  • title (string | null)
  • description (string | null)
  • taskStatus (string | null)
  • priority (string | null)
  • dueAt (string | null)
  • projectId (string | null)
  • createdAt (string | null)
  • updatedAt (string | null)
  • editedAt (string | null)
  • completedAt (string | null)

Example

bash
curl -X POST "https://api.roma.app/api/v1/quick-add" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"text":"<text>"}'

GET /tasks/{id}

One task with its subtasks and project · Read-only · MCP tool get_task_context

Fetch one task with everything needed to start working on it: the full task row (description, status, priority, due date) and the project it belongs to. The equivalent of opening an issue.

Path

  • id: The task's UUID.

Returns 200

  • task (object)
  • project (object | null)

Example

bash
curl -X GET "https://api.roma.app/api/v1/tasks/<id>" \
  -H "Authorization: Bearer roma_…"

PATCH /tasks/{id}

Update a task · Updates or removes existing data · MCP tool update_task

Update fields on an existing task — title, body, status, priority, due date, or which project it is in (projectId; null moves it out to unsorted). Use status transitions to report progress (e.g. todo → inProgress → completed). Only the fields you pass are changed. The body merge mode controls how description combines with the existing body — adding text appends/prepends; it never replaces unless you explicitly ask it to.

Path

  • id: The task's UUID.

Body (JSON)

ParameterTypeRequiredDescription
titlestringno
descriptionstring | nullnoBody text to merge in per mode. Omit to leave the body unchanged; null to clear it.
mode"prepend" | "append" | "replace" | "insertAfter"noHow description merges: 'append' (default, at the bottom), 'prepend' (at the top), 'insertAfter' (right after the line named in anchor), or 'replace' (swap the whole body — only when the user explicitly asked to rewrite it; never to add content; requires confirmReplace: true).
confirmReplacebooleannoRequired (true) for mode 'replace': confirms the user explicitly asked to swap the WHOLE body, deleting everything in it. Never pass it on the user's behalf without that explicit ask.
anchorstringnoFor mode 'insertAfter' only: a verbatim snippet of the existing line to insert after. Errors if not found.
taskStatus"todo" | "inProgress" | "completed"no
priority"low" | "medium" | "high" | nullno
dueAtstring | nullnoISO 8601 timestamp, or null to clear.
projectIdstring | nullnoMove the task: a project UUID (from list_projects or get_context) files it there; null moves it out to unsorted. Omit to leave it where it is.

Returns 200

  • id (string)
  • title (string | null)
  • description (string | null)
  • taskStatus (string | null)
  • priority (string | null)
  • dueAt (string | null)
  • projectId (string | null)
  • createdAt (string | null)
  • updatedAt (string | null)
  • editedAt (string | null)
  • completedAt (string | null)

Example

bash
curl -X PATCH "https://api.roma.app/api/v1/tasks/<id>" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{}'

DELETE /tasks/{id}

Delete a task into the trash · Updates or removes existing data · MCP tool delete_task

Delete a task (or subtask) by id. This is a SOFT delete — the task is recoverable for ~30 days before it is purged. Deleting a task also removes it from search. Deletes one task per call so each delete is confirmed individually.

Path

  • id: The task's UUID.

Returns 200

  • deleted (boolean)
  • id (string)
  • title (string | null)

Example

bash
curl -X DELETE "https://api.roma.app/api/v1/tasks/<id>" \
  -H "Authorization: Bearer roma_…"

Projects

GET /projects

List projects · Read-only · MCP tool list_projects

List all of the user's projects. Use this to resolve a project name to its UUID before creating or filing a task, or to understand the workspace structure.

Returns 200

  • count (number)
  • projects (object[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/projects" \
  -H "Authorization: Bearer roma_…"

POST /projects

Create a project · Adds data · MCP tool create_project

Create a project — a folder that groups the user's tasks and notes. Use it when the user wants a new project, or to give work a home that has none; check list_projects or get_context first so an existing project is not duplicated. Returns the project with its id, ready for create_task / update_task projectId.

Body (JSON)

ParameterTypeRequiredDescription
namestringyesProject name, in the user's own words.
emojistringnoOptional single emoji for the project.

Returns 201

  • id (string)
  • name (string | null)
  • emoji (string | null)

Example

bash
curl -X POST "https://api.roma.app/api/v1/projects" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"name":"<name>"}'

PATCH /projects/{id}

Rename a project or set its emoji · Updates or removes existing data · MCP tool update_project

Rename a project or change its emoji. Only the fields you pass change; emoji null removes it. Does not move or change the project's tasks.

Path

  • id: The project's UUID (from list_projects or get_context).

Body (JSON)

ParameterTypeRequiredDescription
namestringnoNew name.
emojistring | nullnoNew emoji, or null to remove it.

Returns 200

  • id (string)
  • name (string | null)
  • emoji (string | null)

Example

bash
curl -X PATCH "https://api.roma.app/api/v1/projects/<id>" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{}'

Search notes, tasks and list rows · Read-only · MCP tool search

Search the user's Roma workspace — their notes, tasks, typed lists and the rows inside them — by meaning or keyword (hybrid semantic + keyword retrieval). Use this when the user asks about their own information, plans or anything they may have saved, and before adding something that may already exist. Their wording often won't match their notes' wording; the semantic arm bridges that gap (and across languages). Returns the best-matching passage per item; get_note returns a note's full text. An empty result means nothing relevant is saved. Not for general web knowledge.

Query parameters

ParameterTypeRequiredDescription
qstringyesNatural-language query — what the user is trying to find, in their words.
limitintegernoMax results (default 10). (1 to 20)
afterstringnoOnly items CREATED on/after this ISO 8601 timestamp. Use when scoping by when it was saved ("last week", "in March").
beforestringnoOnly items CREATED before this ISO 8601 timestamp (exclusive). Pair with after to bound a window.

Returns 200

  • count (number)
  • results (object[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/search" \
  -H "Authorization: Bearer roma_…"

GET /notes

List notes · Read-only · MCP tool list_notes

List the user's notes, newest first. Scope to the whole workspace, unsorted notes only, or a single project. Returns a snippet of each body; use get_note for the full text. This is browse-by-container — use search to find by topic.

Query parameters

ParameterTypeRequiredDescription
scopestringno"all" (default) for everything, "inbox" for unsorted items only (no project — the value keeps its legacy name), or a project UUID for that project.
createdAfterstringnoISO 8601 instant — only notes created on/after this.
createdBeforestringnoISO 8601 instant — only notes created before this (exclusive).
updatedAfterstringnoISO 8601 instant — only notes last changed on/after this.
updatedBeforestringnoISO 8601 instant — only notes last changed before this (exclusive).
sort"created" | "updated"noRow order, newest first on that stamp. Default created.
limitintegernoMax results (default 50). (1 to 200)

Returns 200

  • count (number)
  • docs (object[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/notes" \
  -H "Authorization: Bearer roma_…"

POST /notes

Create a note · Adds data · MCP tool create_note

Capture a note for the user. Omit projectId to leave it unsorted (no project); set projectId to file it under a project. The body is stored as authored within the editor's supported Markdown subset (unsupported constructs degrade to plain text) — no AI cleanup or reclassification runs — and indexed for search. Returns the created note.

Body (JSON)

ParameterTypeRequiredDescription
contentstringyesThe note body, as Markdown (headings #, lists, task lists - [ ], bold, links — the editor's supported subset). Rendered to rich text; author real Markdown, not literal markers.
titlestringnoShort title. Omit to let the body speak for itself.
projectIdstringnoProject UUID. Omit to leave it unsorted (no project).

Returns 201

  • id (string)
  • title (string | null)
  • content (string)
  • projectId (string | null)
  • createdAt (string | null)

Example

bash
curl -X POST "https://api.roma.app/api/v1/notes" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"content":"<content>"}'

GET /notes/{id}

One note as Markdown · Read-only · MCP tool get_note

Read one note in full by its id — the companion to search: search returns the matched passage, this pulls the whole document when you need more than the snippet. Returns the note's title and full body as Markdown, and, for a note a meeting was recorded into, the attributed transcript once its recording is done.

Path

  • id: The note's UUID (from a search result).

Returns 200

  • id (string)
  • title (string)
  • content (string)
  • projectId (string | null)
  • createdAt (string | null)
  • transcript (string)
  • recording (object)

Example

bash
curl -X GET "https://api.roma.app/api/v1/notes/<id>" \
  -H "Authorization: Bearer roma_…"

PATCH /notes/{id}

Update a note · Updates or removes existing data · MCP tool update_note

Edit an existing note — its title, body, or which project it's in. Only the fields you pass change. The body merge mode controls how content combines with the existing body. Re-indexes for search automatically.

Path

  • id: The note's UUID.

Body (JSON)

ParameterTypeRequiredDescription
titlestringnoNew title. Omit to leave unchanged.
contentstringnoMarkdown body to merge in (headings, lists, bold, links). Omit for a title/project-only edit.
mode"prepend" | "append" | "replace" | "insertAfter"noHow content merges: 'append' (default, at the bottom), 'prepend' (at the top), 'replace' (swap the whole body — only when the user explicitly asked to rewrite it; never to add content; requires confirmReplace: true), or 'insertAfter' (place it right after the line named in anchor, matching that line's formatting).
confirmReplacebooleannoRequired (true) for mode 'replace': confirms the user explicitly asked to swap the WHOLE body, deleting everything in it. Never pass it on the user's behalf without that explicit ask.
anchorstringnoFor mode 'insertAfter' only: a verbatim snippet of the existing line to insert after. Errors if not found.
projectIdstringnoProject UUID to move the note into, or "inbox" to clear its project (unsorted — the value keeps its legacy name). Omit to leave it where it is.

Returns 200

  • id (string)
  • title (string | null)
  • content (string)
  • projectId (string | null)

Example

bash
curl -X PATCH "https://api.roma.app/api/v1/notes/<id>" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{}'

DELETE /notes/{id}

Delete a note into the trash · Updates or removes existing data · MCP tool delete_note

Delete a note by id. This is a SOFT delete — the note is recoverable for ~30 days before it is purged. Deleting a note also removes it from search. Deletes one note per call so each delete is confirmed individually.

Path

  • id: The note's UUID.

Returns 200

  • deleted (boolean)
  • id (string)
  • title (string | null)

Example

bash
curl -X DELETE "https://api.roma.app/api/v1/notes/<id>" \
  -H "Authorization: Bearer roma_…"

Collections

GET /collections

List collections with their columns · Read-only · MCP tool list_collections

List the user's collections (typed lists — a reading list, a watchlist, an expenses tracker). Returns each list's id, name, standing instructions, row count, and its COLUMNS with their stable ids — the ids add_collection_items and update_collection_items take. Use it before writing to a collection whose columns you have not read yet. Pass suppressOptions: true when you only need names/counts — select columns can carry hundreds of options (you don't need them to write: a select value may be sent as its label).

Query parameters

ParameterTypeRequiredDescription
suppressOptionsbooleannotrue replaces each select column's option list with an optionCount — much smaller payload.

Returns 200

  • count (number)
  • collections (object[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/collections" \
  -H "Authorization: Bearer roma_…"

POST /collections

Create a collection · Adds data · MCP tool create_collection

Create a typed list with its columns. Every column is equal — declare the ones the list actually needs, including a name column if rows have names (a list of measurements or dates may have none). Returns the created list WITH the stable column ids to use when adding rows.

Body (JSON)

ParameterTypeRequiredDescription
namestringyesThe list's name.
instructionsstringnoStanding rules for how entries should be handled, one rule per line. Max 500 characters — they ride in the prompt on every turn. (up to 500 characters)
propertiesobject[]noThe columns. Omit to start with one default text column the user can rename, retype or delete.

Returns 201

  • id (string)
  • name (string)
  • columns (object[])

Example

bash
curl -X POST "https://api.roma.app/api/v1/collections" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"name":"<name>"}'

PATCH /collections/{id}

Rename a collection or replace its instructions · Updates or removes existing data · MCP tool update_collection

Rename a collection or edit its standing instructions. instructions REPLACES the existing text — read the current value first (list_collections) and carry forward anything still true; null clears them. Column (schema) editing is not available over MCP — new select options mint automatically when adding or updating rows.

Path

  • id: The collection's UUID (from list_collections).

Body (JSON)

ParameterTypeRequiredDescription
namestringnoNew list name.
instructionsstring | nullnoREPLACES the standing rules (max 500 characters — they ride the prompt every turn); null clears them.

Returns 200

  • id (string)
  • name (string)
  • instructions (string | null)

Example

bash
curl -X PATCH "https://api.roma.app/api/v1/collections/<id>" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{}'

DELETE /collections/{id}

Delete a collection into the trash · Updates or removes existing data · MCP tool delete_collection

Delete a collection (typed list) by id. Deleting the list also deletes ALL its rows. SOFT delete — the list and its rows are recoverable for ~30 days via restore_deleted (type "collection"), which brings the rows deleted with it back too. When the list still holds rows the call refuses unless confirmDeleteItems is true, so the blast radius is always named before it happens.

Path

  • id: The collection's UUID (from list_collections).

Body (JSON)

ParameterTypeRequiredDescription
confirmDeleteItemsbooleannoRequired (true) when the list holds rows: confirms deleting the list AND every row in it. Confirm with the user first.

Returns 200

  • deleted (boolean)
  • id (string)
  • name (string)
  • itemsDeleted (number)

Example

bash
curl -X DELETE "https://api.roma.app/api/v1/collections/<id>" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{}'

GET /collections/{id}/items

Rows of a collection, paged · Read-only · MCP tool get_collection_items

Read the rows of one collection. Values are keyed by COLUMN ID (see list_collections); a select column's value is an option id, a multiSelect column's an array of option ids. Each row also lists its image attachments (so you can verify an import's images actually landed); pass includeImageUrls: true for short-lived viewable links. Paginated: the result carries totalCount and hasMore — keep calling with offset until hasMore is false to read a large list completely. Archived rows are left out unless includeArchived: true. Use to check what a list already holds before adding to it.

Path

  • id: The collection's UUID (from list_collections).

Query parameters

ParameterTypeRequiredDescription
includeArchivedbooleannotrue also returns archived rows (hidden from every list by default) so one can be brought back with update_collection_items; each row then says whether it is archived.
limitintegernoMax rows per page (default 50, newest first). (1 to 200)
offsetintegernoRows to skip — page through a big list with offset + limit until hasMore is false. (0 to 9007199254740991)
includeImageUrlsbooleannotrue additionally returns a short-lived signed url per attachment so the images can be viewed. Off by default.
createdAfterstringnoISO 8601 instant — only rows added on/after this.
createdBeforestringnoISO 8601 instant — only rows added before this (exclusive).
updatedAfterstringnoISO 8601 instant — only rows last changed on/after this.
updatedBeforestringnoISO 8601 instant — only rows last changed before this (exclusive).

Returns 200

  • count (number)
  • totalCount (number)
  • offset (number)
  • hasMore (boolean)
  • items (object[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/collections/<id>/items" \
  -H "Authorization: Bearer roma_…"

POST /collections/{id}/items

Add rows to a collection · Adds data · MCP tool add_collection_items

Add rows to a collection, many in one call (the import path). Values are keyed by column id or name; a select value may be its label or option id, a multiSelect value is an ARRAY of them, and unknown labels become new options. Keys that match no column come back in unknownKeys. Images that could not be stored come back in imageFailures with the reason; create_image_upload is the reliable path for images. Every row is inserted unless matchOn names columns to match on; a matched row keeps every filled cell and only gains what it lacks (empty cells, notes, images), so nothing is overwritten. To change a filled cell use update_collection_items (re-adding without matchOn creates a duplicate).

Path

  • id: The collection's UUID (from list_collections).

Body (JSON)

ParameterTypeRequiredDescription
matchOnstring[]noColumn ids or names that identify an existing row. When given, a row whose listed cells all match an existing row is not added again: the existing row gains the incoming row's empty-cell values, notes and images and keeps every cell it already had; matching is exact. Omit to always insert — no column is a natural key, so there is no default dedup.
itemsobject[]yesEvery row to add, in one call. (up to 200 items)

Returns 201

  • added (number)
  • itemIds (string[])
  • unknownKeys (string[])
  • imagesAttached (number)
  • imageFailures (object[])

Example

bash
curl -X POST "https://api.roma.app/api/v1/collections/<id>/items" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"items":[{}]}'

PATCH /collections/{id}/items

Correct rows of a collection · Updates or removes existing data · MCP tool update_collection_items

Update existing rows of ONE collection, many in one call; pass only what changes. values MERGE into the row (only the keys sent change; "" clears a cell), body replaces the notes, imageUrls add images (clearImages: true drops the old ones first), archived sets a row aside or brings it back. A key matching no column is an error; rows earlier in the batch stay updated and are named, so re-send only the rest. Read row ids and current values with get_collection_items first.

Path

  • id: The collection's UUID (from list_collections).

Body (JSON)

ParameterTypeRequiredDescription
itemsobject[]yesEvery row to update, in one call. (up to 200 items)

Returns 200

  • updated (number)
  • itemIds (string[])
  • imagesAttached (number)
  • imageFailures (object[])

Example

bash
curl -X PATCH "https://api.roma.app/api/v1/collections/<id>/items" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"itemId":"<itemId>"}]}'

DELETE /collections/{id}/items

Delete rows into the trash · Updates or removes existing data · MCP tool delete_collection_items

Delete rows from collections by id — up to 50 per call. SOFT delete: every row stays recoverable for ~30 days via restore_deleted (type "collectionItem") before it is purged, and drops out of search. Returns a per-id result — ids that don't resolve are reported and the rest still delete.

Path

  • id

Body (JSON)

ParameterTypeRequiredDescription
itemIdsstring[]yesThe rows' UUIDs (from get_collection_items). Up to 50 per call. (up to 50 items)

Returns 200

  • deleted (number)
  • results (object[])

Example

bash
curl -X DELETE "https://api.roma.app/api/v1/collections/<id>/items" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"itemIds":["<itemIds>"]}'

POST /uploads

Pre-signed slots for image bytes · Adds data · MCP tool create_image_upload

Get pre-signed URLs to upload images DIRECTLY into Roma storage — the reliable alternative to passing third-party links in imageUrls (those must stay fetchable until the server downloads them; short-lived signed links often expire first). For each slot: HTTP PUT the raw image bytes to uploadUrl with the matching Content-Type header (valid ~2 hours), then pass its bucketPath as an imageUrls entry in add_collection_items / update_collection_items. Keep images at or under 10 MB (maxBytes). Up to 10 slots per call.

Body (JSON)

ParameterTypeRequiredDescription
mimeType"image/png" | "image/jpeg" | "image/heic" | "image/webp"yesThe image type you will upload (all slots in one call share it).
countintegernoHow many upload slots (default 1). (1 to 10)

Returns 201

  • uploads (object[])
  • maxBytes (number)
  • validForSeconds (number)

Example

bash
curl -X POST "https://api.roma.app/api/v1/uploads" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"mimeType":"image/png"}'

Trash

GET /trash

What is in the trash · Read-only · MCP tool list_deleted

The trash: everything soft-deleted in the last ~30 days — tasks, notes, collections, and collection rows — newest first, each with the moment it is purged forever (purgesAt). Anything listed here can be brought back with restore_deleted. Filter by type, or omit type for all kinds.

Query parameters

ParameterTypeRequiredDescription
type"task" | "note" | "collection" | "collectionItem"noOnly this kind. Omit for all kinds.
limitintegernoMax entries per kind (default 25). (1 to 100)

Returns 200

  • count (number)
  • items (object[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/trash" \
  -H "Authorization: Bearer roma_…"

POST /trash/restore

Restore one item from the trash · Adds data · MCP tool restore_deleted

Bring back one soft-deleted item from the trash (see list_deleted) — a task, note, collection, or collection row. Restoring a collection also brings back the rows deleted with it; a row whose list is still deleted can't come back alone (restore the collection instead). A restored task whose project was deleted meanwhile lands in the inbox (movedToInbox: true). Restores one item per call. If the item is already live the call succeeds with alreadyLive: true.

Body (JSON)

ParameterTypeRequiredDescription
type"task" | "note" | "collection" | "collectionItem"yesThe entry's type, as list_deleted reported it.
idstringyesThe deleted item's UUID.

Returns 200

  • restored (boolean)
  • alreadyLive (boolean)
  • type (string)
  • id (string)
  • title (string | null)
  • restoredItems (number)
  • movedToInbox (boolean)

Example

bash
curl -X POST "https://api.roma.app/api/v1/trash/restore" \
  -H "Authorization: Bearer roma_…" \
  -H "Content-Type: application/json" \
  -d '{"type":"task","id":"<id>"}'

Automations

GET /automations

List automations · Read-only · MCP tool list_automations

List the user's automations — standing orders Roma runs on its own, on a schedule or on demand. Returns each one's id, name, what it does, status (active / paused / draft), when it runs, the next run, and how the last run ended. Use it when the user asks what runs on its own, when something runs next, or before reading or starting a run.

Returns 200

  • count (number)
  • automations (object[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/automations" \
  -H "Authorization: Bearer roma_…"

GET /automations/{id}/runs

Recent runs of an automation · Read-only · MCP tool get_automation_runs

Read one automation's recent runs, newest first: when each ran, how it ended, what it wrote (one line per action), the message it left for the user, and any error. Use it for "what did my morning brief find", "why did it fail", or to read the result of a run started with run_automation once it has finished.

Path

  • id: The automation's id (from list_automations or get_context).

Query parameters

ParameterTypeRequiredDescription
limitintegernoHow many runs, newest first (default 5, max 20). (1 to 20)

Returns 200

  • automation (object)
  • runs (object[])

Example

bash
curl -X GET "https://api.roma.app/api/v1/automations/<id>/runs" \
  -H "Authorization: Bearer roma_…"

POST /automations/{id}/run

Start an automation now · Updates or removes existing data · MCP tool run_automation

Start one of the user's automations now — the same as Run now on its page in Roma. Use it only when the user asks to run a specific automation. The run happens inside Roma with the user's connected apps and can take a minute; its result lands in the user's Roma chat, not in this conversation. Read the outcome afterwards with get_automation_runs. Refused for a draft, while the same automation is already running, or once the daily run limit is reached.

Path

  • id: The automation's id (from list_automations or get_context).

Returns 200

  • id (string)
  • name (string)
  • runId (string)
  • status (string)

Example

bash
curl -X POST "https://api.roma.app/api/v1/automations/<id>/run" \
  -H "Authorization: Bearer roma_…"