ACLED API tutorial: fetch and visualize conflict data for humanitarian analysis
A step-by-step guide to querying the Armed Conflict Location and Event Data (ACLED) API, filtering by event_type and fatalities, and turning raw records into charts that support humanitarian decision-making.
TL;DR
The ACLED API (api.acleddata.com/acled/read) returns coded political-violence and protest events as JSON, CSV, or XML. Register at developer.acleddata.com for a free non-commercial key, then filter by country, event_date, event_type, and fatalities. Paginate with page=1..N, cap No current figure rows, and always cite ACLED with the retrieval date.
Why the ACLED API matters for humanitarian analysis
ACLED codes political-violence and protest events across more than 240 countries and territories, with each record carrying a date, location, actor, event_type, and fatality estimate. Programmatic access through the read API lets humanitarian teams monitor escalation, feed alerting systems, and integrate conflict signals into needs assessments without waiting for monthly PDF bulletins.
This tutorial focuses on the two fields most relevant to protection and response planning: event_type (the typology of violence) and fatalities (a conservative lower bound on reported deaths). The examples use Sudan in the first half of 2026, but the pattern generalises to every country ACLED covers.
Six steps from API key to chart
Step 1.Register for ACLED API access
Create a free account at developer.acleddata.com to receive an API key and email. Non-commercial researchers, journalists, and humanitarian analysts qualify for standard access; commercial and government users apply for a paid tier. The key is passed on every request as query parameters.
Step 2.Understand the endpoint and response shape
The core endpoint is https://api.acleddata.com/acled/read. It returns JSON (default), CSV, XML, or TXT. Each record is one coded event with fields for date, location, actor, event_type, sub_event_type, notes, and fatalities. Read the ACLED Codebook alongside the API docs so field values map to your analytical categories.
Step 3.Filter by country, date, and event_type
Use query parameters: country=Sudan, year=2026, event_date=2026-01-01|2026-06-30 with event_date_where=BETWEEN, and event_type=Battles|Violence against civilians|Explosions/Remote violence with event_type_where=IN. Combining event_type with fatalities>0 quickly isolates lethal incidents for humanitarian response mapping.
Step 4.Page through large result sets
The API caps a single request at 500 rows by default (up to No current figure with limit=5000). Use page=1,2,3... to paginate. For multi-year national datasets, request one year at a time and concatenate. Cache raw pulls locally; ACLED rate-limits repeated identical queries.
Step 5.Aggregate event_type and fatalities for analysis
Group by event_type to see the composition of violence (battles vs. protests vs. remote violence). Sum fatalities by admin1 (province) or month to surface escalation. Treat event counts as coverage-sensitive and fatalities as a lower bound; report both together, never one as a proxy for the other.
Step 6.Visualize responsibly
Map event points with symbol size scaled to fatalities, color-coded by event_type. Add a monthly trend line for the country to show whether spikes reflect a single incident or a sustained pattern. Include a source note citing ACLED and the date of retrieval on every chart.
Working code examples
curl: a single filtered pull
curl -G "https://api.acleddata.com/acled/read" \
--data-urlencode "key=YOUR_KEY" \
--data-urlencode "email=you@example.org" \
--data-urlencode "country=Sudan" \
--data-urlencode "event_type=Battles|Violence against civilians" \
--data-urlencode "event_type_where=IN" \
--data-urlencode "event_date=2026-01-01|2026-06-30" \
--data-urlencode "event_date_where=BETWEEN" \
--data-urlencode "limit=500"
Python: paginate and aggregate by event_type
import requests
import pandas as pd
API_KEY = "YOUR_KEY"
EMAIL = "you@example.org"
params = {
"key": API_KEY,
"email": EMAIL,
"country": "Sudan",
"event_date": "2026-01-01|2026-06-30",
"event_date_where": "BETWEEN",
"event_type": "Battles|Violence against civilians|Explosions/Remote violence",
"event_type_where": "IN",
"limit": 5000,
"page": 1,
}
rows = []
while True:
r = requests.get("https://api.acleddata.com/acled/read", params=params, timeout=60)
r.raise_for_status()
batch = r.json().get("data", [])
if not batch:
break
rows.extend(batch)
params["page"] += 1
df = pd.DataFrame(rows)
df["fatalities"] = pd.to_numeric(df["fatalities"], errors="coerce").fillna(0)
# Aggregate by event_type
by_type = df.groupby("event_type").agg(
events=("event_id_cnty", "count"),
fatalities=("fatalities", "sum"),
).sort_values("fatalities", ascending=False)
print(by_type)
Requires requests and pandas. Replace YOUR_KEY and you@example.org with the credentials issued by ACLED. The loop stops when a page returns no further records.
Key ACLED fields to know
| Field | What it means |
|---|---|
| event_date | ISO date the event occurred. Use with event_date_where=BETWEEN and a pipe-separated range for time windows. |
| event_type | One of Battles, Violence against civilians, Explosions/Remote violence, Protests, Riots, Strategic developments. The primary axis for conflict typology. |
| sub_event_type | Finer classification (e.g. Armed clash, Air/drone strike, Attack, Peaceful protest). Use for tactical or thematic breakdowns. |
| actor1 / actor2 | Named parties. actor1 initiates; actor2 is the target or counter-party. Filter with actor1_where=LIKE for partial matches. |
| admin1 / admin2 | Subnational units. Aggregate here for province- or district-level dashboards. |
| latitude / longitude | Geocoded to a settlement or nearest known point. Include the location field for context and geoprecision. |
| fatalities | Reported deaths tied to the event. Treated as a conservative lower bound; ACLED prefers the lowest credible figure. |
| source / source_scale | Media or partner source and its geographic scale (Local, National, International). Useful for coverage-bias diagnostics. |
Source: ACLED Codebook (2024 edition) and the ACLED API documentation at developer.acleddata.com.
Turning event_type and fatalities into charts
- Stacked bar by month. Group by month and event_type, then stack Battles, Violence against civilians, and Explosions/Remote violence to see whether escalation is driven by frontline combat or civilian targeting.
- Choropleth by admin1. Sum fatalities per province over the window, and shade regions by intensity. Overlay event points sized by fatalities for context.
- Actor network. Build an edge list from actor1 and actor2 to visualise which parties are engaged in the most lethal incidents.
- Trend with rolling mean. Plot weekly event counts and fatalities with a 4-week rolling mean to smooth reporting noise.
Common pitfalls
Do not read event counts as violence intensity
Fatalities are a lower bound
Watch for revisions
Respect the terms of use
Frequently asked questions
What is the ACLED API and who can use it?
ACLED (Armed Conflict Location & Event Data) is a global dataset of political-violence and protest events. The read API at api.acleddata.com serves coded events as JSON, CSV, or XML. Non-commercial researchers, journalists, and humanitarian analysts qualify for free access after registering for an API key at developer.acleddata.com; commercial and government users apply for a paid tier.
How do I filter ACLED API results by event_type and fatalities?
Pass event_type=Battles|Violence against civilians with event_type_where=IN to select multiple categories, and fatalities=0 with fatalities_where=%3E (URL-encoded > ) to isolate lethal events. Combine with country and event_date filters. All parameters go on the query string alongside your key and email.
What is the difference between event_type and sub_event_type?
event_type is one of six top-level categories: Battles, Violence against civilians, Explosions/Remote violence, Protests, Riots, and Strategic developments. sub_event_type is a finer classification such as Armed clash, Air/drone strike, or Peaceful protest. Use event_type for typology charts and sub_event_type for tactical or thematic analysis.
How should humanitarian analysts interpret ACLED fatalities?
ACLED records the lowest credible reported figure for each event, so fatalities are a conservative lower bound. Report them alongside event counts, note coverage constraints, and cross-reference peer-reviewed excess-mortality studies for total war deaths. Do not present fatalities as a complete casualty count.
Are there rate limits or size caps on the ACLED API?
A single request returns up to 500 rows by default and No current figure with limit=5000. Use the page parameter to paginate. ACLED rate-limits repeated identical queries; cache raw pulls locally, request one year at a time for large national datasets, and refresh monthly rather than continuously.
Related resources on Humanity Centered Data
How to read IDP, refugee, IPC, and ACLED figures
Datasets, APIs, and methodologies
Live ACLED-backed conflict analytics
Where to find complementary humanitarian datasets
Applied workflow using ACLED events alongside satellite change detection
Sentinel Hub, change indices, and HDX layers for damage verification
