---
title: "Create a list"
method: POST
path: "/api/v1/lists"
tags: ["Lists"]
---

# Create a list

`POST /api/v1/lists`

## Request

- Base URL: `https://api.roma.app`
- URL: `https://api.roma.app/api/v1/lists`
- Auth: HTTP bearer

Create a list. template "tasks" creates a list for to-dos: its items keep a status (todo / inProgress / completed) and a due date, like the Tasks list; `properties` given with it are added beside those two (an Agent person property, say). Otherwise `properties` shape it (a reading list with Author and Status, a CRM with Company and Email); omit both to start with no properties — every item has a title. Check list_lists or get_context first so an existing list is not duplicated. `section` places the list in a sidebar section (an existing section's id or name, or a new name, which makes the section); omitted, the list lands in the default section. Returns the list with its id and its properties' stable ids, ready for create_items.

## Request body

- object
  - `name` string, required: The list's name, in the user's own words.
  - `section` string, nullable: The sidebar section to place the list in: a section's id or name from list_lists, or a NEW name, which makes the section. Omit, or pass null, for the default section.
  - `icon` string, nullable: An emoji for the list.
  - `instructions` string, nullable: Standing rules for how entries should be handled, one rule per line. Max 500 characters — they ride in the prompt on every turn.
  - `template` 'tasks', nullable: "tasks" creates a list for to-dos that keeps a status and a due date. Omit for a list shaped by `properties`.
  - `properties` object[], nullable: The list's own properties (3 to 6 is typical; a title exists on every item, so no title property). With template "tasks" they stand beside the status and the due date.
    - `name` string, required: The property's name.
    - `type` 'text' | 'number' | 'date' | 'url' | 'select' | 'multiSelect' | 'person', required: The property's type. 'select' = ONE choice from a fixed set; 'multiSelect' = ANY NUMBER of choices (tags, genres); 'person' = people with access to the item, by id or name; text / number / date / url otherwise.
    - `options` string[], nullable: select/multiSelect properties only: the choice labels.
  - `titleLabel` string, nullable: What the title column is headed on this list — the word every item's name sits under: Name on a CRM, Book on a reading list. Omit for Title. Never a property: every item has a title.

## Response `201`

Created; the body is the new item.

- object
  - `id` string, required
  - `name` string, required
  - `icon` string, nullable
  - `instructions` string, nullable
  - `titleLabel` string, nullable: The title column's name on this list (Name on a CRM, Book on a reading list); null reads as Title. An item's name is its title under any label.
  - `layout` string
  - `role` 'tasks' | 'notes' | 'other': What the list's items are, read from its properties: "tasks" when it keeps the status and the due date, "notes" when it has no properties, "other" when its properties are its own.
  - `properties` object[]
    - `id` string, required
    - `name` string, required
    - `type` string, required
    - `kind` string: What the property IS: "status" / "dueDate" for the reserved pair a list binds to the task columns, else its type. A select named Status on any other list is a plain select.
    - `options` object[]
      - `id` string, required
      - `label` string, required
    - `optionCount` number
  - `statusPropertyId` string, nullable: "status" when the list keeps its items' status in the task columns.
  - `dueDatePropertyId` string, nullable: "dueDate" when the list keeps its items' due date in the task columns.
  - `itemCount` number: The list's open items: every live item but a repeating template, and never a completed one on a list that keeps its status in the task columns.
  - `isLifeAdmin` boolean
  - `section` object, nullable: The sidebar section the list stands in (id and name); the default section's id is "lists". null on a list somebody shared with the user that they have not filed into a section (it stands under Shared with me).
    - `id` string, required
    - `name` string, required
  - `isPinned` boolean: true when the user pinned the list to the top of the sidebar, beside Tasks.
  - `warning` string

## Other responses

- `400`: The request was understood and refused; the error says what to change.
- `401`: No usable bearer token.
- `404`: No such item for this account.
- `405`: The path exists but not with this method; Allow lists the ones that work.
- `429`: Over the rate limit; wait for Retry-After.

---

[API](https://skmtc.dev/roma/apis/roma-api.md) - [All operations](https://skmtc.dev/roma/apis/roma-api/llms.txt) - [OpenAPI document](https://skmtc.dev/roma/apis/roma-api/revisions/3dd91459b0fb?raw)
