Rate limits

Each key has its own limit of requests a minute, 60 unless you raise it. Every reply tells you how many you have left.

The per-key limit

  • Each key may make 60 requests a minute by default, counted over the last 60 seconds (a rolling window, not the clock minute).
  • Raise it per key in Setup > API keys, under Expiry, rate limit, sites and browser origins: 60 to 120 requests a minute. A TempClock super admin can set up to 600 for a busy feed.
  • Limits are per key, so one busy integration never slows another. Requests sent at the same moment are counted in the order they arrive, so a parallel burst gets exactly what is left of the limit through and the rest get 429: never more, and never fewer.
  • Refused requests (429) do not count, so a client that backs off recovers at once.

Headers

Every reply to a recognised key (successes and errors, including a revoked or expired key) carries:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57

A 429 adds Retry-After, in seconds. A reply to a request with no key or an unknown key has no X-RateLimit-* headers, and carries Retry-After only when it is a 429. A browser page (with its origin on the key) can read all of these headers.

Going over

Over the limit the API answers 429 with error_code: rate_limited and Retry-After: 60. Wait that long, or until X-RateLimit-Remaining would be above 0, then carry on. Nothing in the refused request was done.

Over the key's rate limit (this key allows 1 request a minute) 429

Key used: a key with a limit of 1 request a minute.

Request

curl -s "$TC_BASE/locations.php" \
  -H "Authorization: Bearer $TC_KEY"

Real reply (local test copy, fake demo data)

HTTP 429
Retry-After: 60

{
  "error": true,
  "message": "Rate limit exceeded. Maximum 1 requests per minute.",
  "status": 429,
  "error_code": "rate_limited"
}

Unknown keys

An address that sends 20 unknown keys in 5 minutes gets 429 rate_limited for any further key that does not work, with Retry-After set to when the window clears. This protects real keys from guessing. A key that works is never held back by it, so other callers on a shared address (an office network or an integration platform) cannot block your integration. If you hit it, check the key was copied in full: the API Logs page flags refused keys that start like one of yours.

Page sizes and periods

EndpointMost per request
Every listlimit 100 (default 50)
/payroll.phplimit 200 lines; 26 pay weeks per request
/pay-weeks.php26 pay weeks (default: the current week and the 7 before it)
/charges.php, /exceptions.php93 days
/timesheets.php with payroll_status2,000 matching shifts before paging (narrow with dates)
/availability.php who is freeA slot of up to 24 hours

Throughput for a clock feed

A third-party terminal or turnstile sends one request per clock. At the default 60 a minute, 450 workers arriving for one shift change take about 7.5 minutes to send. Two things keep that accurate and fast:

  1. Send the real time. Put the moment the worker badged in occurred_at. TempClock records that time (up to 15 minutes back), so a queue at the gate never changes anyone's hours. A clock more than 60 seconds back is flagged api_backdated for review on the Exceptions page.
  2. Raise the key's limit. At 120 a minute the same 450 clocks take under 4 minutes; at 600 (set by a TempClock super admin) under a minute.

Queue clocks at the terminal, send them in order with an Idempotency-Key each (so a retry after a network drop never clocks twice), and slow down when X-RateLimit-Remaining runs low. A clock queued for more than 15 minutes is refused (400 validation_failed, field occurred_at) and should be added by hand in TempClock.

Staying well inside the limit

  • Use webhooks instead of polling: TempClock tells you when a week is locked or a shift is approved.
  • Sync with updated_since rather than reading every record again.
  • Cache lookups (sites, departments, cost codes): they change rarely.
  • Ask for the most rows per page you can use (limit=100).
  • Use one key per system, so a busy system has its own limit.