Skip to content

Conventions

Every /v1 operation pages, dates and versions its answers the same way. Learn these rules once and they hold across the API.

You need: the credential required by the operation. See authentication.

Response shape Continue with
page, pageSize, totalPages The next page number, until totalPages
Cover requests with nextCursor That value as cursor, with the same from and to
Availability impact with nextAfterRotationId That value as afterRotationId

Page numbers start at 1, and pageSize is at most 100. Each operation lists the fields it sorts on. An unknown sort field, or a page or size out of range, returns 400.

An empty page does not prove there is nothing more. Check the completion fields and the limitation codes below.

Some reads can answer only part of what you asked: a calendar could not be read, or a rotation’s future depends on somebody acting. These reads carry complete or completion, and a limitationCodes list that says why.

Read Where the codes are
Availability impact preview rotations[].limitationCodes
Swap candidates limitationCodes
One person’s shifts rotations[].limitationCodes

Each entry has a code, and a source when the reason concerns one availability source: manualAvailability or googleCalendar.

{ "code": "googleCalendarUnavailable", "source": "googleCalendar" }
code What it means
recurrenceExpansionIncomplete A recurring availability setting could not be expanded across the whole range.
manualAvailabilityUnavailable Manual availability could not be read.
googleCalendarUnavailable Google Calendar could not be read.
proposalRecurrenceIncomplete The proposed recurring availability could not be expanded across the whole range.
calendarFreshnessUnknown Google Calendar was read, but how recent its events are is not known.
externalRotation The rotation follows a PagerDuty or Jira Service Management schedule, so no availability impact is projected.
rotationDisabled The rotation is switched off, so no availability impact is projected.
projectionUnavailable The rotation could not be projected.
candidateHorizon A swap candidate ending after horizonUtc is left out.
randomFutureUnknown The rotation picks at random, so future duty is not known until it is drawn.
manualFutureContingent The rotation hands over by hand, so future duty depends on somebody rotating it.

A read that carries any code is not exhaustive, so do not treat what it leaves out as confirmed. Treat a code you do not recognise the same way.

Every timestamp carries its UTC offset. Duty and impact operations that ask for UTC accept offset zero only, so convert local dates and times before you send them.

An interval includes its start and excludes its end. To select a whole duty interval, send back the boundaries the API returned. Check each operation’s range limit: swap candidates and the availability impact preview accept at most 31 days.

When a read returns an ETag, keep it exactly as received, quotes included. Where the operation supports conditional reads, send it in If-None-Match. 304 means your copy is still current.

Not every operation supports conditional reads. An ETag can also be the version a later write needs, so its presence alone does not mean If-None-Match works there.

Writes to an existing rotation generally require If-Match. Send the current ETag from the resource, or from the action’s preview.

Result What to do
428 precondition_required Send the required header.
412 precondition_failed Read or preview again, review the current terms, and retry with the new ETag.
409 write_conflict Read again, then retry the same change.

An ETag with a W/ prefix is accepted when its revision matches. Keep the value as you received it.

If-Match: * lets a write through against any current revision. Avoid it when retrying an action that could advance duty twice.

Creating and deleting a rotation absence need neither If-Match nor Idempotency-Key. Creating the same absence again (same person, period and appliesTo) returns the existing one.

Previews change nothing, so they need no If-Match either.

Creating a rotation takes Idempotency-Key instead of If-Match. Use a new key for each rotation you mean to create, and the same key to retry it. A retry within 24 hours returns the rotation already created. Reusing the key after that returns 409.

Duty arrangement, cover and swap actions carry an operationId in the body. After an uncertain result, retry with the same body and the same identifier. Changed terms need a new identifier. See participant duty operations.

Keep authenticated responses private to the caller. Conditional reads count towards rate limits, 304 responses included.

Poll only as often as your integration needs, and wait for Retry-After when a response carries it.