Skip to content

Integration notes

These notes collect real API behaviors that you cannot infer by reading the contract. All of them were verified against the production environment from a live integration.

The catalog’s availability data arrives stale

Section titled “The catalog’s availability data arrives stale”

GET /external/tramos returns availability counters (libres, librescoche, libresmoto) that are not up to date. In a measurement on 28 September 2026, for section 474 and at the same instant:

Request libres librescoche
GET /external/tramo/474 22 22
GET /external/tramos 7 7

This qualifies the recommendation to cache the catalog for five minutes: it holds for geometry, names and operating hours, which change rarely, but not for availability.

Several endpoints identify the resource in the path. The query-string form does not fail obviously: in some cases it returns a misleading error.

Endpoint Correct form
Get plate GET /external/placa/{placa}
Get vehicle GET /external/vehiculo/{vehiculo_id}
Get section GET /external/tramo/{tramo_id}
Pay reservation PUT /external/reserva-pagar/{reserva_id}
Cancel reservation PUT /external/reserva-cancelar/{reserva_id}
Extend reservation PUT /external/reserva-extender/{reserva_id}
Close sanction PUT /external/sancion-cerrar/{sancion_id}
Pay sanction PUT /external/sancion-pagar/{sancion_id}

GET /external/cliente-email reads the email from the JSON body, not from the query string. Sending it as a query parameter causes an HTTP 500 on the server.

Ventana de terminal
curl -X GET "https://api-dev.zonaparqueo.com/external/cliente-email" \
-H "Authorization: Token ABC123:XYZ789" \
-H "Content-Type: application/json" \
-d '{"email": "client@example.com"}'

Unlike the previous one, GET /external/vehiculos does read filters from the query string. Sending them in the body makes the server silently ignore them and return an unfiltered global page, with a 200 status.

GET /external/tramos?id=474 silently ignores the parameter and returns the full catalog, with a 200 status. There is no error and no warning: the response simply carries hundreds of sections. Confirmed by the provider and measured on 28 September 2026 (5 samples): a median of 10.25 s with the parameter versus 10.55 s without it — the same request.

To query a single section, either of these two forms works and takes about seven times less:

Request Median
GET /external/tramo/474 1.36 s
GET /external/tramo?id=474 1.41 s
GET /external/tramos?id=474 10.25 s (the whole catalog)

The path is /external/tramo-precios-estacionar, plural. The singular form tramo-precio-estacionar returns HTTP 404.

An open sanction cannot be paid: the server responds no se puede pagar porque no esta cerrada. It must be closed first.

  1. PUT /external/sancion-cerrar/{sancion_id}
  2. PUT /external/sancion-pagar/{sancion_id}

Closing an already-closed sanction is harmless, so step 1 can always be executed.

GET /external/tramos-cercanos was down between June and September 2026, returning HTTP 500 for all queries because of an ambiguous activado column in the WHERE clause of the tramo LEFT JOIN horario query. It now works normally.

Verified on 26 September 2026: it returns 200 and its distances match, to the metre, an independent haversine calculation over the catalog’s own coordinates (13 out of 13), with no active section inside the radius omitted.

If your integration has a workaround that filters the full catalog by distance on the client side, you can now retire it: that is the slowest path (around 10 s per query versus 2.6 to 5.1 s for the endpoint).

Neither tramos-cercanos nor the catalog applies operating hours. To show only operating sections you must filter on the consumer side by inicio_garantizado / fin_garantizado and activo_domingo, in Bogota local time (UTC-5, no daylight saving). Sections with no hours defined are treated as always open.

The API is slow, and client timeouts should be sized accordingly. Measured on 28 September 2026:

Endpoint Time
/external/tramos (catalog, ~654 KB) ~10 s
/external/tramos-cercanos 2.6 to 5.1 s
/external/tramo/{id} ~1.4 s
/external/placa/{placa} ~2 s

The provider is evaluating paginating the catalog to bring that time down. Endpoints not listed in the table were not measured.

  • The status filter on /external/reservas is named Estado, with a capital E.
  • /external/reservas also accepts tramo_id: combined with Estado=1 it returns the plates currently parked in that section.
  • On reserva-pagar, enviar_recibo: true makes the system email the official receipt to the client.
  • minutos must be a multiple of 10, both when creating and when extending a reservation.

Where this guide’s data comes from: our own measurements against api.zonaparqueo.com on 26 and 28 September 2026 (5 samples per endpoint), the provider’s 28 September response to case 26783728, and the production integration verified against the endpoints in use.