Source: https://developers.woosmap.com/products/distance-api/features/matrix_async/

> For clean Markdown of any page, append `.md` to the page URL.

> For a complete documentation index, see https://developers.woosmap.com/llms.txt

# Distance Matrix Async



**Complete API Specification**: [Distance Async API Reference](/api-reference/distance-async-api/post-distance-matrix-async/)

## What are the Matrix Async Endpoints?

These Endpoints are a specialized service within the Woosmap platform designed to handle large-scale distance matrix
calculations that exceed the limits of the standard synchronous Distance Matrix Endpoint. Instead of waiting for results
in real-time, you submit a calculation job, monitor its progress, and retrieve the results once processing is complete.

### What It Does

This service calculates travel distances and durations between multiple origins and destinations asynchronously,
making it ideal for scenarios involving hundreds or thousands of origin-destination pairs. The asynchronous approach
allows the server to process complex calculations without timing out, while you can continue with other tasks. This information is key to finding and **sorting assets by road distance**.

### Key Characteristics

- **Asynchronous workflow**: Submit a job, poll for status, retrieve results when ready.
- **Large-scale support**: Handle matrix sizes that exceed synchronous API limits.

## When to Use These Endpoints

The Distance Matrix Async Endpoints are the right choice when your distance matrix calculations are too large or complex
for real-time processing. Unlike the synchronous [Matrix API](/products/distance-api/features/matrix), which returns
results immediately but has stricter limits, the async endpoint allows you to submit large jobs and retrieve results
when processing is complete.

Choose the Async endpoints when:

- **Your matrix exceeds synchronous limits**: When the number of origin-destination pairs exceeds what the standard
  Matrix API can handle in a single request.
- **Batch processing is acceptable**: Your workflow can accommodate a submit-poll-retrieve pattern rather than
  requiring instant results.
- **Server-side processing**: You're running backend jobs, scheduled tasks, or data pipelines where waiting for
  results is not an issue.

For real-time user-facing applications requiring immediate responses with smaller matrices (up to 200 elements),
use the standard [Matrix API](/products/distance-api/features/matrix) instead.

The Async Distance Matrix is billed per origin-destination element, similar to the standard Distance Matrix Endpoint.
See your plan details for exact billing information.

## API Endpoints (POST and GET)

The async workflow uses three endpoints:

```http
# 1) Submit a calculation job
POST https://api.woosmap.com/distance/matrix/async/

# 2) Check job status
GET  https://api.woosmap.com/distance/matrix/async/{matrix_id}/status

# 3) Retrieve results (once completed)
GET  https://api.woosmap.com/distance/matrix/async/{matrix_id}
```

### Authentication

Authenticate using either a `key` (public API key for client-side requests) or `private_key` (for server-side requests).
Public keys require domain/IP restrictions, while private keys should be kept secret and never exposed in client code.
You can also use the `X-Api-Key` header for server-side authentication.

```bash
# Client-side (query parameter)
?key=YOUR_PUBLIC_KEY

# Server-side (query parameter)
?private_key=YOUR_PRIVATE_KEY

# Server-side (header)
-H "X-Api-Key: YOUR_PRIVATE_KEY"
```

For complete authentication details and security best practices, see [API Keys Documentation](/api-reference/authentication/).

## Request Parameters Overview

### Required Parameters

**`origins`** — The starting points for calculating travel distance and time. Supply one or more locations separated
by the pipe character (`|`), in the form of latitude/longitude coordinates. Ensure that no space exists between the
latitude and longitude values.

**`destinations`** — One or more locations to use as the finishing points for calculating travel distance and time.
The format is the same as for origins, described above.

To reduce payload size, [encoded polylines](https://developers.google.com/maps/documentation/utilities/polylinealgorithm)
are supported for both `origins` and `destinations` using the syntax `enc:<an-encoded-polyline>:`.

**`key`** or **`private_key`** — Your API authentication key. See [Authentication](#authentication) above.

### Key Optional Parameters

**`mode`** — Specifies the mode of transport to use when calculating distance. Valid values are `driving` (default)
or `truck`.

## Complete Parameter Reference

For all available parameters and advanced options see:

- [OpenAPI Specification](/api-reference/distance-async-api/post-distance-matrix-async/) - Complete technical reference

## Asynchronous Workflow

The async workflow consists of three steps:

### 1. Submit a Job

Send a POST request to the async endpoint with your matrix parameters in the request body. The server validates your
request and returns a `matrix_id` along with an initial status.

### 2. Poll for Status

Periodically query the status endpoint using your `matrix_id`. Continue polling until the status indicates
the job is `completed` or has encountered an error.

### 3. Retrieve Results

Once the status is `completed`, fetch the full matrix results using the results endpoint. The response
will redirect (HTTP 303) to the location containing your calculated matrix.

### Job Status Values

| Status       | Description                                             |
| ------------ | ------------------------------------------------------- |
| `accepted`   | The job has been received and is queued for processing. |
| `inProgress` | The job is currently being processed.                   |
| `completed`  | Processing is complete and results are available.       |
| `timeout`    | The job exceeded the maximum processing time.           |
| `error`      | An error occurred during processing.                    |

## API Request Examples

### 1. Submit an Async Job

```bash
curl -X POST \
  "https://api.woosmap.com/distance/matrix/async/?private_key=YOUR_PRIVATE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "origins": "48.865,2.347|48.8566,2.3522",
    "destinations": "48.820,1.910|48.667,3.143|49.180,-0.362",
    "mode": "driving"
  }'
```

Example response:

```json
{
  "matrix_id": "dm_8d2b9c8f-1234-5678-abcd-ef0123456789",
  "status": "accepted"
}
```

### 2. Check Job Status

```bash
curl "https://api.woosmap.com/distance/matrix/async/dm_8d2b9c8f-1234-5678-abcd-ef0123456789/status?private_key=YOUR_PRIVATE_KEY"
```

Example response (in progress):

```json
{
  "status": "inProgress"
}
```

Example response (completed):

```json
{
  "status": "completed"
}
```

### 3. Retrieve Results

```bash
curl --location --compressed "https://api.woosmap.com/distance/matrix/async/dm_8d2b9c8f-1234-5678-abcd-ef0123456789?private_key=YOUR_PRIVATE_KEY"
```

Use the `--location` flag with curl to automatically follow the HTTP 303 redirect to the results location and
`--compressed` to decompress the response.

Example response:

```json
{
  "matrixId": "dm_8d2b9c8f-1234-5678-abcd-ef0123456789",
  "matrix": {
    "numOrigins": 2,
    "numDestinations": 3,
    "travelTimes": [2570, 3332, 8241, 2598, 3122, 8318],
    "distances": [41205, 74801, 233733, 41203, 73342, 234634]
  },
  "regionDefinition": {
    "type": "world"
  }
}
```

## Understanding the Response

The async result follows a different structure to the standard Distance Matrix API response:

- **`matrix`** — The full distance matrix, including travel times and distances.
- **`matrix.numOrigins`** — The number of origins corresponds to the number of rows in the matrix.
- **`matrix.numDestinations`** — The number of destinations corresponds to the number of columns in the matrix.
- **`matrix.travelTimes[]`** — Each element corresponds to one origin-destination pair and is the travel time between
  them in seconds
- **`matrix.distances[]`** — Each element corresponds to one origin-destination pair and is the distance between them in
  meters
- **`regionDefinition`** — Specifies the region used for distance calculations. Currently, only `world` is supported.

## Usage Limits & Quotas

The following usage limits apply to the Async Distance Matrix API:

- Maximum 20 requests per second per project.

Consult your contract or contact support for specific limits applicable to your project.

## Working Code Examples

Below is a Node.js example demonstrating the complete async workflow. Replace `YOUR_PRIVATE_KEY` with your actual key.

```javascript
const BASE_URL = "https://api.woosmap.com/distance/matrix/async";
const API_KEY = process.env.WOOSMAP_PRIVATE_KEY;

async function submitJob() {
  const response = await fetch(`${BASE_URL}/?private_key=${API_KEY}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      origins: "48.865,2.347|48.8566,2.3522",
      destinations: "48.820,1.910|48.667,3.143|49.180,-0.362",
      mode: "driving",
    }),
  });
  return response.json();
}

async function checkStatus(matrixId) {
  const response = await fetch(`${BASE_URL}/${matrixId}/status?private_key=${API_KEY}`);
  return response.json();
}

async function waitForCompletion(matrixId, timeoutMs = 300000, intervalMs = 2000) {
  const startTime = Date.now();

  while (Date.now() - startTime < timeoutMs) {
    const { status } = await checkStatus(matrixId);

    if (status === "completed") return true;
    if (status === "error" || status === "timeout") {
      throw new Error(`Job failed with status: ${status}`);
    }

    // Wait before polling again
    await new Promise((resolve) => setTimeout(resolve, intervalMs));
  }

  throw new Error("Timeout waiting for job completion");
}

async function fetchResults(matrixId) {
  const response = await fetch(`${BASE_URL}/${matrixId}?private_key=${API_KEY}`, { redirect: "follow" });
  return response.json();
}

// Main execution
(async () => {
  try {
    // Step 1: Submit the job
    const job = await submitJob();
    console.log("Job submitted:", job.matrix_id);

    // Step 2: Wait for completion
    await waitForCompletion(job.matrix_id);
    console.log("Job completed!");

    // Step 3: Fetch results
    const results = await fetchResults(job.matrix_id);
    console.log("Matrix rows:", results.matrix.travelTimes.length);
    console.log("Results:", JSON.stringify(results, null, 2));
  } catch (error) {
    console.error("Error:", error.message);
  }
})();
```
