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

Headers and versioning

Headers and versioning

The request headers you may send, the response headers you get back, and how the API changes within v2.

View as Markdown

This page lists the request headers the API reads, the response headers it sends, and what may change inside version 2. The reference repeats the header names on every operation page; their meaning is explained here, once.

Request headers

HeaderRequiredNotes
Authorization: Bearer <token>AlwaysSee Authentication.
AcceptNoLeave it out, or include application/json or */*. Anything else, application/* included, is 406.
Content-Type: application/jsonOn a request with a bodyAnything else is 415. A charset parameter is fine. There is no form encoding and no multipart.
If-MatchNo, never requiredProtects a write against overwriting a newer version. See Concurrency and ETags.
If-None-MatchNoMakes a read conditional: a match answers 304 with no body.
Idempotency-KeyOn a few POSTsMakes a POST safe to retry. At most 255 characters. See Idempotency.
X-Request-IdNoYour own correlation id. See below.

92 operations accept If-Match and 58 accept Idempotency-Key, of which 3 require it. Each operation page lists the headers it accepts.

Your own request id

Send X-Request-Id with 1 to 64 characters, using only the letters A to Z and a to z, the digits 0 to 9, _ and -. It is recorded with the request in our logs. Support can then find the request by your id as well as ours.

Nothing echoes it back. The X-Request-Id response header always carries our own id, and your id never appears in a response body. A value outside the pattern is dropped silently, and the request runs as normal.

Response headers

On every response

HeaderMeaning
Cache-Controlprivate, no-store, unless the operation declares a cache lifetime of its own. Responses are never publicly cacheable. A few configuration reads declare private, max-age=60, and discovery declares private, max-age=300.
VaryThe request headers the response depends on. Always includes Authorization, so a cache cannot serve one caller's rows to another.
RateLimitWhat is left in the tightest rate bucket. See Rate limits.
RateLimit-PolicyThat bucket's ceiling and window, as <limit>;w=<seconds>.
X-Plnnrly-Api-VersionThe major version that answered. Always 2 on /api/v2.
X-Request-IdOur id for this request, a ULID. Send it when you contact support.
X-Content-Type-Optionsnosniff, problem documents included.

Only on some responses

HeaderWhen
Content-TypeOn every response with a body: application/json, or application/problem+json on an error.
ETagOn a 200 or 201 with a record (strong) or a page of records (weak, W/"…"), on a 304, and the record's current tag on a 412. Never on a 204, and not on other errors. See Concurrency and ETags.
LocationOn a 201: the absolute URL of the new record. The two file registrations, on attachments and on Drive files, do not send it.
Idempotency-Replayed: trueOn a POST whose response was replayed from an earlier request with the same Idempotency-Key. Absent otherwise.

On errors

HeaderWhen
Retry-AfterOn a 429, a 503, and a 409 idempotency-key-in-flight. The seconds to wait.
AllowOn a 405: the methods the path accepts.
WWW-AuthenticateOn a 401: Bearer realm="plnnrly-api".
ETagOn a 412: the record's current tag.

Deprecated

HeaderSent untilUse instead
X-RateLimit-Limit2027-09-01RateLimit
X-RateLimit-Remaining2027-09-01RateLimit
X-RateLimit-Reset2027-09-01RateLimit

X-RateLimit-Reset is a Unix timestamp, while the reset in RateLimit counts seconds from now. The reference strikes these headers through on every operation page.

Versioning

The version is in the path, and only in the path: /api/v2. There is no version header to send and no version parameter. ?version= is an unknown query parameter, so it answers 400 invalid-query-parameter.

X-Plnnrly-Api-Version on a response only tells you which major version answered. It is useful in a log, not for choosing a version.

What can change within v2

Changes within v2 are additive: a new field, a new optional parameter, a new endpoint, or a new value in a response enum. A change that would break a client does not ship in v2. Two requirements follow for your client:

  1. Accept fields you do not know. Do not reject a response because it has an extra key. A field added next month must not break you.
  2. Accept enum values you do not know. Enum fields and parameters marked as extensible may gain new values. The reference says so on the field, and the document carries 200 of these marks. Treat an unknown value as unhandled, for example by falling back to a default, never as an error.

Requests are closed. An unknown body key is refused with 422 validation-failed, code prohibited, and an unknown query parameter with 400 invalid-query-parameter. Neither is ignored. A write that silently drops a field would be worse than one that is refused.

Generating a client shows how to set up a generated client for these rules.

Deprecation

When something is deprecated, the API tells you in the response:

DeprecatedWhat you see
An endpointA Deprecation header with the date it was deprecated (@ and a Unix timestamp), and a Sunset header with the date it stops. When it has a replacement, a Link header with rel="deprecation" points to its documentation.
A field in a responseA deprecated_field entry in meta.warnings, with sunset (the date it stops) and replacement (what to use instead).
Anything, in the referenceIt is struck through, with its sunset date beside it.

After its sunset date, a retired endpoint answers 410 endpoint-retired, with sunset and replaced_by.

The warning codes deprecated_parameter and deprecated_endpoint are declared in the contract but not sent yet. Today nothing is deprecated except the three X-RateLimit-* headers above.

Tracking changes

The whole contract is published as /openapi.json, in OpenAPI 3.1. The changelog records what changed in each release. The info.version field in the document does not change with each release yet, so do not use it to detect a new release. To see exactly what changed, compare two copies of the document.