> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wede.pt/llms.txt
> Use this file to discover all available pages before exploring further.

# Action dispatch

> Rank teams for a catalog action and, with automatic dispatch on, dispatch the best team.

```http theme={null}
POST /v1/teams/dispatch/action
```

Ranks the available teams of your tenant for one action of your event catalog (for example `cardiac_arrest`) at an incident location. When automatic dispatch is on for your tenant, wede also dispatches the best team, as long as its score reaches your minimum score.

The same mechanism processes dispatches that field devices queue while offline and send later through [Device sync](/api-reference/devices.md#sync-a-device).

## Authentication

Session token (`Authorization: Bearer <token>`) with the `dispatch:assign` permission. Tenant roles with it: `company_admin`, `operational_supervisor`, `corporate_client`.

> [!WARNING]
>
> The integration API key (`x-wede-api-key`) has no `dispatch:*` permission. Calls with an API key return `403 forbidden`.

## Body

**action\_id** `string` *required*

`id` of an event type of your catalog (`GET /v1/catalog`, see [Event types](/api-reference/event-types.md)). Only types that send a team (`requires_teams`) rank anyone.

**lat** `number` *required*

Latitude of the incident.

**lng** `number` *required*

Longitude of the incident.

**event\_id** `string`

Identifier of the incident, for example the `event_id` wede returned for the event. If you omit it, wede generates a new UUID and returns it.

**priority** `string`

Priority of the incident. It influences the suggested `channel` of each team.

Send the same `event_id` when you retry: if the chosen team already has a mission for that event, wede returns it instead of creating a second one.

## Example

```bash theme={null}
curl -X POST https://api.wede.pt/v1/teams/dispatch/action \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action_id": "1c9d7f3e-2b4a-4c8e-9f10-3a5b7c9d1e2f",
    "event_id": "fbea1e0d-8f6b-42f5-bf9b-58fe77430f53",
    "lat": 38.7169,
    "lng": -9.1395,
    "priority": "critical"
  }'
```

## Response `200`

```json theme={null}
{
  "action": {
    "id": "1c9d7f3e-2b4a-4c8e-9f10-3a5b7c9d1e2f",
    "code": "cardiac_arrest",
    "name": "Cardiac arrest",
    "vertical": "healthcare"
  },
  "event_id": "fbea1e0d-8f6b-42f5-bf9b-58fe77430f53",
  "tiers": {
    "t1": [
      {
        "team_id": "259edc6e-95f3-42ba-bac5-263cfe51ebc0",
        "team_name": "Alpha Medical",
        "status": "available",
        "vertical": "healthcare",
        "distance_km": 2.4,
        "eta_min": 3,
        "equipment_match": 0.8,
        "member_availability": 1,
        "score": 0.9025,
        "recommended": true,
        "channel": "internet",
        "position": { "lat": 38.7302, "lng": -9.1511, "source": "gps", "last_seen": "2026-06-09T18:40:00.000Z" },
        "tier": 1,
        "fallback": false
      }
    ],
    "t2": [],
    "t3": []
  },
  "count": 1,
  "auto_dispatch_mode": true,
  "auto_dispatched": {
    "team_id": "259edc6e-95f3-42ba-bac5-263cfe51ebc0",
    "team_name": "Alpha Medical",
    "score": 0.9025,
    "channel": "internet"
  },
  "already_dispatched": false,
  "mission_id": "a3f0c2d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "requires_manual": false,
  "threshold": 0.5
}
```

**action** `object`

The catalog action: `id`, `code`, `name`, `vertical`.

**event\_id** `string`

The `event_id` you sent, or the one wede generated.

**tiers.t1** `object[]`

Available teams with members that cover this event type (`PUT /v1/teams/{teamId}/coverage`), best match first.

**tiers.t2** `object[]`

Available teams with members that cover the whole category of this event type, best match first.

**tiers.t3** `object[]`

Always an empty array since 8 October 2026: a team that covers neither the type nor its category is never a candidate. It is listed in `excluded`.

**tiers.\*\[]** `object`

Same fields as in [Dispatch score](/api-reference/teams/score.md#response-200), plus `tier` (`1` or `2`), `fallback` (`false`) and `missing_equipment`, the codes the type calls for that the team does not have operational (they lower the score and never exclude the team). `recommended` marks the first team within each tier.

**excluded** `object[]`

Teams of the vertical left out, each with `team_id`, `team_name` and `reason`: `no_members` or `no_coverage`.

**count** `integer`

Total number of candidate teams.

**auto\_dispatch\_mode** `boolean`

Whether automatic dispatch is on for your tenant.

**auto\_dispatched** `object | null`

The team wede dispatched automatically (`team_id`, `team_name`, `score`, `channel`), or `null`.

**already\_dispatched** `boolean`

`true` when the chosen team already had a mission for this `event_id`, so wede returned that mission.

**mission\_id** `string | null`

Mission of the automatically dispatched team, or `null`.

**requires\_manual** `boolean`

`true` when automatic dispatch is on but could not be completed. An operator must choose a team. Always `false` when automatic dispatch is off.

**threshold** `number`

Your tenant's minimum score for automatic dispatch, from `0` to `1`.

## Automatic dispatch

Automatic dispatch is a tenant setting. A `company_admin` or `company_tech` turns it on and sets the minimum score with `PATCH /v1/tenant/dispatch-settings` (`dispatch_mode`, `dispatch_threshold`).

When it is on, wede takes the best tier 1 team, or the best tier 2 team when no team covers the type itself, and:

1. Records the dispatch and sets the team to `on_mission`.
2. Creates a [mission](/api-reference/missions.md) with status `CREATED`, the type's vertical and the incident coordinates.
3. Sends the `team.dispatched` webhook with `{ team_id, event_id, auto: true, tier, below_threshold }`.

wede never waits for ideal conditions: a team below `threshold` is dispatched all the same and the mission is marked `below_threshold`. Only when no candidate is free does the event stay in the dispatch queue, which wede retries every minute. When automatic dispatch is off, the endpoint only ranks teams, and an operator dispatches with [Dispatch a team](/api-reference/teams/dispatch.md).

## Errors

| Status | `error` | When |
| - | - | - |
| `400` | `validation_error` | `action_id`, `lat` or `lng` is missing, or `lat` or `lng` is not a number. |
| `401` | `unauthorized` | Missing, invalid or expired credentials. |
| `403` | `forbidden` | Your role lacks `dispatch:assign`, or you used an API key. |
| `404` | `not_found` | The action does not exist in your tenant. |
| `500` | `internal_error` | Unexpected server error, including an `action_id` that is not a UUID. |

## SDKs

`dispatchAction` in JavaScript, `dispatch_action` in Python.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.