Skip to main content
Pagination in the Everhour API is per-endpoint. Each endpoint that supports pagination defines its own page and limit parameters, defaults, and maximum values. Some endpoints return the full collection in a single response and accept no pagination parameters at all.

How it works

Paginated endpoints accept one or both of these query parameters:
ParameterTypeDescription
pageintegerPage number, 1-based. Default is 1.
limitintegerNumber of items per page. Defaults and maximums differ by endpoint.
Responses are bare JSON arrays. There are no response headers, no JSON envelope, and no total count field. To detect the last page, check whether the number of items returned is less than limit.

Endpoint reference

Endpointlimit rangelimit defaultpage rangepage defaultNotes
GET /projectsno max enforced1–100001
GET /projects/{id}/tasks1–2502501–1001
GET /projects/{id}/tasks/search1–10010limit only
GET /tasks/search1–100100limit only
GET /tasks/{id}/time1–50000500001
GET /projects/{id}/time1–50000500001
GET /team/time1–50000500001
GET /users/{id}/time1–50000500001Also accepts offset (0–1000000)
Some endpoints — including GET /clients and GET /invoices — return the full collection with no pagination support. Accounts with large collections should narrow requests using available filters rather than fetching everything at once.

Iterating through pages

Because the API returns no total count, the standard approach is:
  1. Fetch page 1 with your chosen limit.
  2. If the number of items returned equals limit, there may be more — fetch the next page.
  3. If the number of items returned is less than limit, you have reached the last page.
LIMIT=50
PAGE=1

while true; do
  RESPONSE=$(curl -s "https://api.everhour.com/projects?page=${PAGE}&limit=${LIMIT}" \
    -H "X-Api-Key: YOUR_API_KEY")

  COUNT=$(echo "$RESPONSE" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))")

  if [ "$COUNT" -lt "$LIMIT" ]; then
    break
  fi

  PAGE=$((PAGE + 1))
done