---
title: "Create a board"
method: POST
path: "/api/boards"
tags: ["Boards"]
---

# Create a board

`POST /api/boards`

## Request

- Base URL: `https://core-api.getaptly.com`
- URL: `https://core-api.getaptly.com/api/boards`
- Auth: one of:
  - API key in header `x-token`
  - API key in header `Authorization`
- TypeScript: <https://skmtc.dev/getaptly/apis/aptly-api/docs/api/boards/post.ts> (a function with typed inputs; its response is checked against the schema)

Creates a new board. Requires the key's dedicated "Create Boards" access toggle to be
enabled, in addition to `insert` permission — unlike the API key's other access
toggles, this one defaults off and must be explicitly turned on in Setup → Developer.

A `stage` field is always added automatically (a board can't render a Kanban/pipeline
view without one) — `ticket` boards default to To Do / In Progress / Done, `deal`
boards to the standard Aptly deal pipeline. To use your own pipeline instead, pass
`stages`. You can add, reorder and recolor stages later with `PUT .../configuration/fields/stage`. `stage`, along with a handful of other
reserved keys (`name`, `dueAt`, `relatedContacts`, and every card-document system key
such as `_id`, `companyId`, `archived`), can't be used as a custom field's `uuid`.

Only a safe, self-contained subset of Aptly's field types may be used for custom
fields — relational types that reference other boards (e.g. `relatedAptlets`,
`mirror`) and system/computed types the backend manages itself (e.g. `stageselect`,
`calculation`) are rejected, since a freshly created board has nothing valid for them
to point at yet.

The key that creates a board keeps access to it. Even if the key is limited to specific
boards (so the new board is not on its list), it can read and write the board's cards, see
it in `GET /api/boards`, and - with the `update` permission but without the "Edit Boards"
toggle - add, change and remove its fields, change its theme and archive it. This applies
only to boards created through this endpoint by that key, and ends when the key is deleted.
It does not extend to other boards, to creating Automations (which has its own toggle), or to
Tasks, Files and mirror-field links to other boards, which still follow the key's board list.
Boards created before this change are not affected.

## Request body

- object
  - `name` string, required: Board display name.
  - `boardType` 'ticket' | 'deal': Determines the default `stage` pipeline. Defaults to `ticket`.
  - `stages` object[]: The board's stage pipeline, in order. Replaces the default pipeline for `boardType`. The first stage is where new cards start, so it cannot be closed or won. Labels must be unique. Stage ids are generated for you.
    - `label` string, required: Stage display name. Unique on the board.
    - `color` string: Hex color. Defaults to a palette color by position.
    - `closed` boolean: A closed stage ends a card's life, such as Done or Lost.
    - `won` boolean: A closed stage that counts as won. Deal boards only. Implies `closed`.
  - `fields` object[]: Optional custom fields to add, beyond the automatic `stage` field.
    - `name` string, required: Field display name.
    - `type` 'string' | 'text' | 'rich-text' | 'number' | 'money' | 'percent' | 'multiplier' | 'boolean' | 'date' | 'datetime-local' | 'email' | 'emails' | 'tel' | 'phones' | 'url' | 'address' | 'person' | 'persons' | 'user' | 'file' | 'files' | 'heroImage' | 'embedVideo' | 'stringList' | 'tags' | 'singleselect' | 'multiselect' | 'checkboxlist', required: The field types that can be created through the API (`POST /api/boards` and `POST /api/board/{boardId}/configuration/fields`). The value column is what a card stores and what the card API (`POST /api/board/{boardId}`) accepts under the field's `uuid`. | `type` | Label | Card value | |---|---|---| | `string` | Short Text | string | | `text` | Long Text | string | | `rich-text` | Rich Text | string (HTML) | | `number` | Number | number | | `money` | Currency | decimal number in requests (`1500.5`); returned as `{ amount, currency }` | | `percent` | Percent | number | | `multiplier` | Multiplier | number | | `boolean` | Checkbox | boolean | | `date` | Date | date | | `datetime-local` | Date and Time | date | | `email` | Email | string | | `emails` | Multiple Emails | string[] | | `tel` | Phone Number | string | | `phones` | Multiple Phone Numbers | array of phone objects | | `url` | URL | string | | `address` | Address | address object | | `person` | Link to a Single Contact | `{ _id }` (or `null` to clear); the contact must exist | | `persons` | Link to Multiple Contacts | array of `{ _id }` | | `user` | Team Member | user id | | `file` | Single Attachment | file id | | `files` | Multiple Attachments | file ids | | `heroImage` | Cover Photo | file id (the card's Kanban thumbnail) | | `embedVideo` | Embed Video | video URL string | | `stringList` | Text List | string[] | | `tags` | Tags | string[] | | `singleselect` | Dropdown | the chosen option's label - **requires `data`** | | `multiselect` | Multiple Select | array of option labels - **requires `data`** | | `checkboxlist` | Task List | array of `{ _id, checked, title }` (no `data`) | Relational and system types (`relatedAptlets`, `mirror`, `location`, `unit`, `stageselect`, `calculation`, and similar) can't be created through the API; boards built in the Aptly app can still contain them and they appear when reading fields.
    - `uuid` string: Optional explicit field key, used later as the key for this field's value in card create/update calls. Must match `^[a-zA-Z][a-zA-Z0-9_]{0,63}$`. Auto-generated when omitted.
    - `optional` boolean
    - `pinned` boolean: Pin this field to the card's Kanban view.
    - `startCard` boolean: Show this field on the form when a card is created. Off when omitted.
    - `defaultValue` string
    - `data` object[]: Required (non-empty) for `singleselect` and `multiselect` — the field's option list. Not used by the other types.
      - `label` string, required
      - `uuid` string: Auto-generated when omitted.

## Response `201`

Board created.

- object
  - `data` Board
    - `uuid` string: Board UUID — use this as `boardId` in board/card endpoints.
    - `name` string: Display name of the board.
    - `endpoints` object[]: Pre-built endpoint URLs for this board.
      - `method` string: HTTP method.
      - `url` string: Full endpoint URL.
      - `description` string: What the endpoint does.

## Other responses

- `400`: `VALIDATION_ERROR` - missing/invalid `name`, `boardType`, or a `fields` entry (per-field `meta.issues`, e.g. `fields.0.type`), or a reserved/duplicate field `uuid`.
- `401`: Invalid or missing API key.
- `403`: This API key does not have insert permission, or does not have the dedicated "Create Boards" access enabled for this key.

---

[API](https://skmtc.dev/getaptly/apis/aptly-api.md) - [All operations](https://skmtc.dev/getaptly/apis/aptly-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getaptly/apis/aptly-api/revisions/75c367e0b8e5?raw)
