Deze referentie is alleen in het Engels. Naar het Nederlandse REST API-overzicht

Diese Referenz gibt es nur auf Englisch. Zur deutschen REST-API-Übersicht

Cette référence existe uniquement en anglais. Aller à la présentation de l'API REST en français

Esta referencia solo está en inglés. Ir a la introducción de la API REST en español

Data formats

Data formats

How the API writes dates, times, durations, money, ids, enums and empty values, and the forms it accepts back.

View as Markdown

This page lists the formats the API uses on the wire. Send values back in the same forms: the API checks them strictly and does not guess.

A worklog row from GET /worklogs shows most of them at once:

JSON
{
  "id": 9021,
  "date": "2026-06-15",
  "minutes": 90,
  "description": "Sprint review with Acme",
  "work_item_id": 812,
  "is_overtime": false,
  "created_at": "2026-06-15T07:30:00Z",
  "updated_at": "2026-06-15T07:30:00Z"
  // 15 more fields: project_id, project, budget_id, budget, task_id, task, work_item, user_id, user, is_not_billable, exceeded_budget, reviewed_by, invoice_id, sales_invoice_row_id, links
}

Field names

Every key is snake_case.

  • A relation usually comes as a foreign key named {relation}_id, next to the relation itself: sprint_id and sprint. Three do not: a Drive item's drive_folder uses folder_id, a Drive folder's parent_folder uses parent_id, and a contact's role uses contact_role_id.
  • A counter is an integer named {relation}_count, such as comments_count.
  • Booleans are JSON true and false. Most are named is_…, but not all: auto_renew and active are booleans too. Go by the type in the schema, not by the name.

Calendar dates

A calendar date is YYYY-MM-DD, such as "2026-06-15". It has no time and no time zone. A worklog's date and a work item's due_date are calendar dates.

A time of day on its own, as in a user's working_hours, is HH:MM, such as "08:30", also without a zone.

Date-times

A date-time is UTC, to the second, with a Z: "2026-06-15T07:30:00Z". Responses always use this form.

Send date-times in exactly this form too, in request bodies and in filters. An offset such as +02:00 or fractions of a second are refused:

WhereWhat you get
Request body422 validation-failed, code date_format
Filter400 invalid-query-parameter, code invalid_format

Convert to UTC before you send. A meeting at 09:30 in Amsterdam on 15 June 2026 is 2026-06-15T07:30:00Z, because Amsterdam is two hours ahead of UTC in summer.

To show a date-time in a person's own zone, read the timezone field on their user record, such as Europe/Amsterdam. When it is null, the organisation's default zone applies.

Durations

A duration is a whole number of minutes, as an integer. One and a half hours is 90.

The field name does not always say so. minutes and logged_minutes do, but a work item's estimation and a budget's budget are minutes as well. The field description in the schema states the unit.

One exception: on a sales invoice row that bills budget time, quantity can hold hours, as a decimal string like any amount. The row's billable_minutes holds that time in minutes.

Money, percentages and coordinates

KindFormExample
MoneyA decimal string with two decimals"1250.00"
PercentageA whole number from 0 to 10021 means 21%, not 0.21
Coordinates in a responseA decimal string with up to seven decimals"52.3675734"
Coordinates in a request bodyA JSON number52.3675734

Money is a string so that no rounding happens on the way. Send amounts as strings with at most two decimals. There is no currency field.

A sales invoice row, for example:

JSON
{
  "quantity": "2.50",
  "unit_price": "95.00",
  "vat_rate": 21,
  "vat_amount": "49.88",
  "total_amount": "237.50",
  "billable_minutes": 150
  // 18 more fields: id, sales_invoice_id, sales_invoice, subscription_item_id, budget_id, exact_item_id, exact_vat_code, exact_cost_center, exact_gl_account, name, description, hourly_rate, is_aggregated_price, sort_order, created_at, updated_at, deleted_at, links
}

Identifiers

Every id is an integer, unique among records of the same resource in your organisation: project 12 and work item 12 are different records.

A work item also has an issue_key, a string such as "ACM-12". Every work item path accepts either form, so /work-items/ACM-12 and /work-items/812 are the same record. Request bodies and filters take the numeric id, such as work_item_id on a worklog. The one exception is after_work_item_id on the move action, which takes either. Store the numeric id as your key: an issue_key can be null.

Absent, null and empty

These three mean different things:

What you seeMeaning
The field is absentYou did not ask for it. Included relations, on-demand fields and detail-only fields appear only when you request them.
nullThere is no value, such as end_date on a project with no planned end. A few on-demand fields are also null when your access does not cover them; their description says so.
[]The list exists and is empty.

See Views and includes for how to request what is absent.

Enum values

Enum values are sent and returned exactly as the schema lists them. They are not always snake_case: a project's status can be on-hold, and on_hold is refused.

Most enums can gain values in a later release. The OpenAPI document marks each of them with x-extensible-enum: true, in 200 places. Treat a value you do not recognise as "unknown, show it as is", never as an error.

A value that is not in the list is 422 with code in in a request body, and 400 with code invalid_format in a filter.

Rich text

FieldFormat
Work item description, comment body, note content, and similar fieldsHTML from the plnnrly editor, sanitised before it is returned
Drive document contentGitHub-Flavored Markdown
Drive document content_htmlThe same document as sanitised HTML, on request

Markdown cannot hold text colours, highlights, alignment or @mentions, so writing a document back as Markdown drops them. Read content_html first when a document may contain them. The drive document operation explains the details.

Projects and work items carry a web_url: an absolute URL that opens the record in plnnrly, on your organisation's own address. It is stable, so you can store it and show it as a link. It is read-only.

Language

Data comes back exactly as people entered it. Nothing is translated.

Problem documents and warnings are always in English, whatever language a user has chosen in plnnrly. Their type, code and enum values are identifiers: switch on those, not on the English text.