One of the challenges I keep running into while researching the U.S.-funded Cuba "democracy" program is that the public search interface of ForeignAssistance.gov is far more restrictive than the underlying dataset. This is not necessarily intentional, but the practical consequence is that it becomes impossible to discover every Cuba-related record through the official web interface alone.
ForeignAssistance.gov is "the U.S. government's flagship website for U.S. foreign assistance data." At some point, it absorbed the information previously available through Explorer.usaid.gov, making it an essential source that I cross-reference with USASpending.gov to track projects associated with this program established between 1995 and 1996 by the now-defunct USAID.
The problem is that the web interface does not allow searches across critical text fields such as Activity Name or Activity Description. Instead, most searches are centered around fields like the recipient country, the managing agencies, or the purpose of the funding —i.e., "Democratic participation and civil society". That sounds reasonable, until you realize that many Cuba-related activities are not reported under Cuba at all.
Some are reported as regional initiatives, others as global programs, and in a few particularly interesting cases, funding associated with Cuba has appeared under countries as unexpected as Afghanistan. In other words, searching for Country = Cuba inevitably misses part of the picture. So I decided to build a small Python utility that talks directly to the ForeignAssistance.gov API.
Instead of filtering by country, the application scans every available record looking for keywords such as
Cuba
Cuban
Cubans
inside the Activity Name and Activity Description fields, while excluding records whose associated country is actually Cuba.
The application retrieves paginated results from the API endpoint
/data-api/complete-data.json
and inspects two text fields from every record:
ACTIVITY_NAME_FIELD = "activity_name"
ACTIVITY_DESCRIPTION_FIELD = "activity_description"
Keyword detection is handled through a regular expression:
CUBA_PATTERN = re.compile(r"\bCuban?s?\b", re.IGNORECASE)
The goal is not to find records that are easy to retrieve by filtering "Cuba" as the recipient country. Instead, the script deliberately filters them out by checking both the country name and the country code.
def is_cuba_country(record):
country_name = safe_str(record.get("country_name")).lower()
if country_name == "cuba":
return True
country_code = safe_str(record.get("country_code")).upper()
if country_code in ("CUB", "CU"):
return True
return False
This allows the search to focus on mentions of Cuba occurring elsewhere in the database.
Once records have been collected, they can be filtered using multiple criteria without modifying the code.
Examples include:
recipient countries
fiscal years
funding agencies
managing agencies
implementing organizations
activity periods
For example:
python find_cuba_mismatches.py \
--countries Spain \
--funding-agency "Department of State" \
--out spain.csv
or
python find_cuba_mismatches.py \
--executing-org "Freedom House" \
--fiscal-years 2022 2023 2024 \
--out freedom_house.csv
This makes it possible to explore the dataset from several analytical perspectives.
Every matching record is exported into a CSV file containing information such as:
matched field
matched text
country
activity name
activity description
fiscal year
funding amount
implementing organization
funding agency
project identifiers
Well, as I hinted above, I found five U.S. Department of State projects—all reporting activity in FY2016—that are officially associated with Afghanistan and Pakistan, yet whose activity_name fields leave little doubt about the actual target of the funding:
Cuba Building a Foundation for Democratic Politic[s]
Fostering Cuban Socio Cultural Dialogue FOCUS Pr[ogram]
Internet Policy in Cuba I3PC
Cuba Emergente: A Latin Immersion Program for Cuba
Inclusive Cuba
In every one of these records, the activity_description field is redacted—thanks to the deliberately broad disclosure exemptions provided by the FATAA. In most cases, the implementing_partner field is also redacted. Where that information is available, however, it identifies an organization that has never, to my knowledge, been associated with Cuba-related democracy programs: Nationwide Supplies, L.P.
Is this simply a reporting error? Or does it reflect funds that were initially allocated to Afghanistan and Pakistan before being redirected elsewhere—i.e., Cuba? One project in particular caught my attention. Internet Policy in Cuba I3PC bears a remarkably similar name to the Internews Initiative for Internet Progress in Cuba (I3PC), a program launched in 2015 by Internews, a long-standing contractor for both USAID and the U.S. Department of State.
Back in 2014, following revelations about USAID's ill-fated ZunZuneo project, reports emerged explaining that similar social media technologies had also been tested in Afghanistan and Pakistan. Thus, these five projects found in ForeignAssistance.gov—and the one found in the federal audits involving Internews—postdate what became a major political scandal for the U.S. government.
I also found a USAID grant (7200AA23CA00030) awarded to Freedom House that is officially associated with Venezuela, yet whose description explicitly states:
"The activity supports activists from Guatemala, Nicaragua, Venezuela and Cuba in documenting and presenting evidence of their governments abuses to international organizations."
Without searching the description itself, associating this award with Cuba would require manually browsing Freedom House projects and finding it almost by serendipity. That is precisely why direct access to the ForeignAssistance.gov API is so valuable. Meanwhile, the corresponding USASpending page contains no reference to Cuba.
Another example is grant 7200AA20CA00037, awarded to the International Republican Institute, which is reported with a global scope. Finally, there is grant 7200AA23LA00002, awarded to Freedom House, which appears in ForeignAssistance.gov as a regional initiative ("Latin America and Caribbean Region"). Yet its description clearly states:
"USAID provides basic needs assistance to political prisoners, their families, and politically marginalized individuals in Cuba to alleviate the hardships they endure due to their political beliefs or efforts to exercise their fundamental freedoms."
In this particular case, the corresponding USASpending file does indicate that the grant is performed primarily—or mostly—in Cuba. However, another limitation emerges here: USASpending's keyword search does not index the "Place of Performance" field. Once again, this limitation disappears when querying the API directly, which is exactly what I already do in a separate Python application built specifically for USASpending.
If your research relies exclusively on the ForeignAssistance.gov website, you're effectively limited by the assumptions built into its search interface. Working directly against the API makes it possible to uncover records that would otherwise remain practically invisible. This could also be done by walking through the full dataset in CSV format, but I prefer working with APIs as the first source, so these CSV files operate as backup sources.