Skip to content
FreeTicketDocs
Esc
↑↓navigate↵open⌘Jpreview
On this page

Errors, pagination and limits

The response envelope, error codes, cursor pagination, rate limits, retries and idempotency shared by the FreeTicket APIs.

Response envelope

Successful responses wrap the payload in data:

{ "data": { "id": "…", "name": "Concierto de prueba" } }

Lists add a page object. See Pagination. Some responses also carry a non-fatal warnings array that explains a surprising result. For example, an empty list may come with a warning when the key also reaches other workspaces. Clients that don’t read warnings keep working.

Errors

Every B2B error has the same shape:

{
  "error": {
    "code": "UNPROCESSABLE_ENTITY",
    "message": "Cuerpo o parámetros inválidos.",
    "retryable": false,
    "details": [{ "path": "dates.0.startsAt", "message": "…" }]
  }
}
Field Meaning
code Stable, machine-readable code. Branch on this, not on message.
message Human-readable explanation, in Spanish.
retryable true when repeating the same request may succeed. Set by the server.
details Optional context. On 422 it lists each invalid field with its path.
Status Default code When
400 BAD_REQUEST Malformed request
401 UNAUTHORIZED Missing, invalid, expired or revoked key
403 FORBIDDEN Role too low, or one of READ_ONLY_KEY, ACCESS_EXPIRED, SECTION_FORBIDDEN
404 NOT_FOUND Doesn’t exist, or belongs to another workspace
409 CONFLICT or a specific code The request conflicts with the resource’s state
422 UNPROCESSABLE_ENTITY Body or query failed validation
429 RATE_LIMITED Too many requests. See Rate limits.
5xx INTERNAL_ERROR, UNAVAILABLE Server or upstream failure

Many 409s carry a specific code that tells you what to do next. For example, SALE_ALREADY_CHECKED_IN when cancelling a sale whose tickets were already used at the door. Each operation lists its codes in the reference.

Pagination

B2B list endpoints use cursor pagination:

Query parameter Default Notes
limit 20 1 to 100
cursor The nextCursor from the previous page
withTotal off 1 adds page.total, at the cost of an extra count
{
  "data": [ … ],
  "page": { "nextCursor": "clx…", "hasMore": true }
}

Keep requesting with cursor=<nextCursor> while hasMore is true:

cursor=""
while :; do
  res=$(curl -s "$FT/sales?limit=100${cursor:+&cursor=$cursor}" \
    -H "Authorization: Bearer $FT_KEY" -H "X-Workspace-Id: $WS")
  echo "$res" | jq -c '.data[]'
  [ "$(echo "$res" | jq -r '.page.hasMore')" = "true" ] || break
  cursor=$(echo "$res" | jq -r '.page.nextCursor')
done

A cursor only means something inside the workspace that issued it, so keep X-Workspace-Id fixed while you walk the pages.

Export endpoints under /reports/exports/* return up to 5,000 rows per call. The public event catalog uses page and pageSize (up to 50) instead of cursors.

Rate limits

Unauthenticated and abuse-prone endpoints are throttled, especially on the public API: order creation is limited per IP, and ticket resend per ticket code. When you hit a limit:

  • The status is 429 and error.retryable is true.
  • The Retry-After header gives the number of seconds to wait.

Honor Retry-After, back off exponentially on repeated 429s, and don’t retry errors where retryable is false. Those fail the same way until you change the request.

Idempotency

POST /sales accepts an Idempotency-Key header of up to 255 characters, unique per workspace. If you repeat a request with the same key, you get the sale that the first attempt created instead of a second one. The replayed response is a 201 with the header Idempotent-Replay: true.

curl -X POST $FT/sales \
  -H "Authorization: Bearer $FT_KEY" \
  -H "X-Workspace-Id: $WS" \
  -H "Idempotency-Key: order-8812" \
  -H "Content-Type: application/json" \
  -d @sale.json

Send one on every sale your client might retry, for example after a timeout. A key longer than 255 characters returns 422 rather than being silently ignored.

Dates, money and time zones

  • Timestamps are ISO 8601. Responses are in UTC. Send UTC (Z) or an explicit offset.
  • Each event date carries an IANA timezone, America/Bogota by default. Use it when you display local times.
  • Amounts are plain numbers in the resource’s currency, usually COP. Don’t assume cents.

Was this page helpful?