Skip to content

Pagination & filtering

GET /releases is the only paginated endpoint. GET /projects returns a single project, and GET /project-languages always returns the complete set, however many languages a project has.

Parameters

ParameterTypeDefaultNotes
pageinteger11-based.
page_sizeinteger20Values above 100 are silently clamped to 100, not rejected.
searchstringCase-insensitive substring match on release name and tag.
sortstringcreated_atOne of name, tag, status, published_at, created_at.
orderstringdescasc or desc.

An unrecognised sort or order value falls back to the default rather than erroring, so a typo produces sensibly-ordered results rather than a failure — check your sorting if the order surprises you.

Terminal window
curl -s "$LOCALEO_API/releases?search=v1.4&sort=published_at&order=desc&page_size=50" \
-H "Authorization: Bearer $LOCALEO_TOKEN"

The response envelope

{
"items": [
{ "id": "7bWq0R", "name": "Spring campaign copy", "tag": "v1.4.0", "status": "published", "published_at": "2026-03-02T14:05:00Z", "created_at": "2026-03-01T11:20:00Z" }
]
}

items is the whole envelope. There is no total count, page count, or next-page link.

Paging through every release

In practice:

  • Use page_size=100. Fewer, larger pages make a whole page of drafts far less likely, and cost less quota.
  • Keep paging until you get an empty page, then stop. This is correct unless a project has 100 consecutive drafts sorted between published releases, which is rare in practice.
  • Prefer not to page at all. Most integrations want the newest release, not the full history — and for the newest release there is a better route that needs no API call whatsoever. See always fetching the latest release.
async function listAllReleases() {
const all = []
for (let page = 1; ; page++) {
const res = await fetch(`${API}/releases?page=${page}&page_size=100`, { headers })
if (!res.ok) throw new Error(`releases page ${page}: ${res.status}`)
const { items } = await res.json()
if (items.length === 0) break
all.push(...items)
}
return all
}

Sorting caveats

sort=status is accepted but not useful here: every release the public API returns has status: "published", so it sorts a constant. It exists because the parameter set is shared with the dashboard’s own release list, which does show drafts.

Sorting by published_at and by created_at can differ. A release created in March but published in April sorts differently under each, and created_at — the default — is about when the release was cut, not when it went live. If you mean “most recently live”, ask for sort=published_at.

Caching interacts with paging

Each distinct query string is cached separately for 60 seconds. Iterating pages 1..N produces N cache entries, and repeating the same iteration within the minute is served entirely from cache and costs no rate limit quota. Note that the cache key is the literal URL, so reordering parameters creates a separate entry. See Caching.