# Reference overview

How the REST API reference is organised, generated from the code, what each operation page shows, and which guide answers which question.

The plnnrly REST API is a JSON API over your organisation's own data. Because the reference comes from the same code that answers your requests, it cannot drift from what the API does.

|                    |                                                                                          |
| ------------------ | ---------------------------------------------------------------------------------------- |
| **Base URL**       | `https://<your-url>/api/v2`                                                              |
| **Authentication** | `Authorization: Bearer <token>`, with a personal API token or a token from OAuth sign-in |
| **Format**         | JSON in both directions                                                                  |
| **Errors**         | RFC 9457 problem documents                                                               |
| **Contract**       | [OpenAPI 3.1](https://developers.plnnrly.com/openapi.json)                               |

`<your-url>` is the address you sign in to plnnrly on, such as `acme.plnnrly.com`, or your organisation's own domain. There is no shared API host. An organisation on its own domain answers only on that domain, and the API never redirects.

The reference has 228 operations across 104 paths.

## Start here

- [Getting started](https://developers.plnnrly.com/en/docs/api/v2/guides/getting-started/): From a token to your first read and your first write, one step at a time.

- [Authentication](https://developers.plnnrly.com/en/docs/api/v2/guides/authentication/): The bearer token, your organisation's address, and OAuth sign-in for apps that other people use.

- [API tokens](https://developers.plnnrly.com/en/docs/api/v2/guides/tokens/): Creating, narrowing, rolling and revoking personal tokens.

- [Scopes and permissions](https://developers.plnnrly.com/en/docs/api/v2/guides/scopes/): What a token's scope allows, what your role allows, and what each operation needs.

## What every operation page tells you

Each operation page opens with the three things a request needs:

- **Token scope**: the ability your token must carry, such as `api:write:times`. Where several are listed, it needs one of them. See [Scopes and permissions](https://developers.plnnrly.com/en/docs/api/v2/guides/scopes/).
- **Permission**: what your role must allow, the same permission plnnrly itself checks. Where it says `none`, the record's own rules decide.
- **Rate cost**: what the request costs against your rate budget, including what its parameters add.

The token check and the role check are separate, and the error says which one failed. A `403` [insufficient-token-scope](https://developers.plnnrly.com/en/docs/api/v2/guides/errors/#insufficient-token-scope) needs a different token. A `403` [insufficient-permission](https://developers.plnnrly.com/en/docs/api/v2/guides/errors/#insufficient-permission) needs a change to your role, and no token can work around it. A `403` [forbidden-by-policy](https://developers.plnnrly.com/en/docs/api/v2/guides/errors/#forbidden-by-policy) means the record itself refuses, for example a project you have no task on when you log time.

Each operation page also shows its MCP id, such as `work-items.actions.transition`: the operation id without its `api.v2.` prefix, the id the MCP server's `search_api` tool returns.

## Two requirements on your client

Read these before you generate a client from the spec.

1. **Accept unknown response fields.** New fields are added within v2. A client that validates responses against a closed schema breaks on a release that broke nothing.
2. **Accept unknown enum values.** The reference marks each extensible enum on its field, 200 of them today. Treat a value you do not recognise as unhandled: show it, or fall back to a default. Never treat it as an error.

Request bodies work the other way round. A key the operation does not accept is refused with `422` [validation-failed](https://developers.plnnrly.com/en/docs/api/v2/guides/errors/#validation-failed), and the error points at the key with code `prohibited`. A dropped field would look like success, so nothing is dropped silently. The same goes for query parameters: one the operation does not declare is a `400`.

## The shape of a response

```json
{
  "data": {},
  "meta": {},
  "links": {}
}
```

- A **collection** answers `data` (an array of rows), `meta.page` and `links` with `self`, `next` and `prev`.
- A **single record** answers `data`, plus `meta` only when there is something to report. That is `warnings`, for example after a write that ignored a field, or `actions` when you ask for them.
- A row of a resource that has its own address carries `links`: `self`, plus the collections that belong to the row, where it has any.
- A `204` has no body at all.

`meta.actions` lists the actions you may call on this record right now, such as `transition` or `restore`. Ask for it with `meta=actions` on a single-record read. 10 operations accept it.

## Guides

The guides cover what is true for every operation, so the operation pages do not repeat it. The [guides index](https://developers.plnnrly.com/en/docs/api/v2/guides/) lists them by group.

### Start

| Guide                                                                                    | Covers                                                                                           |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| [Getting started](https://developers.plnnrly.com/en/docs/api/v2/guides/getting-started/) | From a token to your first read and write.                                                       |
| [Authentication](https://developers.plnnrly.com/en/docs/api/v2/guides/authentication/)   | The bearer token, your organisation's address, and OAuth sign-in for apps that other people use. |
| [Sign in with OAuth](https://developers.plnnrly.com/en/docs/api/v2/guides/oauth-apps/)   | Building an app that acts for whoever signs in.                                                  |
| [API tokens](https://developers.plnnrly.com/en/docs/api/v2/guides/tokens/)               | Creating, narrowing, rolling and revoking personal tokens.                                       |
| [Scopes and permissions](https://developers.plnnrly.com/en/docs/api/v2/guides/scopes/)   | What a token's scope allows, what your role allows, and what each operation needs.               |

### Reading data

| Guide                                                                                                | Covers                                                                     |
| ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| [How the data fits together](https://developers.plnnrly.com/en/docs/api/v2/guides/data-model/)       | The resources and how they relate.                                         |
| [Data formats](https://developers.plnnrly.com/en/docs/api/v2/guides/data-formats/)                   | Dates, times, durations, amounts and other values on the wire.             |
| [Pagination](https://developers.plnnrly.com/en/docs/api/v2/guides/pagination/)                       | Cursor paging, and the collections that also accept page numbers.          |
| [Filtering and sorting](https://developers.plnnrly.com/en/docs/api/v2/guides/filtering-and-sorting/) | Filters and their operators, search with `q`, sorting and deleted records. |
| [Views and includes](https://developers.plnnrly.com/en/docs/api/v2/guides/views-and-includes/)       | The `summary` and `detail` views, `include`, and truncated lists.          |

### Writing data

| Guide                                                                                                  | Covers                                                               |
| ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
| [Concurrency and ETags](https://developers.plnnrly.com/en/docs/api/v2/guides/concurrency-and-etags/)   | `If-Match` against lost updates, `If-None-Match` for cheap re-reads. |
| [Idempotency](https://developers.plnnrly.com/en/docs/api/v2/guides/idempotency/)                       | Making a `POST` safe to retry.                                       |
| [Actions and state changes](https://developers.plnnrly.com/en/docs/api/v2/guides/actions/)             | Transitions, moves, sprint starts and restores.                      |
| [Deleting and restoring](https://developers.plnnrly.com/en/docs/api/v2/guides/deleting-and-restoring/) | What a delete removes, per resource, and how to get it back.         |
| [Files: upload and download](https://developers.plnnrly.com/en/docs/api/v2/guides/uploads/)            | Attaching files, and downloading them again.                         |

### In production

| Guide                                                                                                  | Covers                                                      |
| ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------- |
| [Rate limits](https://developers.plnnrly.com/en/docs/api/v2/guides/rate-limits/)                       | Your rate budget, what each request costs, and the headers. |
| [Errors and retries](https://developers.plnnrly.com/en/docs/api/v2/guides/errors/)                     | Every problem type, what to do about it, and when to retry. |
| [Limits at a glance](https://developers.plnnrly.com/en/docs/api/v2/guides/limits/)                     | Every numeric limit in one table.                           |
| [Keeping a copy in sync](https://developers.plnnrly.com/en/docs/api/v2/guides/syncing-data/)           | Polling for changes, since there are no webhooks.           |
| [Headers and versioning](https://developers.plnnrly.com/en/docs/api/v2/guides/headers-and-versioning/) | Every header once, and what v2 promises.                    |
| [What the API cannot do](https://developers.plnnrly.com/en/docs/api/v2/guides/known-limitations/)      | Known gaps, so you can plan around them.                    |
| [Generating a client](https://developers.plnnrly.com/en/docs/api/v2/guides/client-generation/)         | Generating a client from the spec without the usual traps.  |

### Recipes

| Recipe                                                                                                                   | Covers                                                              |
| ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------- |
| [Log time from a script](https://developers.plnnrly.com/en/docs/api/v2/guides/recipes/log-time/)                         | Booking hours, checking the week, fixing an entry, and timers.      |
| [Move work items through the workflow](https://developers.plnnrly.com/en/docs/api/v2/guides/recipes/work-item-workflow/) | Changing a work item's status, placing it on the board, commenting. |

## The reference

Start with [Discovery](https://developers.plnnrly.com/en/docs/api/v2/discovery/). `GET /` lists every resource your organisation exposes, with its collection URL, its item URL template, the permission prefix it is gated on and its operations. It leaves out resources that belong to a feature your organisation does not have. It does not check your token's scope or your role, so a listed resource can still refuse you. It needs a valid token and no permission, which makes it a good first call to check that a token works.

The sidebar groups the operations by resource, in these sections:

- [Start here](https://developers.plnnrly.com/en/docs/api/v2/discovery/) (4 operations)
- [Projects](https://developers.plnnrly.com/en/docs/api/v2/projects/list/): Projects, budgets and the customers they are billed to. (26 operations)
- [Work items](https://developers.plnnrly.com/en/docs/api/v2/work-items/list/): The backlog: work items, subtasks, links, comments and attachments. (24 operations)
- [Sprints](https://developers.plnnrly.com/en/docs/api/v2/sprints/list/): Sprint planning and the sprint state machine. (7 operations)
- [Time](https://developers.plnnrly.com/en/docs/api/v2/timers/list/): Worklogs and timers. (10 operations)
- [Drive](https://developers.plnnrly.com/en/docs/api/v2/drive-items/comments/list/): Drive items, documents, folders, notes and todos, and the comments and files on a drive item. (31 operations)
- [Customers](https://developers.plnnrly.com/en/docs/api/v2/customers/list/): Customers, contacts and categories. (21 operations)
- [Billing](https://developers.plnnrly.com/en/docs/api/v2/customer-subscriptions/list/): Sales invoices, subscriptions and invoice lines. (42 operations)
- [Leave](https://developers.plnnrly.com/en/docs/api/v2/absences/list/): Absences, holidays, free days, check-ins and furlough balances. (25 operations)
- [Planning](https://developers.plnnrly.com/en/docs/api/v2/events/list/): Calendar events. (6 operations)
- [Organization](https://developers.plnnrly.com/en/docs/api/v2/company-branches/list/): Users and company branches. (7 operations)
- [Configuration](https://developers.plnnrly.com/en/docs/api/v2/labels/list/): Workflows, statuses, work types and labels. (25 operations)

By method, there are 90 `GET`, 58 `POST`, 39 `PATCH` and 41 `DELETE` operations. No operation uses `PUT`: an update is a `PATCH` that carries only the keys you change. The one `PUT` you send is the raw file to an upload's `upload_url` (see [Files: upload and download](https://developers.plnnrly.com/en/docs/api/v2/guides/uploads/)).

### Schemas

[Schemas](https://developers.plnnrly.com/en/docs/api/v2/schemas/) has one page per resource with its full field set, so operation pages can link to it instead of repeating it. Two shared pages are worth a bookmark:

- [Pagination](https://developers.plnnrly.com/en/docs/api/v2/schemas/pagination/): the envelope of every collection, field by field.
- [Problems](https://developers.plnnrly.com/en/docs/api/v2/schemas/problems/): the members of every error document, [by status](https://developers.plnnrly.com/en/docs/api/v2/schemas/problems/#by-status).

## Try it

Each operation page has a console that sends a real request to your organisation. Enter your address and a token. The address is remembered in this browser, and the token only in this tab. The request goes straight from your browser to your organisation, so the docs site never receives your token.

> **Warning:**
> Writes from the console are real. They create, change and delete data like any other request, so try them on a test project you can clean up.

## The contract

[/openapi.json](https://developers.plnnrly.com/openapi.json) is the OpenAPI 3.1 document these pages are generated from, 5.2 MB of it. Point a client generator at it, and read [Generating a client](https://developers.plnnrly.com/en/docs/api/v2/guides/client-generation/) first.

To see what changed between releases, read the [changelog](https://developers.plnnrly.com/en/docs/changelog/). The document's `info.version` has not moved with every release, so do not use it to detect one.

### For machines

- [/openapi.json](https://developers.plnnrly.com/openapi.json): the OpenAPI 3.1 document, 5.2 MB.
- [/llms.txt](https://developers.plnnrly.com/llms.txt): an index of these docs for AI assistants, with every operation and its scope on one line.
- [/llms-full.txt](https://developers.plnnrly.com/llms-full.txt): the API guides, operations and schema pages as Markdown, in one file.
- `/md/api/v2/<slug>.md`: one operation as Markdown, such as [/md/api/v2/work-items/update.md](https://developers.plnnrly.com/md/api/v2/work-items/update.md).

## Not building an integration?

If you want an AI assistant to read and act on your plnnrly data, connect it to the [MCP server](https://developers.plnnrly.com/en/docs/mcp/) instead. It reaches the same operations you can, except file uploads, with no client to write. It deletes only when your organisation allows it and you confirm.
