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

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.

Table 1: Query filters for the ACLED endpoint
Filter Name Type String
key = ?key={api_key}
email = ?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}
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.

Filtering by region and actor type

There are some key differences between ACLED’s API filters and the contents of the data. In particular, 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 we outline which number you should use to request data from each region:

Regions

Table 2: Numeric codes for each region in ACLED data
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

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.

Table 3: Dyadic table of events
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 3 Civilians (Mexico) 7 37
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-) 1 Unidentified Armed Group (Mexico) 3 13
MEX70206 2023-02-01 2023 2 Political violence Violence against civilians Attack Unidentified Armed Group (Mexico) 3 Civilians (Mexico) 7 37
MEX70210 2023-02-01 2023 1 Political violence Violence against civilians Attack Unidentified Armed Group (Mexico) 3 Civilians (Mexico) Police Forces of Mexico (2018-) Ministerial Federal Police 7 37
MEX70211 2023-02-01 2023 2 Political violence Violence against civilians Attack Unidentified Armed Group (Mexico) 3 Civilians (Mexico) 7 37
Table 4: Monadic table of events
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 3 37
MEX70117 2023-02-01 2023 2 Political violence Violence against civilians Attack Civilians (Mexico) 7 37
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-) 1 13
MEX70129 2023-02-01 2023 1 Strategic developments Strategic developments Looting/property destruction Unidentified Armed Group (Mexico) 3 13
MEX70206 2023-02-01 2023 2 Political violence Violence against civilians Attack Unidentified Armed Group (Mexico) 3 37
MEX70206 2023-02-01 2023 2 Political violence Violence against civilians Attack Civilians (Mexico) 7 37
MEX70210 2023-02-01 2023 1 Political violence Violence against civilians Attack Unidentified Armed Group (Mexico) 3 37
MEX70210 2023-02-01 2023 1 Political violence Violence against civilians Attack Civilians (Mexico) Police Forces of Mexico (2018-) Ministerial Federal Police 7 37
MEX70211 2023-02-01 2023 2 Political violence Violence against civilians Attack Unidentified Armed Group (Mexico) 3 37
MEX70211 2023-02-01 2023 2 Political violence Violence against civilians Attack Civilians (Mexico) 7 37

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.

Table 5: Returned data’s column structure
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 int A numeric code between 0 and 8 indicating the type of ‘Actor 1’.
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 int A numeric code between 0 to 8 indicating the type of ‘Actor 2’.
interaction int A two-digit numeric code (combination of ‘Inter 1’ and ‘Inter 2’) indicating the two actor types interacting in the event.
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:3857).
longitude decimal The longitude of the location in four decimal degrees notation (EPSG:3857).
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 precision.
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:

Table 6: The 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 5
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.

  1. Begin with the ACLED API’s base URL.

https://api.acleddata.com/

  1. Add the ACLED endpoint.

https://api.acleddata.com/acled/

  1. Add the response format.

https://api.acleddata.com/acled/read.csv

  1. Input your credentials.

https://api.acleddata.com/acled/read.csv?key=your_key&email=your_email

  1. 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

  1. 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

  1. 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:

  1. Use your full URL as the first argument in requests.get().

  2. 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 
response_full_url = 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")
if response_full_url.json()['status'] == 200:
  print("Congratulations! Request successful! Take a peek to the returned JSON structure.")
Congratulations! Request successful! Take a peek to the returned JSON structure.

As you can see, the requested data matches Table 6. 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=)
response_params_dic = requests.get("https://api.acleddata.com/acled/read", params= parameters)
if response_params_dic.json()['status'] == 200:
  print("Congratulations! Request successful! Take a peek to the returned JSON structure.")
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
Warning: package 'jsonlite' was built under R version 4.2.3
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
response <- 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") 
# Transform the API response into a dataframe
response_json <- jsonlite::fromJSON(content(response, "text"), simplifyVector=T)
response_df_option1 <- as.data.frame(response_json$data)

Now that you have retrieved the data via option #1, you can try option #2.

# Option #2
# Set up the list of parameters
parameters <- list(
  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
response <- GET("https://api.acleddata.com/acled/read", query = parameters)
# Transform the API response into a dataframe
response_json <- jsonlite::fromJSON(content(response, "text"), simplifyVector=T)
response_df_option2 <- as.data.frame(response_json$data)

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! 🚀