ACLED Endpoint
In this section, you will learn how to request ACLED data using API calls to the ACLED
endpoint. Here you can learn in more detail about the specific elements that form an API call to the ACLED
endpoint, which returns data from ACLED’s event dataset. (To learn more about ACLED data and methodology, please see the ACLED codebook.) If you have not already done so, please see the Get started section for an explanation of how to build a basic API call. You can also learn about more advanced techniques for using any of the endpoints in ACLED’s API in our Advanced concepts section.
This section, like the other endpoint sections, is organized as follows:
Query filters (i.e. how to request specific data)
Returned data
An example call and its results
Query filters
In most cases, it is not necessary to download the entirety of the ACLED dataset, but rather a subset of the data. To avoid requesting unnecessary data, you can use “query filters” to specify the exact data you would like to receive. For instance, you can apply a query filter to your API call so that it only returns events occurring in a specific country or involving a particular actor.
All available query filters are listed in the table below. The first column contains the name of each filter, the second states the filter’s type, and the third indicates the string you must add to the API call in order to apply that filter.
ACLED
endpoint
Filter Name | Type | String |
---|---|---|
key | = | ?key={api_key} |
= | ?email={email address associated with key} | |
event_id_cnty | LIKE | ?event_id_cnty={text} |
event_date | = | ?event_date={yyyy-mm-dd} |
year | = | ?year={yyyy} |
time_precision | = | ?time_precision={number} |
disorder_type | LIKE | ?disorder_type={text} |
event_type | LIKE | ?event_type={text} |
sub_event_type | LIKE | ?sub_event_type={text} |
actor1 | LIKE | ?actor1={text} |
assoc_actor_1 | LIKE | ?assoc_actor_1={text} |
inter1 | = | ?inter1={number} |
actor2 | LIKE | ?actor2={text} |
assoc_actor_2 | LIKE | ?assoc_actor_2={text} |
inter2 | = | ?inter2={number} |
interaction | = | ?interaction={number} |
inter_num | = | ?inter_num={0,1} |
civilian_targeting | LIKE | ?civilian_targeting={text} |
iso | = | ?iso={number} |
region | = | ?region={number} |
country | = | ?country={text} |
admin1 | LIKE | ?admin1={text} |
admin2 | LIKE | ?admin2={text} |
admin3 | LIKE | ?admin3={text} |
location | LIKE | ?location={text} |
latitude | = | ?latitude={number} |
longitude | = | ?longitude={number} |
geo_precision | = | ?geo_precision={number} |
source | LIKE | ?source={text} |
source_scale | LIKE | ?source_scale={text} |
notes | LIKE | ?notes={text} |
fatalities | = | ?fatalities={number} |
tags | LIKE | ?tags={text} |
timestamp | >= | ?timestamp={number or yyyy-mm-dd} |
export_type | = | ?export_type={text} |
population | = | ?population={TRUE|full} |
Note: The string column shows the strings you should add to your URL if the filter is the first filter you use. If that particular filter is not the first you use, you should remove the ?
and replace it with &
. Remember that key
and email
are also considered query filters.
To use these filters, add the relevant string(s) from the above table into your request. Be sure to remove the curly brackets (i.e. {}
) from your URL and replace ?
with &
where necessary. After adding the correct query filter to your URL, you can fill in the bracketed section with the desired filter values.
For instance, to request all the data from “Canada” in 2022, you would replace {text}
in the country filter with Canada
and {yyyy}
in the year filter with 2022
. Note that you should not include brackets when entering these strings, so your request should end with the following text:
…&country=Canada&year=2022
You can also change the query type of each query filter to fit your needs. For example, to request all events during and after 2018, you cannot simply include &year=2018
, since the year
query filter is of type =
, meaning this API call will only return events that occurred in 2018. Instead, you can change the query type to >
by adding a new command with the query filter and the suffix _where
, followed by the desired query type (i.e. &year=2017&year_where=>
). For a more in-depth treatment of how to change query filters and what options are available, please see the Advanced concepts section,
In the case of the population
parameter, this takes two different options, either TRUE
which returns only the population_best
population estimate column, or full
which returns all the estimates of population. For more information on the population columns, visit our Conflict Exposure piece.
On 26 September 2024, the default value of interaction code columns changed from numeric to text-based. Prior to this change, the inter1, inter2, and interaction columns appeared as numeric values that corresponded to a specific actor type in the codebook. After the change, the values appeared in the data as text. For instance, if actor1 was a ‘State forces’ actor, then before the change, the value in the inter1 column would have been ‘1’, whereas after the change, the value became ‘State forces.’
The interaction column, which was a combination of the inter1 and inter2 columns, also changed to a text-based output by default. For instance, before the change, if inter1 was 1 and inter2 was 2, the interaction column would have had the value ‘12’. After the change, the interaction column showed the text combination of the inter1 and inter2 columns (e.g., interaction = State forces - Rebel group).
Although the default output for these columns changed, we recognized that some users would want to continue receiving numeric values. As a result, a new filter was added to the API: inter_num. By setting inter_num=1, users can receive the inter1, inter2, and interaction columns with numeric values. Excluding the parameter or setting inter_num=0 returns the default text descriptors.
Filtering by region and actor type
There are some key differences between ACLED’s API filters and the contents of the data, particularly with respect to region
names and inter codes.
Regions
region
names appear in the dataset as strings (e.g. “Central America”, “Northern Africa”, etc.), but in the API, they are represented by numeric codes. For instance, if you want all the data from Western Africa, rather than including region=Western Africa in your request, you should instead include region=1. In the table below (Table 2) we outline which number you should use to request data from each region
.
Region | Numeric Code |
---|---|
Western Africa | 1 |
Middle Africa | 2 |
Eastern Africa | 3 |
Southern Africa | 4 |
Northern Africa | 5 |
South Asia | 7 |
Southeast Asia | 9 |
Middle East | 11 |
Europe | 12 |
Caucasus and Central Asia | 13 |
Central America | 14 |
South America | 15 |
Caribbean | 16 |
East Asia | 17 |
North America | 18 |
Oceania | 19 |
Antarctica | 20 |
Inter codes and interactions
inter1
, inter2
, and interaction
values appear in the data as strings (e.g. “State Forces”), but in the API they are represented by numeric codes. For example, if you want to receive data for events where actor1
is “State Forces”, you should specify inter1=1
rather than inter1=State Forces
. Below you can find a table (Table 3) of numeric codes corresponding to the actor types represented by inter codes. If you wish to specify events based on the interaction
column, please see Table 3 of the ACLED codebook for numeric interaction
values corresponding to their text-based actor types. Also note that you can receive numeric rather than text-based inter and interaction values using the inter_num
filter (Table 1).
Numeric Inter Code | Text-based Actor Type |
---|---|
10 | State forces only |
11 | State forces-State forces |
12 | State forces-Rebel group |
13 | State forces-Political militia |
14 | State forces-Identity militia |
15 | State forces-Rioters |
16 | State forces-Protesters |
17 | State forces-Civilians |
18 | State forces-External/Other forces |
20 | Rebel group only |
22 | Rebel group-Rebel group |
23 | Rebel group-Political militia |
24 | Rebel group-Identity militia |
25 | Rebel group-Rioters |
26 | Rebel group-Protesters |
27 | Rebel group-Civilians |
28 | Rebel group-External/Other forces |
30 | Political militia only |
33 | Political militia-Political militia |
34 | Political militia-Identity militia |
35 | Political militia-Rioters |
36 | Political militia-Protesters |
37 | Political militia-Civilians |
38 | Political militia-External/Other forces |
40 | Identity militia only |
44 | Identity militia-Identity militia |
45 | Identity militia-Rioters |
46 | Identity militia-Protesters |
47 | Identity militia-Civilians |
48 | Identity militia-External/Other forces |
50 | Rioters only |
55 | Rioters-Rioters |
56 | Rioters-Protesters |
57 | Rioters-Civilians |
58 | Rioters-External/Other forces |
60 | Protesters only |
66 | Protesters-Protesters |
67 | Protesters-Civilians |
68 | Protesters-External/Other forces |
70 | Civilians only |
77 | Civilians-Civilians |
78 | External/Other forces-Civilians |
80 | External/Other forces only |
88 | External/Other forces-External/Other forces |
Dyadic versus monadic formats - 'export_type'
ACLED data are available in two formats: dyadic (default) and monadic, specified by the export_type
filter, outlined at the end of Table 1.
“Dyadic” is the default format for ACLED data. Dyadic data have a column structure that matches the structure outlined in the ACLED Codebook. This data format includes one event per row and highlights the interaction between actors. In dyadic data, actor1 and actor2 are separate columns.
However, you may wish to analyze events by making actor-based calculations rather than analyzing the interactions occurring during each event. The “monadic” data format is actor-based, with each row representing a single actor-event. Having one actor per row means that the same event may appear twice: once for each actor involved in that event (here “actor” only refers to the actors in the actor1 and actor2 columns, not the associate actor columns). Ultimately, monadic data have fewer columns because they do not include actor2, assoc_actor_2, or inter2 columns, but more rows because many events appear twice in the monadic dataset.
event_id_cnty | event_date | year | time_precision | disorder_type | event_type | sub_event_type | actor1 | assoc_actor_1 | inter1 | actor2 | assoc_actor_2 | inter2 | interaction |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MEX70117 | 2023-02-01 | 2023 | 2 | Political violence | Violence against civilians | Attack | CJNG: Jalisco New Generation Cartel | Political militia | Civilians (Mexico) | Civilians | Political militia-Civilians | ||
MEX70129 | 2023-02-01 | 2023 | 1 | Strategic developments | Strategic developments | Looting/property destruction | Military Forces of Mexico (2018-) | Police Forces of Mexico (2018-) National Guard; Police Forces of Mexico (2018-) | State forces | Unidentified Armed Group (Mexico) | Political militia | State forces-Political militia | |
MEX70206 | 2023-02-01 | 2023 | 2 | Political violence | Violence against civilians | Attack | Unidentified Armed Group (Mexico) | Political militia | Civilians (Mexico) | Civilians | Political militia-Civilians | ||
MEX70210 | 2023-02-01 | 2023 | 1 | Political violence | Violence against civilians | Attack | Unidentified Armed Group (Mexico) | Political militia | Civilians (Mexico) | Police Forces of Mexico (2018-) Ministerial Federal Police | Civilians | Political militia-Civilians | |
MEX70211 | 2023-02-01 | 2023 | 2 | Political violence | Violence against civilians | Attack | Unidentified Armed Group (Mexico) | Political militia | Civilians (Mexico) | Civilians | Political militia-Civilians |
event_id_cnty | event_date | year | time_precision | disorder_type | event_type | sub_event_type | actor1 | assoc_actor_1 | inter1 | interaction |
---|---|---|---|---|---|---|---|---|---|---|
MEX70117 | 2023-02-01 | 2023 | 2 | Political violence | Violence against civilians | Attack | CJNG: Jalisco New Generation Cartel | Political militia | Political militia-Civilians | |
MEX70117 | 2023-02-01 | 2023 | 2 | Political violence | Violence against civilians | Attack | Civilians (Mexico) | Civilians | Political militia-Civilians | |
MEX70129 | 2023-02-01 | 2023 | 1 | Strategic developments | Strategic developments | Looting/property destruction | Military Forces of Mexico (2018-) | Police Forces of Mexico (2018-) National Guard; Police Forces of Mexico (2018-) | State forces | State forces-Political militia |
MEX70129 | 2023-02-01 | 2023 | 1 | Strategic developments | Strategic developments | Looting/property destruction | Unidentified Armed Group (Mexico) | Political militia | State forces-Political militia | |
MEX70206 | 2023-02-01 | 2023 | 2 | Political violence | Violence against civilians | Attack | Unidentified Armed Group (Mexico) | Political militia | Political militia-Civilians | |
MEX70206 | 2023-02-01 | 2023 | 2 | Political violence | Violence against civilians | Attack | Civilians (Mexico) | Civilians | Political militia-Civilians | |
MEX70210 | 2023-02-01 | 2023 | 1 | Political violence | Violence against civilians | Attack | Unidentified Armed Group (Mexico) | Political militia | Political militia-Civilians | |
MEX70210 | 2023-02-01 | 2023 | 1 | Political violence | Violence against civilians | Attack | Civilians (Mexico) | Police Forces of Mexico (2018-) Ministerial Federal Police | Civilians | Political militia-Civilians |
MEX70211 | 2023-02-01 | 2023 | 2 | Political violence | Violence against civilians | Attack | Unidentified Armed Group (Mexico) | Political militia | Political militia-Civilians | |
MEX70211 | 2023-02-01 | 2023 | 2 | Political violence | Violence against civilians | Attack | Civilians (Mexico) | Civilians | Political militia-Civilians |
By default, the API will return a dyadic dataset. If you would like to be returned a monadic dataset, you should add &export_type=monadic
to your request.
Returned data
The data you receive from the API will include the columns listed in the table below. The table contains the name of each column, its data type, and a short description of the data in that column. For more on these columns, see the ACLED Codebook.
Column Name | Type | Description |
---|---|---|
event_id_cnty | string | A unique alphanumeric event identifier by number and country acronym. This identifier remains constant even when the event details are updated. |
event_date | date | The date on which the event took place. Recorded as Year-Month-Day. |
year | int | The year in which the event took place. |
time_precision | int | A numeric code between 1 and 3 indicating the level of precision of the date recorded for the event. The higher the number, the lower the precision |
disorder_type | string | The disorder category an event belongs to. |
event_type | string | The type of event; further specifies the nature of the event. |
sub_event_type | string | A subcategory of the event type. |
actor1 | string | One of two main actors involved in the event (does not necessarily indicate the aggressor). |
assoc_actor_1 | string | Actor(s) involved in the event alongside ‘Actor 1’ or actor designations that further identify ‘Actor 1’ |
inter1 | string or int | A numeric code or string indicating actor type (Table 3). |
actor2 | string | One of two main actors involved in the event (does not necessarily indicate the target or victim). |
assoc_actor_2 | string | Actor(s) involved in the event alongside ‘Actor 2’ or actor designation further identifying ‘Actor 2’. |
inter2 | string or int | A numeric code or string indicating actor type (Table 3). |
interaction | string or int | A two-digit numeric code or a hyphenated string corresponding to inter1 and inter2. |
civilian_targeting | string | This column indicates whether the event involved civilian targeting. |
iso | int | A unique three-digit numeric code assigned to each country or territory according to ISO 3166. |
region | string | The region of the world where the event took place. |
country | string | The country or territory in which the event took place. |
admin1 | string | The largest sub-national administrative region in which the event took place. |
admin2 | string | The second largest sub-national administrative region in which the event took place. |
admin3 | string | The third largest sub-national administrative region in which the event took place. |
location | string | The name of the location at which the event took place. |
latitude | decimal | The latitude of the location in four decimal degrees notation (EPSG:4326). |
longitude | decimal | The longitude of the location in four decimal degrees notation (EPSG:4326). |
geo_precision | int | A numeric code between 1 and 3 indicating the level of certainty of the location recorded for the event. The higher the number, the lower the precisi |
source | string | The sources used to record the event. Separated by a semicolon. |
source_scale | string | An indication of the geographic closeness of the used sources to the event |
notes | string | A short description of the event. |
fatalities | int | The number of reported fatalities arising from an event. When there are conflicting reports, the most conservative estimate is recorded |
tags | string | Additional structured information about the event. Separated by a semicolon. |
timestamp | int/date | An automatically generated Unix timestamp that represents the exact date and time an event was last uploaded to the ACLED API. |
population_1km | int | Estimated population in a 1km radius (only returned if population=full) |
population_2km | int | Estimated population in a 2km radius (only returned if population=full) |
population_5km | int | Estimated population in a 5km radius (only returned if population=full) |
population_best | int | Best estimate of affected population (only returned if population=full OR population=TRUE) |
Returned data - JSON
only
As outlined in the Get started section, you can request data in different formats (i.e., .csv
,.json
,.xml
, and .txt
). If you request data in JSON
format, you will receive some additional fields that are described below:
JSON
response data
Attribute Name | Type | Description |
---|---|---|
status | int | A number representing the request status |
success | boolean | A boolean representation on the success of the call |
last_update | int | The number of hours since the last update to the data |
count | int | The number of data rows returned |
messages | array | An array of information messages that may require future action |
data | array | The rows of data returned. For details of attributes returned in each row, see Table 6 |
filename | string | The filename that will be used for .csv calls |
error | array | The details of the error with a status as an integer and message as a string |
Example - URL 💻
Imagine you are interested in the types of events and the number of fatalities that occurred in the Southern Caucasus in 2021. You will likely want to gather all the events that occurred in “Georgia”, “Armenia”, and “Azerbaijan” in 2021, but for your analysis you really only need the event_id_cnty, event_date, event_type, country, and fatalities columns.
You can follow these steps to build your data request.
- Begin with the ACLED API’s base URL.
https://api.acleddata.com/
- Add the
ACLED
endpoint.
https://api.acleddata.com/acled/
- Add the response format.
https://api.acleddata.com/acled/read.csv
- Input your credentials.
https://api.acleddata.com/acled/read.csv?key=your_key&email=your_email
- Add query filters specifying the countries for which you would like to receive data.
https://api.acleddata.com/acled/read.csv?key=your_key&email=your_email&country=Georgia|Armenia|Azerbaijan
- Add a query filter to specify the year in which the events occurred.
https://api.acleddata.com/acled/read.csv?key=your_key&email=your_email&country=Georgia|Armenia|Azerbaijan&year=2021
- Next, specify which data columns you want to receive.
https://api.acleddata.com/acled/read.csv?key=your_key&email=your_email&country=Georgia|Armenia|Azerbaijan&year=2021&fields=event_id_cnty|event_date|event_type|country|fatalities
Now that your query is built, you can paste it into your browser and download your data. For more instruction on building your URL please see the Advanced concepts section.
Best of luck! 🚀
Example - Python
You can request the same data using Python. Recall that we want to get data that includes:
- Events during 2021,
- Events from Georgia, Armenia, and Azerbaijan,
- And to only receive the following columns: event_id_cnty, event_date, event_type, country, and fatalities.
Before requesting data in Python, you will need to import the requests
and json
modules.
import requests
import json
The requests
module allows you to execute your data request. You can do this in two ways:
Use your full URL as the first argument in
requests.get()
.Alternatively, remove the query filters from your URL and pass them as a dictionary to the params argument of
requests.get()
.
You can see examples of both below.
# Option #1
# Request the data as a JSON file
= requests.get("https://api.acleddata.com/acled/read?key=your_key&email=your_email&country=Georgia|Armenia|Azerbaijan&year=2021&fields=event_id_cnty|event_date|event_type|country|fatalities")
response_full_url if response_full_url.json()['status'] == 200:
print("Congratulations! Request successful! Take a peek to the returned JSON structure.")
As you can see, the requested data matches Table 7. This approach is straightforward, although you may find it somewhat time-consuming when executing multiple requests.
# Option #2
# Create a dictionary of parameters.
= {
parameters "email": "your_email",
"key": "your_key",
"country": "Georgia|Armenia|Azerbaijan",
"year": 2021,
"fields": "event_id_cnty|event_date|event_type|country|fatalities"
}# Request the data as a JSON file and pass our paramenters as an argument (params=)
= requests.get("https://api.acleddata.com/acled/read", params= parameters)
response_params_dic if response_params_dic.json()['status'] == 200:
print("Congratulations! Request successful! Take a peek to the returned JSON structure.")
Both methods produce the same dataset. In option #1, you have to build the full URL and pass it as an argument. For option #2, you create a dictionary of parameters that the program uses to create the full URL.
Both approaches have their advantages and disadvantages. Which option is best for you will depend on your knowledge of APIs and how you expect to use API requests.
Best of luck! 🚀
Example - R
Working with ACLED’s API in R is straightforward, simple, and similar to the Python examples you saw above.
You can start by loading the required packages:
library(httr) # For handling API requests
library(jsonlite) # For handling the response of the API
library(dplyr) # For handling data
Recall that you are looking for the following data:
Events during 2021,
Events from Georgia, Armenia, and Azerbaijan,
Only receive columns: event_id_cnty, event_date, event_type, country, and fatalities.
As in Python, you can take two different approaches when requesting data from the API: you can pass the full URL to the httr::GET()
function, or you can pass in the API’s base URL with the "read"+{file extension}
command while using a list of parameters to specify query filters in httr:: GET()
.
# Option #1
# Execute our call
<- GET("https://api.acleddata.com/acled/read?key=your_key&email=your_email&country=Georgia|Armenia|Azerbaijan&year=2021&fields=event_id_cnty|event_date|event_type|country|fatalities")
response # Transform the API response into a dataframe
<- jsonlite::fromJSON(content(response, "text"), simplifyVector=T)
response_json <- as.data.frame(response_json$data) response_df_option1
Now that you have retrieved the data via option #1, you can try option #2.
# Option #2
# Set up the list of parameters
<- list(
parameters email= "your_email",
key= "your_key",
country= "Georgia|Armenia|Azerbaijan",
year= 2021,
fields= "event_id_cnty|event_date|event_type|country|fatalities")
# Execute your call
<- GET("https://api.acleddata.com/acled/read", query = parameters)
response # Transform the API response into a dataframe
<- jsonlite::fromJSON(content(response, "text"), simplifyVector=T)
response_json <- as.data.frame(response_json$data) response_df_option2
Like the Python example above, both options provide the same results. Which option you opt to employ will depend on your needs and use cases.
Best of luck! 🚀