# v1 endpoints

The older API, in the routing engine's and geocoder's own formats. It still works, but new clients should use /v2.

> **New clients should use [`/v2`](../index.md).** These endpoints still work and haven't changed. They use different coordinate order and units from `/v2`, so a client that talks to both must not share a point-formatting helper.

## Rules for v1 calls

1. **Send your key.** Programs send `X-API-Key` on every call except `/health`. Missing or unknown keys get `401`. `/isochrone` and `/spt` accept a key only.
2. **`point=` query parameters are `lat,lng`.** `point=10.7202,122.5621` is Iloilo City. This is the opposite of `/v2`.
3. **`POST /route` bodies and every response use `[lng, lat]`.** Swap them to `lat,lng` before you use a returned coordinate in a `point=` parameter.
4. **`profile` is `car`.** Any other value returns `400`.
5. **`distance` is in metres and `time` is in milliseconds.** Divide `time` by 60000 for minutes.
6. **Don't send `ch.disable` or custom models.** They return `403`.
7. **`POST` is for `/route` only.** `GET /route` and `POST` to any other endpoint return `403`.

The rate limit is 20 requests per second per key, with a burst of 40. Over it, you get `429` with `Retry-After`.

## `POST /route`

```bash
curl -s -X POST -H 'Content-Type: application/json' -H "X-API-Key: $QUADRUPER_KEY" \
  -d '{"points":[[122.5621,10.7202],[122.5644,10.6969]],"profile":"car","points_encoded":false,"instructions":true,"locale":"en"}' \
  https://quadruper.com/route
```

| Field | Required | Description |
|---|---|---|
| `points` | Yes | 2 or more `[lng, lat]` pairs, in travel order. Stops aren't reordered. Keep consecutive points within 1000 km. |
| `profile` | Yes | `car` |
| `points_encoded` | No | `false` returns GeoJSON geometry. The default is an encoded polyline. |
| `calc_points` | No | `false` leaves out the geometry. |
| `instructions` | No | `true` (default) returns turn-by-turn steps. |
| `locale` | No | Language of the instruction text. |
| `details` | No | Array of per-segment attributes such as `road_class`, `street_name`, `max_speed` or `road_environment`. |
| `point_hints` | No | Array, one entry per point. Helps snap to a named street. |
| `snap_preventions` | No | Array. Stops a point snapping onto a road type. The default already avoids `tunnel`, `bridge` and `ferry`. |

The body is limited to 32 KB. For distance and time only, send `"calc_points":false,"instructions":false`.

The fields you usually need are in `paths[0]`:

| Field | Meaning |
|---|---|
| `distance` | Total metres |
| `time` | Total milliseconds |
| `bbox` | `[minLng, minLat, maxLng, maxLat]` of the route |
| `points` | GeoJSON `LineString`, coordinates `[lng, lat]` |
| `instructions[]` | Steps with `text`, `distance`, `time`, `street_name`, `sign` and `interval` (an index range into `points`) |
| `details.<name>` | Lists of `[fromIndex, toIndex, value]` over `points` |

Common `sign` values: `0` continue, `-2` left, `2` right, `-1` and `1` slight left and right, `-3` and `3` sharp left and right, `7` keep right, `-7` keep left, `6` roundabout, `4` arrive.

v1 has no matrix. Use [`POST /v2/matrix`](../reference/matrix.md).

## `GET /nearest`

```bash
curl -s -H "X-API-Key: $QUADRUPER_KEY" 'https://quadruper.com/nearest?point=10.7202,122.5621'
```

Returns `{"type": "Point", "coordinates": [lng, lat], "distance": 2.93}`. `distance` is how far in metres the input was from the road.

## `GET /info`

```bash
curl -s -H "X-API-Key: $QUADRUPER_KEY" https://quadruper.com/info
```

Useful fields are `bbox`, `profiles`, `data_date` and `import_date`.

## `GET /health`

```bash
curl -s https://quadruper.com/health
```

Returns `OK` when the service is up. It needs no key.

## `GET /geocode/...`

These return GeoJSON `FeatureCollection`s. Each feature's coordinates are `[lng, lat]`, and its `properties` include `name`, `type`, `osm_key`, `osm_value` and `country`.

```bash
# Forward search
curl -s -H "X-API-Key: $QUADRUPER_KEY" 'https://quadruper.com/geocode/api?q=Iloilo&limit=1'

# Reverse lookup
curl -s -H "X-API-Key: $QUADRUPER_KEY" 'https://quadruper.com/geocode/reverse?lat=10.7202&lon=122.5621'

# Structured search
curl -s -H "X-API-Key: $QUADRUPER_KEY" 'https://quadruper.com/geocode/structured?countrycode=PH&city=Davao'
```

## `GET /isochrone`

Key only, and expensive. Keep `time_limit` small, such as 300 to 900 seconds.

```bash
curl -s -H "X-API-Key: $QUADRUPER_KEY" \
  'https://quadruper.com/isochrone?point=10.7202,122.5621&profile=car&time_limit=300'
```

`buckets=3` splits the area into rings. `reverse_flow=true` gives the area that can reach the point instead. The response is `{"polygons": [GeoJSON Feature, ...]}`.

## `GET /spt`

Key only, and expensive. Returns a CSV table of every node reachable within the time limit. `time` is in milliseconds and `distance` in metres.

```bash
curl -s -H "X-API-Key: $QUADRUPER_KEY" \
  'https://quadruper.com/spt?point=10.7202,122.5621&profile=car&time_limit=60&columns=longitude,latitude,time,distance'
```

## `GET /mvt/{z}/{x}/{y}.mvt`

Mapbox Vector Tiles (`application/x-protobuf`) of the routable road graph, for map clients that want to draw the network. Tiles outside the Philippines are empty.

## v1 errors

Errors return a JSON body with a human-readable `message` and a `hints[]` list. `hints[].point_index` tells you which point caused the problem.

| Status | Example `message` | What to do |
|---|---|---|
| `400` | `Point 1 is out of bounds` | Check the point and that it uses `lat,lng` order. |
| `400` | `The requested profile 'foot' does not exist` | Use `profile=car`. |
| `400` | `Cannot find point 0` | The point is too far from a drivable road. Move it, or call `/nearest` first. |
| `400` | `Connection between locations not found` | No road link exists. Tell the user, and don't retry. |
| `429` | `Monthly data cap reached. Contact the operator to raise it.` | Don't retry. See [Known limits](../concepts/known-limits.md#your-key). |
| `429` | `Rate limit exceeded. Slow down and retry.` | Wait and retry with backoff. |
| `5xx` | | Check `/health`, then retry with backoff a few times at most. |
