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.
Path parameter, not query string
Section titled “Path parameter, not query string”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 with a JSON body
Section titled “GET with a JSON body”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.
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"}'Body vs. query on /external/vehiculos
Section titled “Body vs. query on /external/vehiculos”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.
id does not filter the catalog
Section titled “id does not filter the catalog”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 name of the pricing endpoint
Section titled “The name of the pricing endpoint”The path is /external/tramo-precios-estacionar, plural. The singular form
tramo-precio-estacionar returns HTTP 404.
Mandatory order when paying a sanction
Section titled “Mandatory order when paying a sanction”An open sanction cannot be paid: the server responds
no se puede pagar porque no esta cerrada. It must be closed first.
PUT /external/sancion-cerrar/{sancion_id}PUT /external/sancion-pagar/{sancion_id}
Closing an already-closed sanction is harmless, so step 1 can always be executed.
tramos-cercanos works now
Section titled “tramos-cercanos works now”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).
Operating hours
Section titled “Operating hours”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.
Response times
Section titled “Response times”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.
Smaller details
Section titled “Smaller details”- The status filter on
/external/reservasis namedEstado, with a capital E. /external/reservasalso acceptstramo_id: combined withEstado=1it returns the plates currently parked in that section.- On
reserva-pagar,enviar_recibo: truemakes the system email the official receipt to the client. minutosmust 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.
