Getting started

Integrations

Language

Reference

Conventions & errors

The rules that hold across every endpoint, so you only have to learn them once.

Pagination

List endpoints take page (1-based) and pageSize (1–100, default 30) as query parameters and wrap results in one envelope:

{
  "items": [],
  "pageNumber": 2,
  "totalPages": 9,
  "totalCount": 174,
  "hasPreviousPage": true,
  "hasNextPage": true
}

Enums are camelCase strings

Enum values are always strings in camelCase — never integers: "pounds", "kilometers", "oneRepMax", "chest", "normal". Treat unknown enum values as forward-compatible: new ones may appear without a version bump.

Units

MeasureUnit
Weight (sets, records)Pounds
DistanceMeters
Set / record durationSeconds
Workout durationMinutes (durationMinutes)
Body measurementsThe unit system in the entry’s weightUnit (inches with pounds, centimeters with kilograms)

The user’s preferred display units are on /api/v1/user — convert at the edge of your app, not in storage.

Identifiers

  • User data (workouts, templates, splits, measurements) — stable GUIDs
  • Catalog data (exercises, equipment) — stable integer ids shared with the Gravl app
  • The user — an opaque string id, stable across all endpoints and tokens

Dates

All timestamps are UTC, ISO 8601 (2026-07-12T17:03:00Z). Date-range filters (startDate, endDate) are inclusive.

Rate limits

SurfaceLimitKeyed by
/api/v1/*100 requests / 15 minapp + user
/oauth/*10 requests / minIP address

Exceeding a limit returns 429 with a Retry-After header when available. Back off exponentially; don’t poll — most personal data changes at human speed.

Errors

StatusWhenBody
401Missing, malformed, expired or revoked token; suspended appEmpty (WWW-Authenticate challenge)
403Valid token, missing scopeProblem details with the missing scope named
404Resource doesn’t exist — or belongs to another userProblem details
429Rate limitedEmpty; Retry-After header
400Validation failure (bad page size, malformed parameters)Problem details with field errors
Problem details (RFC 7807)
{
  "status": 403,
  "title": "Missing scope",
  "detail": "This authorization is missing the 'measurements:read' scope."
}

Note the 404-for-foreign-data rule: requesting another user’s workout by id returns 404, not 403 — the API never confirms that data you can’t see exists.

Questions or ideas?

The developer platform is young and shaped by what people build. For OAuth app registration, questions, or feature requests, email developers@gravl.ai.