# Waze All-in-One API (`romy/waze-all-in-one-api`) Actor

Standby REST API for Waze: real-time road events, live route calculation, place search, nearby POI, reverse geocoding, walking distance, batch ETA, and emergency/roadside-assistance contacts — via Waze's internal RT protocol. Confirmed working worldwide, not just one region. No API key needed.

- **URL**: https://apify.com/romy/waze-all-in-one-api.md
- **Developed by:** [Romy](https://apify.com/romy) (community)
- **Categories:** Travel, Developer tools
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.68 / 1,000 real-time road alerts

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### What does Waze All-in-One API do?

**Waze All-in-One API** is a REST endpoint for Waze's live data — crowd-sourced road events, route calculation with real-time traffic, place search, nearby points of interest, reverse geocoding, logistics helpers (walking distance, batch ETA), and real local emergency/roadside-assistance contacts — from a single always-on API powered by [Apify Standby](https://docs.apify.com/platform/actors/development/programming-interface/standby).

It talks directly to the same internal protocol the official [Waze](https://www.waze.com/) Android app uses (`rt.waze.com`), reverse-engineered by live MITM capture against a real device and cross-referenced against the app's own decompiled protobuf schema (see `proto/waze_rt.proto` in the source repo — field names and numbers are the real app's, not guesses). No Waze account, no API key, no scraping setup — call the endpoint, get JSON back. Each request mints its own short-lived anonymous session server-side; you never see or manage credentials.

**Confirmed working worldwide** — every endpoint below was tested live in Indonesia, the UK, the US, and Israel during development, not just one market.

### Why use Waze All-in-One API?

- **Real crowd-sourced road events** — closures, contraflow lanes, and hazards with geometry, the same data rendered as dashed lines and pins in the Waze app
- **Live route calculation** — distance, ETA, live traffic comparison, and route-level warnings (tolls, permits, restricted lanes), the same engine behind the app's own navigation
- **Place search** — the same location-biased venue lookup as the app's search bar
- **Nearby POI discovery** — what's around a point, with real category tags, no text query needed
- **Reverse geocoding** — turn any coordinate into a street address
- **Batch ETA** — real-time ETA to many destinations in one request, for dispatch/delivery routing
- **Emergency & roadside assistance contacts** — real local numbers (police/ambulance/fire, auto clubs, manufacturer roadside assistance), not templated
- **Global** — not tied to one country's data
- **Always-on** — Standby mode means no cold start, responds in milliseconds
- **No account needed** — every request authenticates itself
- **Use cases:** traffic monitoring dashboards, logistics/routing risk analysis, road-closure alerting, ETA estimation, delivery dispatch, urban mobility research, travel/safety apps

### Endpoints

| Method | Path | Description |
|--------|------|--------------|
| `GET` | `/alerts` | Real-time road events (closures, contraflow, hazards) within a bounding box |
| `GET` | `/route` | Live route calculation between two points — distance, ETA, traffic, warnings |
| `GET` | `/search` | Place/venue search, biased toward a location |
| `GET` | `/nearby` | Points of interest near a location, with real category tags |
| `GET` | `/reverse-geocode` | Turn a coordinate into a street address |
| `GET` | `/walking-distance` | Walking distance in meters between two points |
| `GET` | `/eta-batch` | Live ETA from one origin to many destinations in a single call |
| `GET` | `/sos-providers` | Emergency numbers and roadside-assistance contacts for a location |

### How to use Waze All-in-One API

1. Open this Actor's Standby API URL (shown on the Actor's page, under the API tab).
2. Call any endpoint — for example:
   ```bash
   curl "https://romy--waze-all-in-one-api.apify.actor/alerts?north=-6.15&south=-6.18&east=106.83&west=106.82"
   curl "https://romy--waze-all-in-one-api.apify.actor/route?from_lat=-6.1754&from_lon=106.827&to_lat=-6.1274&to_lon=106.6577"
   curl "https://romy--waze-all-in-one-api.apify.actor/search?query=SPBU&lat=-6.1754&lon=106.827"
   curl "https://romy--waze-all-in-one-api.apify.actor/nearby?lat=-6.175&lon=106.827"
   curl "https://romy--waze-all-in-one-api.apify.actor/reverse-geocode?lat=-6.1954&lon=106.8206"
   curl "https://romy--waze-all-in-one-api.apify.actor/walking-distance?from_lat=-6.1754&from_lon=106.827&to_lat=-6.178&to_lon=106.83"
   curl "https://romy--waze-all-in-one-api.apify.actor/eta-batch?from_lat=-6.1754&from_lon=106.827&to=-6.1274,106.6577&to=-6.1954,106.8206"
   curl "https://romy--waze-all-in-one-api.apify.actor/sos-providers?lat=40.7580&lon=-73.9855"
   ```
3. Read the JSON response — no setup required.

### Input

This Actor takes no run-input; it starts immediately in Standby mode. All parameters are passed per-request as HTTP query strings — see the endpoint table above and the OpenAPI schema (API tab on the Actor's page).

### Output

Every response is returned directly over HTTP — this Actor does not write to an Apify dataset. Real responses (trimmed):

`GET /alerts?north=-6.15&south=-6.18&east=106.83&west=106.82`:

```json
{
  "success": true,
  "events": [
    {
      "id": "750503858",
      "version": 0,
      "typeCode": 5,
      "street": "Contra Flow Hayam Wuruk",
      "city": "Jakarta Pusat",
      "crossStreet": "Gajah Mada",
      "points": [
        { "lon": 106.820862, "lat": -6.167265 },
        { "lon": 106.819936, "lat": -6.163168 }
      ],
      "roadSegmentIds": ["516284383", "516266383"],
      "raw": ["AddRoadInfo", "750503858", "0", "5", "0", "Contra Flow Hayam Wuruk", "Jakarta Pusat", "", "Gajah Mada", "F", "F", "0", "0", "2", "0", "-1", "T", "-1", "-1", "12", "-1", "F", "0", "0", "465", "", "1164106498", "1"]
    }
  ]
}
```

`GET /route?from_lat=-6.1754&from_lon=106.827&to_lat=-6.1274&to_lon=106.6577`:

```json
{
  "success": true,
  "routes": [
    { "totalLength": 31365, "totalSeconds": 1986 },
    { "totalLength": 27001, "totalSeconds": 2909 },
    { "totalLength": 27176, "totalSeconds": 1990 }
  ]
}
```

`GET /search?query=SPBU&lat=-6.1754&lon=106.827`:

```json
{
  "success": true,
  "venues": [
    {
      "name": "SPBU 34.10401",
      "location": { "x": 106.843635672, "y": -6.184980284 },
      "city": "Jakarta Pusat",
      "country": "ID",
      "address": "Kramat Raya 116 RT 002/09",
      "phone": "+62-21-3106507"
    }
  ]
}
```

`GET /nearby?lat=-6.175&lon=106.827&max_results=2`:

```json
{
  "success": true,
  "venues": [
    { "name": "Monumen Nasional", "categories": ["MUSEUM"], "location": { "x": 106.827159601, "y": -6.175430914 }, "city": "Jakarta Pusat", "country": "ID" },
    { "name": "Monas Futsal Arenas", "categories": ["STADIUM_ARENA"], "location": { "x": 106.829028705, "y": -6.174461243 }, "street": "Medan Merdeka Timur", "city": "Jakarta Pusat", "country": "ID" }
  ]
}
```

`GET /reverse-geocode?lat=-6.1954&lon=106.8206`:

```json
{
  "success": true,
  "venue": { "street": "Jalan Teluk Betung", "city": "Jakarta Pusat" }
}
```

`GET /walking-distance?from_lat=-6.1754&from_lon=106.827&to_lat=-6.178&to_lon=106.83`:

```json
{ "success": true, "meters": 411 }
```

`GET /eta-batch?from_lat=-6.1754&from_lon=106.827&to=-6.1274,106.6577&to=-6.1954,106.8206`:

```json
{
  "success": true,
  "results": [
    { "lat": -6.1274, "lon": 106.6577, "seconds": 2056 },
    { "lat": -6.1954, "lon": 106.8206, "seconds": 455 }
  ]
}
```

`GET /sos-providers?lat=40.7580&lon=-73.9855`:

```json
{
  "success": true,
  "providers": [
    { "phone": "911", "name": "911" },
    { "type": 1, "subtype": 3, "phone": "18444110791", "name": "AAA" },
    { "type": 1, "subtype": 3, "phone": "18777983752", "name": "Tesla" }
  ]
}
```

### Data table

**`/alerts` events:**

| Field | Description |
|-------|--------------|
| `id` | Stable event id, unchanged across live updates |
| `version` | Update/sequence number for this event |
| `typeCode` | Numeric event type (not yet mapped to a name — see Known limitations) |
| `street` / `city` / `crossStreet` | Location context, as reported |
| `points` | Event geometry (polyline), decoded lon/lat |
| `roadSegmentIds` | Underlying Waze road-graph segment ids the event is linked to |
| `raw` | The unparsed `AddRoadInfo` CSV fields, for the handful of positions not yet mapped to a named field above |

**`/route` alternatives:**

| Field | Description |
|-------|--------------|
| `totalLength` | Distance in meters |
| `totalSeconds` | ETA in seconds |
| `trafficComment` | Live traffic-comparison text (e.g. "lighter traffic than usual"), when present |
| `isInvalidForPrivateVehicle` | True when this route needs a taxi/permit/restricted-vehicle type |
| `question` | Route-level warnings/confirmations (tolls, permits, restricted lanes), when present |

**`/search`, `/nearby` venues / `/reverse-geocode` venue:**

| Field | Description |
|-------|--------------|
| `name` / `houseNumber` / `street` / `city` / `country` / `address` / `phone` | Venue/address details, as reported (not every field is populated for every result) |
| `location.x` / `location.y` | Longitude / latitude (plain decimal degrees) — `/search` and `/nearby` only |
| `categories` | Real Waze taxonomy (e.g. `["MUSEUM"]`, `["CAFE"]`) — `/nearby` only |

**`/eta-batch` results:**

| Field | Description |
|-------|--------------|
| `lat` / `lon` | Echoes back the destination requested |
| `seconds` | Live ETA in seconds, `null` if that leg failed |

**`/sos-providers` providers:**

| Field | Description |
|-------|--------------|
| `name` / `phone` / `url` | Contact details, as reported |
| `type` / `subtype` | Numeric category (not yet mapped to a name) |

### Pricing

Pay-per-event, billed on each successful call. See the Actor's Pricing tab for current rates.

### Known limitations

- **`/alerts`' `typeCode`, and a handful of its other numeric fields, aren't mapped to human-readable names.** `AddRoadInfo` is parsed entirely natively (no Java-side protobuf class to cross-reference, unlike every other endpoint here) — confirmed by decompiling the actual native parser function. That decompile did surface two verified wire-format facts not yet correlated to an exact field position: one numeric field is a float scaled ×10 (not a plain int), and one field supports a `|`-delimited sub-list of up to 20 integers — never populated in any sample captured so far. The unmapped positions are returned under `raw` rather than guessed at.
- **`/route` doesn't return route line geometry.** Waze encodes it with Google's S2 cell geometry format (a compressed spherical-geometry encoding), which isn't decoded by this Actor — distance, ETA, traffic, and warnings are all real-time and accurate, only the polyline itself is omitted.
- **`/reverse-geocode` returned empty in some regions during testing** (New York and Tel Aviv, both otherwise dense Waze markets) despite working reliably in Indonesia and the UK. Cause not yet isolated — logged as a regional caveat rather than assumed fixed everywhere.
- **Parking search exists in the protocol but isn't exposed here.** It returned zero results in every live test during development — Jakarta, a Jakarta mall district, and Tel Aviv (Waze's own home market) — despite a well-formed request, across multiple radii and with/without the "popular" flag. Most likely the request needs a different shape than a generic point+radius search (e.g. anchored to a specific venue) rather than a data gap. Kept in the proto schema for future work, not exposed as a public endpoint while empty.
- **`/nearby` doesn't support filtering by category.** The protocol has a `category` filter field, and real category strings were pulled straight from the app (`GAS_STATION`, `PARKING_LOT`, `CHARGING_STATION`, `EV_CHARGING_STATION`, ...), but every one tried returned zero results in testing, while leaving the filter unset reliably returns real nearby venues with their category already attached. Filter client-side on the `categories` field in the response for now.
- This is an unofficial, reverse-engineered integration, not affiliated with or endorsed by Waze / Google. Behavior may change if Waze changes its protocol.

Found a bug or have a feature request? Use the Issues tab on this Actor's page.

# Actor input Schema

## Actor input object example

```json
{}
```

# Actor output Schema

## `api` (type: `string`):

This Actor doesn't write to a dataset — every response is returned directly over HTTP by its Standby web server. See the README / web server OpenAPI schema (webServerSchema) for the full endpoint list and response shapes (GET /alerts).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("romy/waze-all-in-one-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("romy/waze-all-in-one-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call romy/waze-all-in-one-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,romy/waze-all-in-one-api"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4V1sWZxVbTdma6p3f/builds/9sU4UrZLivBxQb9up/openapi.json
