curl --request GET \
--url https://gdeltcloud.com/api/v2/maritime/port-pulse \
--header 'Authorization: Bearer <token>'import requests
url = "https://gdeltcloud.com/api/v2/maritime/port-pulse"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://gdeltcloud.com/api/v2/maritime/port-pulse', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"success": true,
"data": [
{
"port_id": "UAODS",
"name": "Odesa",
"unlocode": "UAODS",
"country": "UKR",
"country_name": "Ukraine",
"lat": 46.49,
"lon": 30.74,
"harbor_size": "Medium",
"lng_terminal": false,
"oil_terminal": true,
"relevant_events": 37,
"conflict_events": 12,
"events_last_7d": 9,
"anomaly_ratio": 1.35,
"energy_exposure": {
"assets_nearby": 2,
"state_owned": 1,
"sanctions": 0,
"china": 0
},
"pulse_level": "critical",
"ais_coverage": {
"status": "no_coverage",
"nearest_chokepoint": null,
"distance_km": null
},
"recent_events": [
{
"headline": "Port infrastructure struck in overnight attack",
"family": "conflict",
"event_date": "2026-06-13",
"distance_km": 4,
"cluster_id": "c_abc123",
"cluster_date": "2026-06-13"
}
]
}
],
"summary": {
"ports": 6,
"window_days": 14,
"event_radius_km": 60,
"ports_with_conflict": 4,
"ports_active": 5
},
"applied_filters": {
"country": "UKR",
"days": 14,
"event_radius_km": 60,
"ignored": {}
}
}{
"success": false,
"error": "<string>",
"code": "<string>",
"details": {}
}{
"success": false,
"error": "<string>",
"code": "<string>",
"details": {}
}{
"success": false,
"error": "<string>",
"code": "<string>",
"details": {}
}Port disruption pulse
Port-level disruption intelligence — geo-fuses the WPI ports reference with GDELT events near each port (within event_radius_km over the last days): relevant-event volume, conflict signal, a 7d-vs-baseline anomaly ratio, recent headlines, nearby flagged-energy-asset exposure, and AIS-coverage context. Scope by country, terminal type, name, or proximity; with no scope it defaults to strategic ports (LNG/oil terminals + large harbors). Requires a plan with Maritime intelligence access (can_use_maritime) — see Pricing for the plans that include it.
Each row scores a pulse_level (critical / elevated / active / quiet) and rows are risk-ranked. Envelope: { success, data, summary, applied_filters }.
Pulse rubric: critical = at least 5 conflict Events; elevated = 1–4 conflict Events; active = no conflict Events but at least one other relevant Event; quiet = no relevant Events. Relevant-event volume does not override a conflict-based level. relevant_events: Events within event_radius_km that are either conflict-family Events or carry one of the published maritime, infrastructure, trade, sanctions, energy, logistics, port, shipping, pipeline, customs, smuggling, or commodity relevance tags.
curl --request GET \
--url https://gdeltcloud.com/api/v2/maritime/port-pulse \
--header 'Authorization: Bearer <token>'import requests
url = "https://gdeltcloud.com/api/v2/maritime/port-pulse"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://gdeltcloud.com/api/v2/maritime/port-pulse', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"success": true,
"data": [
{
"port_id": "UAODS",
"name": "Odesa",
"unlocode": "UAODS",
"country": "UKR",
"country_name": "Ukraine",
"lat": 46.49,
"lon": 30.74,
"harbor_size": "Medium",
"lng_terminal": false,
"oil_terminal": true,
"relevant_events": 37,
"conflict_events": 12,
"events_last_7d": 9,
"anomaly_ratio": 1.35,
"energy_exposure": {
"assets_nearby": 2,
"state_owned": 1,
"sanctions": 0,
"china": 0
},
"pulse_level": "critical",
"ais_coverage": {
"status": "no_coverage",
"nearest_chokepoint": null,
"distance_km": null
},
"recent_events": [
{
"headline": "Port infrastructure struck in overnight attack",
"family": "conflict",
"event_date": "2026-06-13",
"distance_km": 4,
"cluster_id": "c_abc123",
"cluster_date": "2026-06-13"
}
]
}
],
"summary": {
"ports": 6,
"window_days": 14,
"event_radius_km": 60,
"ports_with_conflict": 4,
"ports_active": 5
},
"applied_filters": {
"country": "UKR",
"days": 14,
"event_radius_km": 60,
"ignored": {}
}
}{
"success": false,
"error": "<string>",
"code": "<string>",
"details": {}
}{
"success": false,
"error": "<string>",
"code": "<string>",
"details": {}
}{
"success": false,
"error": "<string>",
"code": "<string>",
"details": {}
}Authorizations
GDELT Cloud API key. Send as Authorization: Bearer gdelt_sk_....
Query Parameters
Country filter on port-pulse. Accepts a country name, ISO-2, or ISO-3 (e.g. Ukraine, UA, UKR) via the shared resolveCountryInput layer; an unresolvable value returns 400 INVALID_COUNTRY.
Case-insensitive match on port name, alternate name, or UN/LOCODE.
true → only ports with an LNG terminal.
true → only ports with an oil terminal.
Point 'lat,lon' for a radius search; combine with radius_km (default 200). Format: lat,lon — pass the radius separately in radius_km.
"51.5,-0.12"
GEM energy-asset gem_id — scope to ports within radius_km of that asset (cross-source join).
Radius in km for near / near_gem_id. Default 200; clamped 1–2000.
GDELT event window in days (1–30). Defaults to 14.
1 <= x <= 30How close an event must be to a port to count it (5–500 km). Defaults to 50.
5 <= x <= 500Number of ports to score (1–50). Defaults to 20.
1 <= x <= 50Response
Risk-ranked ports with their pulse. Each row: port_id, name, unlocode, country, lat, lon, harbor_size, lng_terminal / oil_terminal, relevant_events, conflict_events, events_last_7d, anomaly_ratio, energy_exposure, pulse_level, ais_coverage, and up to 3 recent_events. A summary block totals the window.

