Conflict Alert System (CAST) API

In March 2023, ACLED released the Conflict Alert System (CAST), a conflict prediction tool. CAST provides a monthly forecast of the number of political violence events for every country and territory in the world up to six months in advance.

In addition to exploring conflict forecasts in ACLED’s interactive dashboard, you can also access CAST results (i.e. predictions) by downloading them from ACLED’s website or using the CAST endpoint in ACLED’s API. This section will walk you through how to use the CAST endpoint.

In this section you will find information regarding:

Access to the CAST endpoint

Accessing the CAST endpoint differs from accessing other endpoints in ACLED’s API. The CAST endpoint has its own usage limits, which are not tied to your general API limitations (which vary from user to user). Accessing CAST data will not count against your limit of general API calls. Instead, after registering your account, you will receive 10 free logins per year to the CAST dashboard and/or endpoint. However, Civil Society users (e.g. media, academics, NGOs, etc.), sponsors, partners, and ACLED Network members receive unlimited access. Corporate and Public Sector users can receive additional logins by contacting [email protected].

As is the case when using any ACLED data, your usage of the CAST tool must follow ACLED’s Terms of Use & Attribution Policy. For instance, if for non-commercial purposes you want to reproduce or republish a visual, graphic, or map from ACLED CAST (rather than creating an original image using raw data), you should include the following citation:

ACLED. (DD MM YYYY). “ACLED Conflict Alert System.” Armed Conflict Location & Event Data Project (ACLED). https://acleddata.com/early-warning-research-hub/conflict-alert-system/ © 2023 ACLED All rights reserved. Used with permission from ACLED. Accessed (DD MM YYYY).

Query filters

After gaining access to the CAST endpoint, you can request data in the same way as you would for other endpoints in ACLED’s API. For instance, you can use query filters to limit your request so that your API call returns only the data you need. Basic instructions for using query filters are included below, but you can find a step-by-step set of directions in the Get started section and Advanced concepts section. You can find a list of query filters that can be used in the CAST endpoint in the following table:

Table 1: Table of query filters in ‘CAST’ endpoint
Query Name Type Query String
email = ?key={api_key}
key = ?email={email address associated with key}
country LIKE ?country={text}
admin1 LIKE ?admin1={text}
month LIKE ?month={text}
year = ?year={yyyy}
total_forecast = ?total_forecast={text}
battles_forecast = ?battles_forecast={text}
erv_forecast = ?erv_forecast={text}
vac_forecast = ?vac_forecast={text}
total_observed = ?total_observed={text}
battles_observed = ?battles_observed={text}
erv_observed = ?erv_observed={text}
vac_observed = ?vac_observed={text}
timestamp >= ?timestamp={number or yyyy-mm-dd}

As is the case with other endpoints, query types can be modified to fit your needs. To modify the query type, you should add an extra command with the name of the query filter you want to change and the suffix _where, followed by the desired query type (e.g. year_where=> if you want to use the query type “greater than”). You can visit the Advanced concepts section for a more detailed explanation and list of query type options.

Remember that you can also combine multiple query filters and query types, either by using &’,|, or:OR:` depending on your needs. Please see the Advanced concepts section for more information.

Returned data

When you execute your API call, you will receive data containing the following variables:

Table 2: Table of returned data in ‘CAST’ endpoint
Attribute Name Type Description
country string The name of the country
admin1 string The name of the first-level administrative division
month string The month of events
year int The year of events
total_forecast int Total number of events forcasted
battles_forecast int Total number of battles events forecasted
erv_forecast int Total number of explosions/remote violence events forecasted
vac_forecast int Total number of violence against civilians events forecasted
total_observed int Total number of events observed. This column will be populated once the given month has passed
battles_observed int Total number of battles events observed. This column will be populated once the given month has passed
erv_observed int Total number of explosions/remote violence events observed. This column will be populated once the given month has passed
vac_observed int Total number of violence against civilians events observed. This column will be populated once the given month has passed
timestamp int or date The unix timestamp (or date stamp) this data entry was last updated

Note: You can learn more about the data in each of these columns in the CAST methodology guide

To reduce the size of the returned file and streamline later analyses, you can limit which columns are returned by using the fields filter to specify which columns you want to receive. If you would like to request multiple columns, list them all while separating each column name by the pipe operator (|). For instance, if you are only interested in the admin1, month, vac_forecast and battles_forecast columns, you can include the following section in your URL:

…&fields=admin1|month|battles_forecast|vac_forecast

Returned data - JSON only.

If you request your data in .json format (the default option) rather than .csv, .txt, or .xml, you will also receive the following as part of the API response:

Table 3: 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 above
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 💻

You can now apply what you learned above to a simple example: gathering forecast data for “Argentina” and “Brazil” in 2023.

You can build your query by following these steps:

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

https://api.acleddata.com/

  1. Add the CAST endpoint.

https://api.acleddata.com/cast/

  1. Specify the desired response format.

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

  1. Include your credentials by replacing “your_key” and “your_email” with your registered key and email, respectively.

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

  1. Add query filters specifying the desired countries.

https://api.acleddata.com/cast/read.csv?key=your_key&email=your_email&country=Brazil|Argentina

  1. Add a query filter specifying the desired year.

https://api.acleddata.com/cast/read.csv?key=your_key&email=your_email&country=Brazil|Argentina&year=2023

Now that your URL is built, you can paste it into your internet browser to receive your requested data from ACLED’s server. Your file should look something like this:

country admin1 month year total_forecast battles_forecast erv_forecast vac_forecast total_observed battles_observed erv_observed vac_observed timestamp
Argentina Salta March 2023 0 0 0 0 0 0 0 0 1704898526
Brazil Parana October 2023 8 3 1 4 9 2 0 7 1704898532
Argentina Santa Fe August 2023 0 0 0 0 0 0 0 0 1704898526
Brazil Mato Grosso do Sul December 2023 12 6 0 6 22 14 0 8 1704898532
Brazil Distrito Federal September 2023 3 1 0 2 0 0 0 0 1704898532
Brazil Ceara July 2023 6 2 0 4 6 2 0 4 1704898532
Argentina Rio Negro September 2023 0 0 0 0 0 0 0 0 1704898526
Brazil Roraima March 2023 9 4 0 5 2 1 0 1 1704898533
Argentina Chubut December 2023 0 0 0 0 0 0 0 0 1704898525
Brazil Sergipe November 2023 6 3 0 3 5 5 0 0 1704898533

Success! Your file contained data for “Argentina” and “Brazil” in 2023!

Best of luck building your next URL! 🚀

Example - Python

You can also request data using Python rather than your internet browser. Remember that you want to end up with a file containing data that:

  • is from 2023,
  • contains the countries of “Argentina” and “Brazil”.

To start, make sure you have already imported the necessary modules (requests and json)

import requests
import json

You can use the requests module to execute your data request in one of 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 learn how to request data in both ways below:

# Option #1
# Request the data as a JSON file 
response_full_url = requests.get("https://api.acleddata.com/cast/read?key=your_key&email=your_email&country=Brazil|Argentina&year=2023")
if response_full_url.json()['status'] == 200:
  print("Congratulations! Request successful!")
Congratulations! Request successful!
# Option #2
# Create a dictionary of parameters.
parameters = {
  "email": "your_email",
  "key": "your_key",
  "country": "Brazil|Argentina", # we introduce a workaround to adding our multiple country statement
  "year": 2023
}
# Request the data as a JSON file and pass our paramenters as an argument (params=)
response_params_dic = requests.get("https://api.acleddata.com/cast/read", params= parameters)
if response_params_dic.json()['status'] == 200:
  print("Congratulations! Request successful!")
Congratulations! Request successful!

Using either option yields the same data. Which option is best for you will depend on your needs and use cases.

Best of luck! 🚀

Example - R

Working with ACLED’s API in R is straightforward, simple, and similar to the Python example above.

You should start by loading the packages you will need:

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 

Remember that you are looking to receive data that:

  • is from 2023,
  • contains the countries of “Argentina” and “Brazil”.

As with the Python example, you can take two different approaches when executing an API call in R. First, you can pass the full URL to the httr::GET() function. Alternatively, you can pass the API’s base URL with the "read"+{file extension} command while using a list of parameters in httr:: GET() to specify your query filters.

# Option #1
# Execute your call
response <- GET("https://api.acleddata.com/cast/read?key=your_key&email=your_email&country=Brazil|Argentina&year=2023") 
# 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)
# Option #2
# Set up the list of parameters
parameters <- list(
  email= "your_email",
  key= "your_key",
  country= "Brazil|Argentina", # we introduce a workaround to adding our multiple country statement
  year= 2023,
)
# Execute your call
respose <- GET("https://api.acleddata.com/cast/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)
No encoding supplied: defaulting to UTF-8.

Now you can check your data:

glimpse(response_df_option1)
Rows: 510
Columns: 13
$ country          <chr> "Brazil", "Brazil", "Brazil", "Brazil", "Brazil", "Br…
$ admin1           <chr> "Parana", "Pernambuco", "Pernambuco", "Pernambuco", "…
$ month            <chr> "December", "March", "April", "May", "June", "July", …
$ year             <chr> "2023", "2023", "2023", "2023", "2023", "2023", "2023…
$ total_forecast   <chr> "6", "16", "17", "5", "25", "25", "8", "7", "5", "10"…
$ battles_forecast <chr> "2", "10", "7", "2", "4", "5", "4", "0", "2", "3", "5…
$ erv_forecast     <chr> "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"…
$ vac_forecast     <chr> "4", "6", "9", "3", "21", "20", "4", "7", "3", "7", "…
$ total_observed   <chr> "6", "12", "2", "15", "9", "5", "7", "5", "5", "17", …
$ battles_observed <chr> "5", "6", "1", "3", "2", "2", "0", "2", "1", "7", "1"…
$ erv_observed     <chr> "1", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0"…
$ vac_observed     <chr> "0", "5", "1", "12", "7", "3", "7", "3", "4", "10", "…
$ timestamp        <chr> "1704898533", "1704898533", "1704898533", "1704898533…

Both options should allow you to easily request the data you are looking for, so please choose the option that best suits your needs.

Best of luck! 🚀