# API EmCurso

Ocorrências de proteção civil (ANEPC), avisos meteorológicos (IPMA) e dados de risco, contexto e histórico para Portugal.

> Serviço não oficial. Não substitui a informação oficial da ANEPC ou do IPMA e não é um canal de emergência. Em emergência, ligue 112.

- Base URL: `https://api.emcurso.pt`
- Endpoints: 37

## Atribuição da fonte (obrigatória)

Sempre que estes dados forem apresentados, tem de ser indicada a entidade que os produziu e o EmCurso como via de acesso, de forma visível junto dos dados. Os dados da ANEPC, do IPMA e do ICNF são publicados sob Creative Commons Atribuição 4.0: a atribuição é a condição da licença, não uma cortesia, e a licença cessa automaticamente para quem a viole. A mesma licença obriga a indicar que houve alterações — e há: as naturezas são normalizadas e as ocorrências classificadas e enriquecidas. O EmCurso não é a fonte primária nem um serviço oficial; apresentar os dados como oficiais, ou como sendo do EmCurso, induz o leitor em erro. Cada resposta traz um campo `fonte` ou `source` — use-o.

Formato mínimo: `Fonte: ANEPC · via api.emcurso.pt`

| Dados | Fonte a indicar | Licença |
| --- | --- | --- |
| Ocorrências de proteção civil | **ANEPC** | CC BY 4.0 |
| Avisos e previsão meteorológica, risco de incêndio | **IPMA** | CC BY 4.0 |
| Área ardida e causas (séries anuais) | **ICNF** | CC BY 4.0 |
| Perímetros de área ardida | **EFFIS · Copernicus EMS** | Dados Copernicus |
| Focos de calor por satélite | **NASA FIRMS** | Termos LANCE/FIRMS |
| Trânsito | **TomTom** | Licença comercial |
| Limites administrativos, meios de socorro, rotas | **OpenStreetMap** | ODbL |

## Acesso a esta documentação

Este documento é público e não exige chave. Está limitado a 30 pedidos por minuto e 300 por hora por endereço IP; o conteúdo só muda com um novo deploy, por isso vale a pena guardá-lo em cache em vez de o voltar a pedir.

## Autenticação

Todos os pedidos exigem uma chave de API no header `Authorization`, em formato Bearer, e um header `User-Agent` que identifique o sistema chamador. A chave é pedida em https://api.emcurso.pt e emitida após apreciação.

```http
Authorization: Bearer $EMCURSO_KEY
User-Agent: MinhaApp/1.0 (+https://exemplo.pt)
```

## Limites

Limites por omissão: 60 pedidos por minuto, 1000 por hora, 10000 por dia. Cada resposta transporta o estado da quota; um 429 indica em `Retry-After` quantos segundos aguardar, e esse valor nunca é zero.

## Headers de resposta

`Cache-Control` durante quantos segundos a resposta é válida · `X-Cache` HIT, MISS ou STALE · `X-Request-ID` identificador do pedido, a indicar ao reportar um problema · `X-RateLimit-Remaining` quanto resta da janela atual.

## Códigos de estado

`200` servido · `401` chave ausente ou inválida · `403` endpoint ou User-Agent não autorizado · `404` endpoint inexistente · `429` limite excedido · `5xx` erro do serviço ou da fonte. Repetir apenas em 429 e 5xx, com recuo exponencial.

## Cache

Pedir mais depressa do que os dados mudam devolve a mesma resposta e consome quota. Intervalo mínimo útil por família de endpoint:

| Endpoint | Cache |
| --- | --- |
| `/prociv/*` | 30 s |
| `/traffic/*` | 1 min |
| `/icnf/ocorrencia` | 5 min |
| `/fires/*, /context` | 5 min |
| `/ipma/warnings` | 10 min |
| `/ipma/forecast, /ipma/fire-risk` | 30 min |
| `/icnf/*, /geo/route` | 1 h |
| `/prociv/distritos, /geo/municipality-boundary` | 24 h |

## Endpoints

- **Conta e chave** — Dados da própria chave, devolvidos pelo EmCurso
  - [`/key`](#key-self) — Estado da própria chave
  - [`/health`](#health-self) — Saúde do sistema
- **Proteção Civil** — Fonte: ANEPC · dados a menos de 30 s da origem
  - [`/prociv/ocorrencias/todas`](#ocorrencias-todas) — Todas as ocorrências ativas
  - [`/prociv/ocorrencias/todas/last7days`](#ocorrencias-7dias) — Ocorrências dos últimos 7 dias
  - [`/prociv/ocorrencias/significativas`](#ocorrencias-significativas) — Ocorrências significativas
  - [`/prociv/ocorrencias/graves`](#ocorrencias-graves) — Ocorrências graves
  - [`/prociv/ocorrencias/distrito/{codigo}`](#ocorrencias-distrito) — Ocorrências por distrito
  - [`/prociv/ocorrencias/concelho/{codigo}`](#ocorrencias-concelho) — Ocorrências por concelho
  - [`/prociv/incendios`](#incendios) — Incêndios rurais e urbanos
  - [`/prociv/incendios/ativos`](#incendios-ativos) — Incêndios ativos
  - [`/prociv/incendios/significativos`](#incendios-significativos) — Incêndios significativos
  - [`/prociv/acidentes`](#acidentes) — Acidentes rodoviários e ferroviários
  - [`/prociv/meteorologia/impactos`](#meteorologia-impactos) — Ocorrências de causa meteorológica
  - [`/prociv/meios`](#meios) — Meios mobilizados (agregado)
  - [`/prociv/estatisticas`](#estatisticas) — Estatísticas globais
  - [`/prociv/distritos`](#distritos) — Tabela de distritos
  - [`/prociv/ocorrencias/stream`](#stream) — Notificação de alteração (SSE)
- **Deteção e risco de incêndio** — Fontes: NASA FIRMS · EFFIS (Copernicus) · ICNF · IPMA · redes ADS-B
  - [`/fires/hotspots`](#fires-hotspots) — Focos de calor por satélite
  - [`/fires/early-detection`](#fires-early-detection) — Deteção precoce
  - [`/fires/burnt-area`](#fires-burnt-area) — Área ardida de uma ocorrência
  - [`/fires/aircraft`](#fires-aircraft) — Meios aéreos em voo
  - [`/fires/risk-analysis`](#fires-risk-analysis) — Análise de risco de incêndio
  - [`/icnf/burnt-area`](#icnf-burnt-area) — Área ardida e causas (ICNF)
  - [`/icnf/ocorrencia/{codigo}`](#icnf-ocorrencia) — Ficha SGIF de uma ocorrência
  - [`/ipma/fire-risk`](#ipma-fire-risk) — Risco conjuntural de incêndio (RCM)
- **Meteorologia** — Fonte: IPMA · avisos e previsão
  - [`/ipma/warnings`](#warnings) — Avisos meteorológicos
  - [`/ipma/forecast`](#forecast) — Previsão por cidade
- **Contexto e histórico** — Trânsito TomTom, meteorologia IPMA e histórico próprio, por ocorrência
  - [`/context`](#context) — Contexto operacional de uma ocorrência
  - [`/incidents/history/{id}`](#history) — Histórico de uma ocorrência
  - [`/incidents/status-timeline`](#status-timeline) — Cronologia de estado
  - [`/stats/period-comparison`](#period-comparison) — Comparação de períodos
- **Geografia e trânsito** — Fontes: TomTom · Open-Meteo · OpenStreetMap · Nominatim · OSRM
  - [`/traffic/incidents`](#traffic-incidents) — Incidentes de trânsito
  - [`/traffic/geocode`](#traffic-geocode) — Geocodificação e geocodificação inversa
  - [`/geo/route`](#geo-route) — Rota entre dois pontos
  - [`/geo/wind`](#geo-wind) — Vento num ponto
  - [`/geo/entidades`](#geo-entidades) — Meios de socorro próximos
  - [`/geo/municipality-boundary`](#geo-municipality-boundary) — Limites administrativos

## Conta e chave

_Dados da própria chave, devolvidos pelo EmCurso_

### GET /key

**Estado da própria chave**

Dados da chave usada no pedido — nome, entidade, endpoints autorizados, User-Agent exigido — e o estado atual das três janelas de limite (minuto, hora, dia), incluindo quando cada uma repõe.

> **Nota:** Disponível com qualquer chave, seja qual for o valor de allowedEndpoints: este pedido não é validado contra os endpoints autorizados nem consome quota, precisamente para poder ser usado para verificar quanto resta. Numa janela já reposta, used vem a 0 e resetAt vem null.

#### Parâmetros

Sem parâmetros.

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/key"
```

#### Resposta (200)

```json
{
  "success": true,
  "key": {
    "id": "8f1c2e40-9b3a-4d61-9f2e-3c7a1b2d4e5f",
    "name": "Painel Operacional",
    "description": "Chave da sala de situação",
    "prefix": "emer_ab12",
    "entity": "EmCurso",
    "active": true,
    "expiresAt": null,
    "allowedEndpoints": ["*"],
    "userAgents": { "patterns": [], "enforced": false },
    "totalRequests": 48213,
    "lastUsedAt": "2026-08-03T10:41:00.000Z",
    "createdAt": "2026-01-15T09:00:00.000Z"
  },
  "rateLimit": {
    "minute": { "limit": 60, "used": 3, "remaining": 57, "resetAt": "2026-08-03T11:44:00.000Z" },
    "hour": { "limit": 1000, "used": 42, "remaining": 958, "resetAt": "2026-08-03T12:00:00.000Z" },
    "day": { "limit": 10000, "used": 120, "remaining": 9880, "resetAt": "2026-08-04T00:00:00.000Z" }
  },
  "meta": { "timestamp": "2026-08-03T11:43:22.000Z" }
}
```

### GET /health

**Saúde do sistema**

Confirma se a API está a responder, com que latência, o estado atual do serviço, qual chave autenticou o pedido e se há alguma anomalia em curso — quebra detetada por sonda, indisponibilidade declarada ou manutenção. Serve para um integrador distinguir, num único pedido, um problema do seu lado de um problema do nosso.

> **Nota:** Tal como /key, funciona com qualquer chave e não consome quota nem é validado contra allowedEndpoints — um diagnóstico não pode depender de ter acesso ao que está a diagnosticar. respondingMs é o tempo desta própria verificação; latency é a mediana e o p95 da última hora de tráfego real. anomalies vem vazio quando não há nada em curso.

#### Parâmetros

Sem parâmetros.

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/health"
```

#### Resposta (200)

```json
{
  "success": true,
  "responding": true,
  "respondingMs": 812,
  "status": "degraded",
  "latency": { "median1hMs": 118, "p95_1hMs": 340 },
  "key": {
    "id": "8f1c2e40-9b3a-4d61-9f2e-3c7a1b2d4e5f",
    "name": "Painel Operacional",
    "prefix": "emer_ab12",
    "active": true
  },
  "anomalies": [
    {
      "component": "ingest",
      "kind": "degraded",
      "severity": "minor",
      "title": "Recolha de histórico",
      "startedAt": "2026-08-03T10:58:00.000Z"
    }
  ],
  "checkedAt": "2026-08-03T11:43:22.000Z"
}
```

## Proteção Civil

_Fonte: ANEPC · dados a menos de 30 s da origem_

### GET /prociv/ocorrencias/todas

**Todas as ocorrências ativas**

Lista completa das ocorrências ativas em Portugal Continental, com estado, localização e meios mobilizados. Aceita formato GeoJSON para utilização direta em mapas.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/ocorrencias/todas"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 121,
    "cached": false,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/ocorrencias/todas/last7days

**Ocorrências dos últimos 7 dias**

Janela deslizante de sete dias, adequada a análise de tendência e a relatórios de curto prazo.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/ocorrencias/todas/last7days"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 812,
    "cached": true,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/ocorrencias/significativas

**Ocorrências significativas**

Subconjunto classificado pela ANEPC com código de importância 2: ocorrências em curso ou em resolução cuja duração e meios ultrapassam os limiares operacionais correntes.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/ocorrencias/significativas"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 3,
    "cached": false,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/ocorrencias/graves

**Ocorrências graves**

Ocorrências com código de importância 3, acrescidas das que estão em curso com mais de 50 operacionais mobilizados. Destina-se a alertas e a painéis de situação.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/ocorrencias/graves"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 2,
    "cached": false,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/ocorrencias/distrito/{codigo}

**Ocorrências por distrito**

Filtra as ocorrências ativas pelo código de distrito. Aceita também o nome do distrito. A lista de códigos está em /prociv/distritos.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `codigo` | path | sim | Código do distrito ou nome, ex.: 11 ou Lisboa. A lista completa está em /prociv/distritos. |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/ocorrencias/distrito/11"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": {
    "distrito": {
      "codigo": 11,
      "nome": "Lisboa",
      "capital": "Lisboa"
    },
    "ocorrencias": [
      {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "fonte": "PROCIV"
    }
    ],
    "total": 14
  },
  "meta": {
    "total": 14,
    "cached": false,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  },
  "distrito": {
    "codigo": 11,
    "nome": "Lisboa",
    "capital": "Lisboa"
  }
}
```

### GET /prociv/ocorrencias/concelho/{codigo}

**Ocorrências por concelho**

Filtra as ocorrências ativas pelo código DICO do concelho (distrito + concelho, quatro dígitos).

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `codigo` | path | sim | Código DICO do concelho, ex.: 1111 = Sintra. |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/ocorrencias/concelho/1111"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 3,
    "cached": false,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/incendios

**Incêndios rurais e urbanos**

Ocorrências ativas classificadas como incêndio, usando exatamente a mesma classificação da categoria Incêndios do mapa público. Um incêndio em veículo na sequência de uma colisão conta como incêndio, não como acidente.

> **Nota:** O bloco sgif cruza a ocorrência da ANEPC com o SGIF do ICNF pelo campo numero. Vem a null quando o ICNF não tem ficha — sempre nos incêndios urbanos, que o SGIF não cobre, e nos primeiros minutos de um incêndio rural, antes de ser registado. altitudeMediaM só aparece dias depois, quando o ICNF corre o geoprocessamento; classificacao e fonteAlerta estão lá desde o início. O enriquecimento nunca atrasa a rota: tem um orçamento de 4 segundos e o que o ICNF não servir a tempo sai a null, ficando disponível no pedido seguinte. Se o ICNF estiver em baixo, o pedido não falha — as ocorrências saem na mesma. Para a ficha completa de uma delas, /icnf/ocorrencia/{codigo}.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |
| `sgif` | query | não | 0 dispensa o bloco sgif, para quem prefira a resposta mais leve. Por omissão ele vem sempre. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/incendios"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "sgif": {
        "codigo": "20261243564",
        "classificacao": "fogacho",
        "fogacho": true,
        "fonteAlerta": "112",
        "altitudeMediaM": 135.54,
        "areaTotalHa": 0
      },
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 31,
    "cached": false,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "sgif": {
          "codigo": "20261243564",
          "classificacao": "fogacho",
          "fogacho": true,
          "fonteAlerta": "112",
          "altitudeMediaM": 135.54,
          "areaTotalHa": 0
        },
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/incendios/ativos

**Incêndios ativos**

O mesmo conjunto de /prociv/incendios, retirando os que já passaram a Em Conclusão.

> **Nota:** O bloco sgif cruza a ocorrência da ANEPC com o SGIF do ICNF pelo campo numero. Vem a null quando o ICNF não tem ficha — sempre nos incêndios urbanos, que o SGIF não cobre, e nos primeiros minutos de um incêndio rural, antes de ser registado. altitudeMediaM só aparece dias depois, quando o ICNF corre o geoprocessamento; classificacao e fonteAlerta estão lá desde o início. O enriquecimento nunca atrasa a rota: tem um orçamento de 4 segundos e o que o ICNF não servir a tempo sai a null, ficando disponível no pedido seguinte. Se o ICNF estiver em baixo, o pedido não falha — as ocorrências saem na mesma. Para a ficha completa de uma delas, /icnf/ocorrencia/{codigo}.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |
| `sgif` | query | não | 0 dispensa o bloco sgif, para quem prefira a resposta mais leve. Por omissão ele vem sempre. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/incendios/ativos"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "sgif": {
        "codigo": "20261243564",
        "classificacao": "fogacho",
        "fogacho": true,
        "fonteAlerta": "112",
        "altitudeMediaM": 135.54,
        "areaTotalHa": 0
      },
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 6,
    "cached": false,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "sgif": {
          "codigo": "20261243564",
          "classificacao": "fogacho",
          "fogacho": true,
          "fonteAlerta": "112",
          "altitudeMediaM": 135.54,
          "areaTotalHa": 0
        },
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/incendios/significativos

**Incêndios significativos**

O mesmo conjunto de /prociv/incendios, restrito ao código de importância 2 (Significativa) atribuído pela ANEPC.

> **Nota:** O bloco sgif cruza a ocorrência da ANEPC com o SGIF do ICNF pelo campo numero. Vem a null quando o ICNF não tem ficha — sempre nos incêndios urbanos, que o SGIF não cobre, e nos primeiros minutos de um incêndio rural, antes de ser registado. altitudeMediaM só aparece dias depois, quando o ICNF corre o geoprocessamento; classificacao e fonteAlerta estão lá desde o início. O enriquecimento nunca atrasa a rota: tem um orçamento de 4 segundos e o que o ICNF não servir a tempo sai a null, ficando disponível no pedido seguinte. Se o ICNF estiver em baixo, o pedido não falha — as ocorrências saem na mesma. Para a ficha completa de uma delas, /icnf/ocorrencia/{codigo}.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |
| `sgif` | query | não | 0 dispensa o bloco sgif, para quem prefira a resposta mais leve. Por omissão ele vem sempre. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/incendios/significativos"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "sgif": {
        "codigo": "20261243564",
        "classificacao": "fogacho",
        "fogacho": true,
        "fonteAlerta": "112",
        "altitudeMediaM": 135.54,
        "areaTotalHa": 0
      },
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 2,
    "cached": false,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "sgif": {
          "codigo": "20261243564",
          "classificacao": "fogacho",
          "fogacho": true,
          "fonteAlerta": "112",
          "altitudeMediaM": 135.54,
          "areaTotalHa": 0
        },
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/acidentes

**Acidentes rodoviários e ferroviários**

Ocorrências ativas classificadas como acidente — colisões, despistes e atropelamentos — usando exatamente a mesma classificação da categoria Acidentes do mapa público.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/acidentes"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 22,
    "cached": true,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/meteorologia/impactos

**Ocorrências de causa meteorológica**

Ocorrências ativas atribuíveis a condições meteorológicas — quedas de árvore por vento, inundações e cheias — usando exatamente a mesma classificação da categoria Naturais do mapa público. Útil para medir o impacto no terreno de um aviso do IPMA. Uma queda em altura não conta: só entram as quedas de causa meteorológica.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `format` | query | não | geojson devolve uma FeatureCollection com geometria [lng, lat] e o resto da ocorrência em properties. Omitido devolve o JSON padrão. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/meteorologia/impactos"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": [
    {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "fonte": "PROCIV"
    }
  ],
  "meta": {
    "total": 47,
    "cached": false,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

#### Resposta com `format=geojson`

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-8.5563, 37.3172]
      },
      "properties": {
        "id": 1243,
        "objectId": 8814231,
        "numero": 1243,
        "ano": 2026,
        "tipo": "Incêndio",
        "natureza": "Incêndio Rural - Mato",
        "familia": "Incêndios Rurais",
        "especie": "Mato",
        "codNatureza": 3103,
        "idFamilia": 3,
        "grupoOcorrencia": "Incêndios Rurais",
        "estado": "Em Curso",
        "estadoAgrupado": "Em Curso",
        "codEstado": 5,
        "faseIncendio": "Combate",
        "importancia": "Significativa",
        "codImportancia": 2,
        "distrito": "Faro",
        "codDistrito": 8,
        "concelho": "Monchique",
        "codConcelho": 806,
        "freguesia": "Monchique",
        "localidade": "Alferce",
        "endereco": "EN266, km 12",
        "dataOcorrencia": "2026-08-02T09:14:00.000Z",
        "dataAtualizacao": "2026-08-02T11:42:00.000Z",
        "hora": "10:14",
        "duracao": "02:28",
        "duracaoMinutos": 148,
        "meios": { "operacionais": 420, "terrestres": 125, "aereos": 4, "aquaticos": 0 },
        "recursosHumanos": {
          "bombeiros": 386,
          "gnr": 18,
          "psp": 0,
          "inem": 6,
          "forcasArmadas": 0,
          "outros": 10,
          "total": 420
        },
        "meiosAereos": { "total": 4, "OPAereos": 12 },
        "entidadeResponsavel": "CDOS Faro",
        "quantEntidades": 7,
        "ultimoPosit": "Frente ativa em resolução no flanco norte.",
        "fonte": "PROCIV"
      }
    }
  ],
  "metadata": {
    "total": 1,
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "PROCIV"
  }
}
```

### GET /prociv/meios

**Meios mobilizados (agregado)**

Totais nacionais de operacionais e de meios terrestres, aéreos e aquáticos em operação, com desagregação por entidade e a lista das ocorrências que têm meios atribuídos.

#### Parâmetros

Sem parâmetros.

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/meios"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": {
    "totalOperacionais": 2841,
    "totalMeiosTerrestres": 861,
    "totalMeiosAereos": 7,
    "totalMeiosAquaticos": 2,
    "recursosHumanos": {
      "bombeiros": 2503,
      "gnr": 174,
      "psp": 46,
      "inem": 62,
      "forcasArmadas": 12,
      "outros": 44,
      "total": 2841
    },
    "meiosAereos": { "total": 7, "OPAereos": 21 },
    "porOcorrencia": [
      {
        "id": 1243,
        "natureza": "Incêndio Rural - Mato",
        "distrito": "Faro",
        "meios": {
          "operacionais": 420,
          "terrestres": 125,
          "aereos": 4,
          "aquaticos": 0
        }
      }
    ],
    "timestamp": "2026-08-02T11:42:20.000Z"
  },
  "meta": { "cached": false, "fonte": "PROCIV" }
}
```

### GET /prociv/estatisticas

**Estatísticas globais**

Contagens agregadas por estado, por importância e por distrito, para painéis de vista geral.

#### Parâmetros

Sem parâmetros.

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/estatisticas"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": {
    "total": 121,
    "porEstado": {
      "Em Curso": 64,
      "Em Resolução": 38,
      "Em Conclusão": 19
    },
    "porImportancia": {
      "Normal": 112,
      "Significativa": 7,
      "Grave": 2
    },
    "porDistrito": {
      "Lisboa": 18,
      "Porto": 15,
      "Faro": 11
    },
    "porTipo": {
      "Incêndio": 47,
      "Acidente": 33,
      "Assistência": 41
    },
    "meiosTotais": {
      "operacionais": 2841,
      "terrestres": 861,
      "aereos": 7,
      "aquaticos": 2
    },
    "timestamp": "2026-08-02T11:42:20.000Z"
  },
  "meta": { "cached": false, "fonte": "PROCIV" }
}
```

### GET /prociv/distritos

**Tabela de distritos**

Dados de referência: as 29 unidades territoriais usadas pela ANEPC — os 18 distritos do Continente mais as ilhas da Madeira e dos Açores — com código oficial e capital. Estáticos: recomenda-se guardar localmente em vez de consultar a cada pedido.

#### Parâmetros

Sem parâmetros.

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/distritos"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": {
    "distritos": [
      { "codigo": 1, "nome": "Aveiro", "capital": "Aveiro" },
      { "codigo": 11, "nome": "Lisboa", "capital": "Lisboa" },
      { "codigo": 31, "nome": "Ilha da Madeira", "capital": "Funchal" },
      { "codigo": 42, "nome": "Ilha de São Miguel", "capital": "Ponta Delgada" }
    ],
    "total": 29,
    "nota": "Use o código ou nome do distrito para filtrar ocorrências em /api/prociv/ocorrencias/distrito/:identificador"
  },
  "meta": {
    "timestamp": "2026-08-02T11:42:20.000Z",
    "fonte": "INE/PROCIV"
  }
}
```

### SSE /prociv/ocorrencias/stream

**Notificação de alteração (SSE)**

Canal Server-Sent Events que emite um evento update assim que o feed da ANEPC muda — nova ocorrência, mudança de estado ou alteração de meios. Serve para dispensar polling: ao receber o evento, o cliente relê o endpoint que lhe interessa. A ligação é reciclada ao fim de 4 minutos e o cliente reconecta automaticamente.

> BETA

> **Nota:** Em beta e sujeito a pedido específico: não é ativado com a chave padrão. Indique a necessidade no formulário de acesso e a chave será autorizada para este endpoint. A interface pode mudar sem aviso enquanto estiver em beta. Máximo de 3 ligações simultâneas por IP — cada ligação ocupa um recurso do servidor durante todo o seu tempo de vida, e o evento indica apenas que houve alteração, não transporta os dados.

#### Parâmetros

Sem parâmetros.

#### Pedido

```bash
curl -N -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/prociv/ocorrencias/stream"
```

#### Resposta (200)

```text
retry: 3000
event: hello
data: {"at":1785312000000}

: keep-alive 1785312025000

event: update
data: {"at":1785312060000}
```

## Deteção e risco de incêndio

_Fontes: NASA FIRMS · EFFIS (Copernicus) · ICNF · IPMA · redes ADS-B_

### GET /fires/hotspots

**Focos de calor por satélite**

Deteções térmicas sobre Portugal nas últimas 48 horas (NASA FIRMS, VIIRS 375 m), em GeoJSON. Um foco de calor é uma anomalia térmica detetada por satélite, não uma ocorrência confirmada.

#### Parâmetros

Sem parâmetros.

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/fires/hotspots"
```

#### Resposta (200)

```json
{
  "success": true,
  "updatedAt": 1785312120,
  "count": 2,
  "geojson": {
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "geometry": { "type": "Point", "coordinates": [-8.1983, 39.4621] },
        "properties": {
          "frp": 42.6,
          "brightness": 331.7,
          "acqAt": 1785312000,
          "satellite": "VIIRS_SNPP_NRT",
          "confidence": "high",
          "daynight": "day"
        }
      }
    ]
  }
}
```

### GET /fires/early-detection

**Deteção precoce**

Cruza focos de calor recentes com as ocorrências já declaradas e isola as deteções térmicas sem ocorrência correspondente — candidatas a ignições ainda não reportadas. Indicativo: exige validação antes de qualquer uso operacional.

#### Parâmetros

Sem parâmetros.

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/fires/early-detection"
```

#### Resposta (200)

```json
{
  "success": true,
  "fetchedAt": "2026-08-02T09:45:00.000Z",
  "clusters": [
    {
      "lat": 39.84121,
      "lng": -7.99312,
      "detections": 4,
      "maxFrp": 18.4,
      "lastDetectionAt": "2026-08-02T09:31:00.000Z",
      "nearestIncidentKm": 34.2
    }
  ]
}
```

### GET /fires/burnt-area

**Área ardida de uma ocorrência**

Cruza a localização de uma ocorrência com os perímetros oficiais do EFFIS. Se ainda não houver perímetro publicado, devolve uma estimativa por satélite, devidamente assinalada na resposta.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `lat` | query | sim | Latitude da ocorrência. |
| `lng` | query | sim | Longitude da ocorrência. |
| `incidentId` | query | não | Id da ocorrência. Quando indicado, a resposta inclui history com a evolução registada da área. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/fires/burnt-area?lat=39.4621&lng=-8.1983&incidentId=1243"
```

#### Resposta (200)

```json
{
  "success": true,
  "found": true,
  "source": "EFFIS · Copernicus EMS",
  "burntArea": {
    "id": 48213,
    "estimate": false,
    "archived": false,
    "areaHa": 412.6,
    "firedate": "2026-07-30T14:20:00",
    "lastupdate": "2026-08-02T06:00:00",
    "commune": "Abrantes",
    "province": "Santarém",
    "containsPoint": true,
    "distanceKm": 0,
    "geometry": {
      "type": "MultiPolygon",
      "coordinates": [[[[-8.2011, 39.4602], [-8.1954, 39.4640]]]]
    },
    "history": [
      { "t": 1785205200, "areaHa": 180.2, "source": "viirs-estimate" },
      { "t": 1785312000, "areaHa": 412.6, "source": "effis" }
    ],
    "nextSatellitePass": "2026-08-02T13:20:00.000Z"
  }
}
```

### GET /fires/aircraft

**Meios aéreos em voo**

Aviões e helicópteros de combate a incêndios em voo nas proximidades de um ponto, identificados a partir de redes ADS-B abertas. A cobertura ADS-B é irregular em zonas de interior e a baixa altitude.

> **Nota:** Serviço apoiado em infraestrutura comunitária gratuita. Disponibilidade best-effort e sem garantia de latência; para uso intensivo é necessário acordo prévio.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `lat` | query | sim | Latitude do centro de busca. |
| `lng` | query | sim | Longitude do centro de busca. |
| `radius` | query | não | Raio de busca em quilómetros. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/fires/aircraft?lat=39.47&lng=-8.19&radius=25"
```

#### Resposta (200)

```json
{
  "success": true,
  "fetchedAt": "2026-08-02T11:42:10.000Z",
  "sources": ["adsb.fi", "opensky"],
  "aircraft": [
    {
      "hex": "4951d8",
      "callsign": "EPT23",
      "registration": "CS-AVB",
      "type": "AT8T",
      "operator": "Everjets",
      "typeName": "Air Tractor AT-802",
      "kind": "plane",
      "role": "firefighting",
      "lat": 39.4712,
      "lng": -8.1904,
      "altFt": 1250,
      "onGround": false,
      "groundSpeedKt": 118,
      "track": 214,
      "distanceKm": 1.2,
      "seenS": 4,
      "sources": ["adsb.fi"]
    }
  ]
}
```

### GET /fires/risk-analysis

**Análise de risco de incêndio**

Índice compósito de 0 a 100 para um ponto, combinando o risco conjuntural de incêndio do IPMA com a atividade térmica recente detetada por satélite. É um indicador derivado do EmCurso, não um índice oficial.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `lat` | query | sim | Latitude do ponto. |
| `lng` | query | sim | Longitude do ponto. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/fires/risk-analysis?lat=39.4621&lng=-8.1983"
```

#### Resposta (200)

```json
{
  "success": true,
  "score": 68,
  "level": "Elevado",
  "color": "#f97316",
  "summary": "Risco elevado — pesa sobretudo o índice de risco IPMA e a atividade térmica na zona.",
  "factors": [
    {
      "key": "rcm",
      "label": "Risco conjuntural IPMA",
      "detail": "Classe 4 (Muito Elevado) para o concelho.",
      "contribution": 32,
      "max": 40
    },
    {
      "key": "hotspots",
      "label": "Atividade térmica recente",
      "detail": "9 deteções VIIRS num raio de 10 km nas últimas 24 h.",
      "contribution": 21,
      "max": 30
    }
  ],
  "rcm": {
    "value": 4,
    "label": "Muito Elevado",
    "dataPrev": "2026-08-02"
  },
  "updatedAt": "2026-08-02T11:40:00.000Z"
}
```

### GET /icnf/burnt-area

**Área ardida e causas (ICNF)**

Dados oficiais do ICNF: área ardida por ano, causa e distrito, ano corrente ao dia via SGIF, e série anual desde 1975. O detalhe varia com o ano — causas, distritos e coberto existem de 2014 em diante.

> **Nota:** A cartografia do ICNF não tem o mesmo detalhe em todos os anos, e o pedido nunca falha por isso: os campos que a fonte não publica vêm a null e são nomeados em unavailable, com HTTP 200. Causas (groupBy=causa), distritos (groupBy=distrito) e coberto só existem de 2014 em diante; 2010 é publicado sem área, logo totalHa vem a null; e 1989 não tem um único registo. Antes de 2009 os anos vêm das décadas agrupadas de series=annual.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `year` | query | não | Ano a consultar; omitido devolve o mais recente. |
| `groupBy` | query | não | causa ou distrito. Só de 2014 em diante. |
| `full` | query | não | 1 devolve o ano completo num pedido: total, causas, distritos e coberto. |
| `coverage` | query | não | 1 devolve a área por coberto (povoamento, mato, agrícola). Só de 2014 em diante. |
| `series` | query | não | annual devolve a série ano a ano mais as décadas agrupadas. |
| `criticos` | query | não | 1 devolve os locais críticos com mais ocorrências nos últimos 15 dias. |
| `sgif` | query | não | 1 devolve o ano corrente ao dia. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/icnf/burnt-area?groupBy=causa"
```

#### Resposta (200)

```json
{
  "success": true,
  "year": 2025,
  "totalHa": 272453,
  "totalCount": 2084,
  "groups": [
    { "key": "Negligente", "areaHa": 61930, "count": 2401 },
    { "key": "Desconhecida", "areaHa": 29817, "count": 903 }
  ],
  "unavailable": []
}
```

### GET /icnf/ocorrencia/{codigo}

**Ficha SGIF de uma ocorrência**

Ficha completa de uma ocorrência no SGIF do ICNF: classificação (fogacho, incêndio, agrícola), fonte de alerta, terreno, meteorologia no momento da ignição, índices FWI, cronologia, causa apurada e áreas por coberto. O código é o mesmo numero que a ANEPC publica em /prociv/incendios, por isso saltar de uma lista para a ficha não exige conversão nenhuma.

> NOVO

> **Nota:** O SGIF cobre apenas incêndios RURAIS: uma ocorrência urbana devolve 404, e isso é resposta correta, não avaria. Nas ocorrências recentes o terreno (altitudeMediaM, decliveMedio) e os índices FWI vêm a null — o ICNF só os calcula dias depois, por geoprocessamento; a classificação e a fonte de alerta estão lá desde o início. As datas são hora local de Portugal continental, sem sufixo de fuso, tal como a fonte as publica. duracaoMin é passado tal e qual: o SGIF publica valores negativos e absurdos nalguns registos.

#### Índices FWI

- `ffmc` — Secura dos combustíveis finos à superfície — mede a facilidade de ignição.
- `dmc` — Secura da camada orgânica intermédia.
- `dc` — Secura da camada profunda — a seca acumulada da época.
- `isi` — Velocidade de propagação esperada (combina ffmc com o vento).
- `bui` — Combustível disponível para arder (combina dmc com dc).
- `fwi` — Intensidade esperada da frente de fogo — o número-resumo.
- `dsr` — O mesmo que fwi, numa escala que se pode somar ou comparar entre dias.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `codigo` | path | sim | Código de 11 dígitos (ano + sequência), ex. 20261243564. É o campo numero das rotas /prociv. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/icnf/ocorrencia/20261243564"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": {
    "codigo": "20261243564",
    "ano": 2026,
    "tipo": "Florestal",
    "classificacao": "fogacho",
    "fogacho": true,
    "incendio": false,
    "agricola": false,
    "reacendimentos": 0,
    "fonteAlerta": "112",
    "localizacao": {
      "distrito": "Coimbra",
      "concelho": "Penacova",
      "freguesia": "Friúmes",
      "local": "Serra da Atalhada (IP3 Km 63)",
      "ine": "61303",
      "lat": 40.286558,
      "lng": -8.260586,
      "x": 189160,
      "y": 368660
    },
    "cronologia": {
      "alerta": "2026-09-01T17:06:00",
      "primeiraIntervencao": "2026-09-01T17:21:00",
      "extincao": null,
      "duracaoMin": null
    },
    "areas": { "totalHa": 0, "povoamentoHa": 0, "matoHa": 0, "agricolaHa": 0, "hectaresPorHora": 0 },
    "causa": null,
    "terreno": { "altitudeMediaM": 135.54, "decliveMedio": 35.74, "horasExposicaoSolar": 10.64 },
    "meteo": { "zona": "Interior Centro - Beiras Interiores", "temperaturaC": 26.58, "humidadeRelativaPct": 49.59, "ventoKmh": 15.49, "precipitacaoMm": 0 },
    "fwi": { "ffmc": null, "dmc": null, "dc": null, "isi": null, "bui": null, "fwi": null, "dsr": null }
  },
  "meta": { "timestamp": "2026-09-01T17:30:00.000Z", "fonte": "ICNF/SGIF" }
}
```

### GET /ipma/fire-risk

**Risco conjuntural de incêndio (RCM)**

Índice oficial de risco de incêndio rural do IPMA, em classes de 1 a 5, por concelho, para hoje ou amanhã.

> **Nota:** Sem lat e lng, a resposta é o documento completo: { success, day, dataPrev, total, levels, data } em que data é a lista de células { dico, rcm, lat, lng } de todos os concelhos.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `lat` | query | não | Latitude — devolve o risco do concelho mais próximo. |
| `lng` | query | não | Longitude — devolve o risco do concelho mais próximo. |
| `day` | query | não | 0 = hoje, 1 = amanhã. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/ipma/fire-risk?lat=39.4621&lng=-8.1983"
```

#### Resposta (200)

```json
{
  "success": true,
  "day": 0,
  "dataPrev": "2026-08-02",
  "dico": "1402",
  "rcm": 4,
  "level": { "label": "Muito Elevado", "color": "#ef4444" }
}
```

## Meteorologia

_Fonte: IPMA · avisos e previsão_

### GET /ipma/warnings

**Avisos meteorológicos**

Avisos meteorológicos por área, nos níveis amarelo, laranja e vermelho, com início, fim e descrição oficial do IPMA.

> **Nota:** Com region ou type, a resposta troca activeOnly e metadata por region/regionName ou type. Com stats=true devolve apenas as contagens agregadas.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `active` | query | não | true devolve apenas avisos em vigor. |
| `region` | query | não | Código de área IPMA, ex.: LSB, PTO, FAR. |
| `type` | query | não | Tipo de aviso, ex.: Vento, Precipitação. |
| `stats` | query | não | true devolve apenas contagens agregadas por nível. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/ipma/warnings?active=true"
```

#### Resposta (200)

```json
{
  "success": true,
  "activeOnly": true,
  "count": 2,
  "warnings": [
    {
      "id": "LSB-Tempo Quente-2026-07-31T23:00:00",
      "type": "Tempo Quente",
      "typeName": "Tempo Quente",
      "level": "orange",
      "levelName": "Laranja",
      "levelColor": "#f97316",
      "region": "LSB",
      "regionName": "Lisboa",
      "description": "Persistência de valores elevados da temperatura máxima.",
      "startTime": "2026-07-31T23:00:00.000Z",
      "endTime": "2026-08-04T22:59:00.000Z",
      "isActive": true
    }
  ],
  "metadata": {
    "regions": { "LSB": "Lisboa", "PTO": "Porto", "FAR": "Faro" },
    "types": ["Tempo Quente", "Tempo Frio", "Precipitação", "Vento"]
  }
}
```

### GET /ipma/forecast

**Previsão por cidade**

Previsão diária do IPMA para as capitais de distrito, com temperaturas mínima e máxima, probabilidade de precipitação e vento.

> **Nota:** Sem processed=true, data traz os campos crus do IPMA (tMin, tMax, precipitaProb, idWeatherType, classWindSpeed, predWindDir) como strings, e a resposta inclui owner, country e dataUpdate.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `city` | query | sim | Nome da cidade, ex.: Lisboa, Porto, Faro. |
| `day` | query | não | 0, 1 ou 2 — dia da previsão (0 = hoje). |
| `processed` | query | não | true devolve descrições legíveis em vez de códigos numéricos. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/ipma/forecast?city=Lisboa&processed=true"
```

#### Resposta (200)

```json
{
  "success": true,
  "city": "Lisboa",
  "globalIdLocal": 1110600,
  "data": [
    {
      "date": "2026-08-02",
      "dayOfWeek": "Domingo",
      "tempMin": 19,
      "tempMax": 38,
      "precipitationProb": 0,
      "windDirection": "N",
      "windSpeedClass": 2,
      "windSpeedDescription": "Fraco",
      "weatherType": 1,
      "weatherDescription": "Céu limpo",
      "weatherIcon": "☀️"
    }
  ]
}
```

## Contexto e histórico

_Trânsito TomTom, meteorologia IPMA e histórico próprio, por ocorrência_

### GET /context

**Contexto operacional de uma ocorrência**

Para um ponto e uma natureza de ocorrência, devolve os constrangimentos de trânsito num raio de 1 km — cortes e congestionamento — e a meteorologia local com os avisos ativos do distrito. A relevância de cada bloco é determinada pela natureza indicada.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `lat` | query | sim | Latitude da ocorrência (WGS84). |
| `lng` | query | sim | Longitude da ocorrência (WGS84). |
| `natureza` | query | não | Natureza da ocorrência — determina a relevância de trânsito e meteorologia. |
| `idFamilia` | query | não | Família ANEPC: 1 natural, 2 tecnológica, 3 mista. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/context?lat=38.7223&lng=-9.1393&natureza=Colis%C3%A3o&idFamilia=2"
```

#### Resposta (200)

```json
{
  "success": true,
  "relevance": { "traffic": true, "weather": false },
  "district": "Lisboa",
  "traffic": {
    "relevant": true,
    "summary": "Foram detetados constrangimentos de trânsito na zona.",
    "radiusKm": 1,
    "totalNearby": 3,
    "hasConstraints": true,
    "counts": {
      "closure": 1,
      "works": 0,
      "jam": 1,
      "accident": 1,
      "breakdown": 0
    },
    "items": [
      {
        "id": "PT-A5-2026080211",
        "categoryCode": 8,
        "categoryLabel": "Estrada cortada",
        "road": "A5",
        "from": "Nó de Carnaxide",
        "to": "Nó de Miraflores",
        "delayMinutes": 6,
        "distanceKm": 0.3,
        "confidence": 0.82,
        "startTime": "2026-08-02T10:58:00Z"
      }
    ]
  },
  "weather": null,
  "errors": []
}
```

### GET /incidents/history/{id}

**Histórico de uma ocorrência**

Última captura arquivada de uma ocorrência já encerrada, com o mesmo formato de incident (meios, recursosHumanos, meiosAereos) que /prociv/ocorrencias/todas devolve — deliberadamente: não há um segundo formato para uma ocorrência arquivada. Inclui também timeline, a cronologia completa de estados por que passou, com o instante de cada transição. historical e endedAt dizem explicitamente que a ocorrência já terminou e quando, em vez de obrigar quem chama a inferir isso do incident.estado — que pode ainda ler "Em Curso" se o cron nunca chegou a captar a transição para "Em Conclusão" antes de a ocorrência sair do feed. Serve para consultar ocorrências que já saíram do feed ao vivo da ANEPC. Quando não há registo, a resposta é 200 com found: false.

> **Nota:** incident é gerado pelo mesmo normalizador que a via ao vivo — os campos são exatamente os de OCORRENCIA. historical vem sempre true neste endpoint (só devolve o que já saiu do feed ao vivo — prova suficiente de que terminou, seja qual for o último estado registado). endedAt é sempre o instante da última entrada de timeline, não uma procura por um estado "de conclusão": a ANEPC nem sempre transita a ocorrência por Em Conclusão/Concluída antes de a deixar cair do feed, por isso exigir essa palavra-chave deixaria exatamente essas de fora. Sem nenhuma entrada em timeline, cai para o instante da última captura conhecida. timeline vem vazio quando ainda não há transições registadas para a ocorrência.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `id` | path | sim | Identificador interno da ocorrência (ex.: 46642307). Aceita em alternativa o número oficial da ANEPC (ex.: 20261089809) — este já inclui o ano nos primeiros dígitos, não é para concatenar nada à parte. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/incidents/history/46642307"
```

#### Resposta (200)

```json
{
  "success": true,
  "found": true,
  "source": "history",
  "historical": true,
  "endedAt": "2026-08-02T11:42:00.000Z",
  "incident": {
      "id": 1243,
      "objectId": 8814231,
      "numero": 1243,
      "ano": 2026,
      "tipo": "Incêndio",
      "natureza": "Incêndio Rural - Mato",
      "familia": "Incêndios Rurais",
      "especie": "Mato",
      "codNatureza": 3103,
      "idFamilia": 3,
      "grupoOcorrencia": "Incêndios Rurais",
      "estado": "Em Curso",
      "estadoAgrupado": "Em Curso",
      "codEstado": 5,
      "faseIncendio": "Combate",
      "importancia": "Significativa",
      "codImportancia": 2,
      "distrito": "Faro",
      "codDistrito": 8,
      "concelho": "Monchique",
      "codConcelho": 806,
      "freguesia": "Monchique",
      "localidade": "Alferce",
      "endereco": "EN266, km 12",
      "localizacao": { "lat": 37.3172, "lng": -8.5563 },
      "dataOcorrencia": "2026-08-02T09:14:00.000Z",
      "dataAtualizacao": "2026-08-02T11:42:00.000Z",
      "hora": "10:14",
      "duracao": "02:28",
      "duracaoMinutos": 148,
      "meios": {
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "aquaticos": 0
      },
      "recursosHumanos": {
        "bombeiros": 386,
        "gnr": 18,
        "psp": 0,
        "inem": 6,
        "forcasArmadas": 0,
        "outros": 10,
        "total": 420
      },
      "meiosAereos": { "total": 4, "OPAereos": 12 },
      "entidadeResponsavel": "CDOS Faro",
      "quantEntidades": 7,
      "ultimoPosit": "Frente ativa em resolução no flanco norte.",
      "fonte": "PROCIV"
    },
  "timeline": [
    { "estado": "Em Despacho", "t": 1785308400 },
    { "estado": "Em Curso", "t": 1785309120 },
    { "estado": "Em Resolução", "t": 1785320400 },
    { "estado": "Em Conclusão", "t": 1785325320 }
  ]
}
```

### GET /incidents/status-timeline

**Cronologia de estado**

Sequência de estados por que uma ocorrência passou — Em Despacho, Em Curso, Em Resolução, Em Conclusão, e o que se seguir depois disso (Concluída, Vigilância, …) — com o instante de cada transição. historical e endedAt refletem sempre a última transição registada, sem tentar adivinhar se é ou não uma palavra de conclusão: a ANEPC nem sempre fecha uma ocorrência através de um estado de conclusão explícito. Aceita id, ou numero em alternativa — um dos dois, não é preciso indicar os dois.

> **Nota:** historical e endedAt refletem sempre a última entrada de timeline nesta mesma resposta — não uma procura por um estado "de conclusão". Note o exemplo: Vigilância vem depois de Em Conclusão, e é essa a entrada usada, por ser a mais recente. Sem nenhuma transição registada, historical vem false e endedAt vem null. Ao contrário de /incidents/history, onde o facto de a ocorrência ter saído do feed ao vivo já prova que terminou, aqui não há essa garantia: uma ocorrência ainda ativa, com transições registadas, também devolve historical: true — o campo diz "há uma última transição conhecida e é esta", não "a ocorrência já não está em curso".

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `id` | query | não | Identificador da ocorrência. Obrigatório apenas se numero não for indicado. |
| `numero` | query | não | Número oficial da ANEPC (ex.: 20261089809, já inclui o ano). Alternativa a id — resolve a ocorrência sozinho, sem mais nenhum parâmetro. |
| `ano` | query | não | Filtro extra opcional a acompanhar numero. Nunca obrigatório: numero já é suficiente sozinho. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/incidents/status-timeline?numero=20261089809"
```

#### Resposta (200)

```json
{
  "success": true,
  "historical": true,
  "endedAt": "2026-08-02T19:34:37.000Z",
  "timeline": [
    { "estado": "Despacho de 1º Alerta", "t": 1785694118 },
    { "estado": "Em Curso", "t": 1785694851 },
    { "estado": "Em Resolução", "t": 1785695464 },
    { "estado": "Em Conclusão", "t": 1785696519 },
    { "estado": "Vigilância", "t": 1785699277 }
  ]
}
```

### GET /stats/period-comparison

**Comparação de períodos**

Compara as ocorrências de um período com o período anterior de igual duração: totais, evolução diária, distritos e categorias.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `start` | query | não | Data de início (YYYY-MM-DD). |
| `end` | query | não | Data de fim (YYYY-MM-DD). |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/stats/period-comparison?start=2026-07-25&end=2026-08-01"
```

#### Resposta (200)

```json
{
  "success": true,
  "data": {
    "currentMetrics": {
      "total": 3556,
      "active": 121,
      "totalOperacionais": 41208,
      "totalTerrestres": 12904,
      "totalAereos": 214,
      "avgDuration": 96,
      "incendios": 612,
      "acidentes": 883,
      "significativas": 47,
      "riscoElevado": 12
    },
    "previousMetrics": {
      "total": 2506,
      "active": 98,
      "totalOperacionais": 30117,
      "totalTerrestres": 9822,
      "totalAereos": 151,
      "avgDuration": 88,
      "incendios": 480,
      "acidentes": 741,
      "significativas": 31,
      "riscoElevado": 7
    },
    "dailyData": [
      { "date": "2026-07-25", "total": 470, "incendios": 82, "acidentes": 118, "outros": 270 }
    ],
    "hourlyData": [{ "hour": "14", "count": 288 }],
    "districtRankings": [
      { "name": "Lisboa", "count": 512, "operacionais": 4890, "aereos": 8 }
    ],
    "categoryData": [{ "name": "Incêndios", "value": 612 }],
    "typeData": [{ "name": "Incêndio Rural - Mato", "value": 244 }],
    "responseAnalysis": { "avg": 96, "min": 4, "max": 2140, "median": 61 },
    "peakAnalysis": {
      "busiestDay": { "date": "2026-07-29", "count": 688 },
      "busiestHour": { "hour": 14, "count": 288 },
      "busiestDistrict": { "name": "Lisboa", "count": 512 }
    },
    "topIncidents": [
      {
        "id": 1243,
        "natureza": "Incêndio Rural - Mato",
        "distrito": "Faro",
        "concelho": "Monchique",
        "operacionais": 420,
        "terrestres": 125,
        "aereos": 4,
        "data": "2026-08-02"
      }
    ],
    "periodStart": "2026-07-25",
    "periodEnd": "2026-08-01"
  }
}
```

## Geografia e trânsito

_Fontes: TomTom · Open-Meteo · OpenStreetMap · Nominatim · OSRM_

### GET /traffic/incidents

**Incidentes de trânsito**

Cortes de estrada, obras e congestionamento reportados pela TomTom, numa área delimitada. Sem bbox, cobre Portugal Continental.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `bbox` | query | não | minLng,minLat,maxLng,maxLat. |
| `categories` | query | não | Códigos de categoria TomTom, ex.: 7,8,9. |
| `language` | query | não | Idioma das descrições, ex.: pt-PT. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/traffic/incidents?bbox=-9.3,38.6,-9.0,38.8"
```

#### Resposta (200)

```json
{
  "success": true,
  "regionsQueried": 1,
  "count": 42,
  "incidents": [
    {
      "id": "PT-A5-2026080211",
      "category": "Road closed",
      "categoryCode": 8,
      "categoryLabel": "Estrada cortada",
      "categoryIcon": "🚧",
      "from": "Nó de Carnaxide",
      "to": "Nó de Miraflores",
      "description": "Estrada cortada devido a acidente",
      "delay": 6,
      "length": 1840,
      "magnitudeOfDelay": 3,
      "startTime": "2026-08-02T10:58:00Z",
      "endTime": null,
      "roadNumbers": ["A5"],
      "confidence": 85,
      "confidenceLabel": "probable",
      "numberOfReports": 4,
      "lastReportTime": "2026-08-02T11:35:00Z",
      "geometry": {
        "type": "LineString",
        "coordinates": [[-9.2381, 38.7154], [-9.2204, 38.7132]]
      },
      "coordinates": [[-9.2381, 38.7154], [-9.2204, 38.7132]]
    }
  ]
}
```

### GET /traffic/geocode

**Geocodificação e geocodificação inversa**

Converte coordenadas em cidade e distrito, ou uma morada em coordenadas. Com lat e lng faz o sentido inverso; com street, city ou district faz o direto.

> **Nota:** Apoiado no Nominatim (OpenStreetMap), cuja política de utilização proíbe geocodificação em massa. Destina-se a consultas pontuais no contexto de uma ocorrência; para volume, use um serviço de geocodificação próprio.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `lat` | query | não | Latitude, para geocodificação inversa. |
| `lng` | query | não | Longitude, para geocodificação inversa. |
| `street` | query | não | Rua, para geocodificação direta. |
| `city` | query | não | Cidade, para geocodificação direta. |
| `district` | query | não | Distrito, para geocodificação direta. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/traffic/geocode?lat=38.7223&lng=-9.1393"
```

#### Resposta (200)

```json
{
  "success": true,
  "city": "Lisboa",
  "district": "Lisboa",
  "displayName": "Praça do Comércio, Santa Maria Maior, Lisboa, Portugal",
  "lat": 38.7223,
  "lng": -9.1393
}
```

### GET /geo/route

**Rota entre dois pontos**

Rota rodoviária real, com distância e duração, usada para estimar tempos de resposta a partir dos meios mais próximos.

> **Nota:** Apoiado no servidor de demonstração público do OSRM, partilhado pela comunidade e sem garantia de serviço. Percursos longos são recusados. Para uso em produção, alojar uma instância própria de OSRM.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `fromLat` | query | sim | Latitude de origem. |
| `fromLng` | query | sim | Longitude de origem. |
| `toLat` | query | sim | Latitude de destino. |
| `toLng` | query | sim | Longitude de destino. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/geo/route?fromLat=39.46&fromLng=-8.20&toLat=39.47&toLng=-8.21"
```

#### Resposta (200)

```json
{
  "success": true,
  "distanceKm": 6.4,
  "durationMin": 8.9,
  "geometry": {
    "type": "LineString",
    "coordinates": [[-8.20014, 39.46012], [-8.20512, 39.46498], [-8.21003, 39.47004]]
  }
}
```

### GET /geo/wind

**Vento num ponto**

Velocidade, rajada e direção do vento num ponto, para estimar a direção provável de propagação de um incêndio.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `lat` | query | sim | Latitude do ponto. |
| `lng` | query | sim | Longitude do ponto. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/geo/wind?lat=39.4621&lng=-8.1983"
```

#### Resposta (200)

```json
{
  "success": true,
  "windKmh": 18.4,
  "gustKmh": 32.1,
  "directionFromDeg": 315,
  "directionToDeg": 135,
  "cardinalFrom": "NO",
  "cardinalTo": "SE",
  "fetchedAt": "2026-08-02T11:40:00.000Z"
}
```

### GET /geo/entidades

**Meios de socorro próximos**

Quartéis de bombeiros e postos das forças de segurança mais próximos de um ponto, a partir do OpenStreetMap. A completude depende do que estiver mapeado localmente.

> **Nota:** Serviço apoiado em infraestrutura comunitária gratuita. Disponibilidade best-effort e sem garantia de latência; para uso intensivo é necessário acordo prévio.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `lat` | query | sim | Latitude do centro de busca. |
| `lng` | query | sim | Longitude do centro de busca. |
| `radius` | query | não | Raio de busca em km, máximo 50. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/geo/entidades?lat=39.4621&lng=-8.1983&radius=15"
```

#### Resposta (200)

```json
{
  "success": true,
  "count": 2,
  "source": "OpenStreetMap · Overpass API",
  "facilities": [
    {
      "id": "node/1284471902",
      "kind": "fire",
      "force": null,
      "name": "Corpo de Bombeiros Voluntários de Abrantes",
      "operator": "Associação Humanitária dos Bombeiros Voluntários de Abrantes",
      "lat": 39.46512,
      "lng": -8.19714,
      "distanceKm": 0.8,
      "tags": {
        "amenity": "fire_station",
        "name": "Corpo de Bombeiros Voluntários de Abrantes"
      }
    }
  ]
}
```

### GET /geo/municipality-boundary

**Limites administrativos**

Geometria GeoJSON do limite administrativo de um concelho ou distrito, para desenhar no mapa. Dados estáveis: recomenda-se cache do lado do cliente.

> **Nota:** Serviço apoiado em infraestrutura comunitária gratuita. Disponibilidade best-effort e sem garantia de latência; para uso intensivo é necessário acordo prévio.

#### Parâmetros

| Parâmetro | Em | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `district` | query | não | Nome do distrito. |
| `municipality` | query | não | Nome do concelho. |

#### Pedido

```bash
curl -H "Authorization: Bearer $EMCURSO_KEY" "https://api.emcurso.pt/geo/municipality-boundary?municipality=Abrantes&district=Santar%C3%A9m"
```

#### Resposta (200)

```json
{
  "success": true,
  "found": true,
  "municipality": "Abrantes",
  "district": "Santarém",
  "bbox": [-8.4021, 39.2841, -7.9014, 39.6012],
  "geometry": {
    "type": "Polygon",
    "coordinates": [[[-8.4021, 39.2841], [-7.9014, 39.3104], [-8.0122, 39.6012], [-8.4021, 39.2841]]]
  }
}
```
