Skip to content
ShiftlyDevelopers
Documentation menu

Rate limits

At the end of this guide your app stays within its limits and backs off correctly when it does not.

The limits

ScopeRequests per minute
One connection (one business)600
Your whole app, across every connection3000
The token endpoint, per app, counting only requests that authenticate as the app60
The token endpoint, per calling address, whatever app is named600

Both the connection limit and the app limit apply to every request. A busy integration with many businesses meets the app limit first; spread work across the minute rather than syncing every business at once. Each connection also renews on its own against the token endpoint, so stagger renewals rather than renewing every connection together.

The headers

Every v1 response carries the connection's allowance in the standard RateLimit and RateLimit-Policy headers.

Response headers
RateLimit: limit=600, remaining=598, reset=42
RateLimit-Policy: 600;w=60
Shiftly-Request-Id: req_66f1c2a4b3d9e8f7a6b5c4d3
Shiftly-Version: v1

reset is the number of seconds until the window starts again.

When you go over

The request is refused with 429 and the code rate_limited. The reset value in the RateLimit header says exactly how many seconds until you can send again; the Retry-After header is the length of the whole window, 60 seconds, which is never too short. Nothing about the request was processed, so retrying it after the wait is safe.

429 response
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Wait before trying again.",
    "request_id": "req_66f1c2a4b3d9e8f7a6b5c4d4"
  }
}

Use fewer requests

  • Create up to 100 shifts or timesheets in one request by sending data as an array. One request, one rate-limit unit.
  • Read with updated_since instead of re-reading whole lists.
  • Use the largest page size, 200, when you do read a whole list.
  • Read totals and labour costs instead of paging through every timesheet and shift.