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:
How to access the
CAST
endpointRelevant query filters
The format and contents of returned data
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:
Query Name | Type | Query String |
---|---|---|
= | ?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:
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:
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:
- Begin with the ACLED API’s base URL.
https://api.acleddata.com/
- Add the
CAST
endpoint.
https://api.acleddata.com/cast/
- Specify the desired response format.
https://api.acleddata.com/cast/read.csv
- 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
- Add query filters specifying the desired countries.
https://api.acleddata.com/cast/read.csv?key=your_key&email=your_email&country=Brazil|Argentina
- 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:
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 learn how to request data in both ways below:
# Option #1
# Request the data as a JSON file
= requests.get("https://api.acleddata.com/cast/read?key=your_key&email=your_email&country=Brazil|Argentina&year=2023")
response_full_url 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=)
= requests.get("https://api.acleddata.com/cast/read", params= parameters)
response_params_dic 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
<- GET("https://api.acleddata.com/cast/read?key=your_key&email=your_email&country=Brazil|Argentina&year=2023")
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
# Option #2
# Set up the list of parameters
<- list(
parameters email= "your_email",
key= "your_key",
country= "Brazil|Argentina", # we introduce a workaround to adding our multiple country statement
year= 2023,
)# Execute your call
<- GET("https://api.acleddata.com/cast/read", query = parameters)
respose # 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
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! 🚀