World Bank Trade Data API: How to Pull Global Import and Export Statistics
The World Bank WITS database covers bilateral trade flows between 200+ countries. Here is how to access it programmatically and what the data actually contains.
The actor referenced in this article is live on Apify. Pay only for results delivered.
If you have ever tried to analyze international trade flows, you have probably bounced between three sources: the World Bank’s main indicators API, UN Comtrade, and the WITS portal. All three claim to have “trade data.” None of them have exactly the same numbers. The relationships between them are poorly documented.
This post explains what WITS actually contains, why it is different from the World Bank indicators API you may already be using, and how to pull bilateral trade flows, HS-code-level product data, and country partner rankings programmatically.
TL;DR: WITS (World Integrated Trade Solution) is the World Bank’s database for bilateral trade flows. It covers 200+ countries, 5,000+ HS product codes, and goes back to 1988. The base URL is
https://wits.worldbank.org/API/V1/SDMX/V21/rest/. Authentication is not required. For scheduled pulls, structured dataset output, or joining WITS data with World Bank development indicators, a managed scraper removes the rate-limit and format-handling overhead.
WITS vs. the Standard World Bank Indicators API
The World Bank has two distinct data systems that serve different purposes.
The World Bank Indicators API (api.worldbank.org/v2) contains aggregate economic statistics: GDP, population, FDI inflows, total exports as a share of GDP. These are single-country time series. There is no bilateral dimension. You can find out that India exported $776 billion in goods in 2022, but you cannot find out how much India exported specifically to Germany.
WITS is built on UN Comtrade data with additional cleaning and normalization by the World Bank. It stores bilateral trade flows: country A exported X dollars of product P to country B in year Y. This is the data you need for supply chain analysis, sanctions monitoring, or market entry research.
WITS also integrates tariff data (applied and bound rates), non-tariff measures, and trade facilitation indicators. The trade flow data is the most commonly used piece.
The API Endpoint Structure
WITS exposes an SDMX-compliant REST API. The base URL is:
https://wits.worldbank.org/API/V1/SDMX/V21/rest/
The core endpoint for trade flows is:
/data/DF_WITS_TradeStats_Tariff/A.{reporter}.{partner}.{product}.TRAINS/ALL/
Parameters:
Ais frequency (Annual){reporter}is the reporting country ISO3 code (e.g.,INDfor India){partner}is the partner country ISO3 code orWLDfor world total{product}is the HS code (e.g.,710231for cut diamonds) orTOTALfor all productsTRAINSis the data series name
For a simpler JSON interface, WITS also exposes:
https://wits.worldbank.org/API/V1/wits/country/{reporter}/tradestats/{flow}/partner/{partner}/product/{product}/year/{year}/
Where {flow} is imports or exports.
HS Code Filtering
Trade data is classified by the Harmonized System (HS), a 6-digit product taxonomy maintained by the World Customs Organization. The HS structure is hierarchical:
- 2-digit: Section (e.g.,
71= Natural or cultured pearls, precious stones) - 4-digit: Heading (e.g.,
7102= Diamonds) - 6-digit: Subheading (e.g.,
710231= Non-industrial diamonds, not mounted or set)
WITS accepts HS codes at any level of aggregation. Use TOTAL for all trade, a 2-digit code for a broad sector, or a full 6-digit code for a specific product.
Python: Pulling Total Imports from China to India
import requests
import pandas as pd
BASE = "https://wits.worldbank.org/API/V1/wits/country"
def get_bilateral_trade(reporter, partner, flow, year, product="TOTAL"):
"""
Pull trade flow between two countries for a given year.
reporter: ISO3 code of the reporting country (e.g., 'IND')
partner: ISO3 code of partner (e.g., 'CHN') or 'WLD'
flow: 'imports' or 'exports'
year: 4-digit year string (e.g., '2023')
product: HS code string or 'TOTAL'
"""
url = f"{BASE}/{reporter}/tradestats/{flow}/partner/{partner}/product/{product}/year/{year}/"
response = requests.get(url, headers={"Accept": "application/json"})
response.raise_for_status()
data = response.json()
rows = []
for item in data.get("TradeStats", {}).get("tradestats", []):
rows.append({
"reporter": item.get("r"),
"partner": item.get("p"),
"product": item.get("pc"),
"year": item.get("yr"),
"value_usd": float(item.get("TradeValue", 0)),
"quantity": item.get("Quantity"),
"unit": item.get("QuantityUnit"),
})
return pd.DataFrame(rows)
# India's total imports from China in 2023
df = get_bilateral_trade("IND", "CHN", "imports", "2023")
print(df.head())
print(f"\nTotal import value: ${df['value_usd'].sum():,.0f}")
The TradeValue field is in thousands of US dollars in WITS responses. Multiply by 1,000 to get the actual dollar figure. This catches many researchers off guard.
Getting Top Trading Partners for a Country
def get_top_partners(reporter, flow, year, top_n=20):
"""Get top N trading partners for a country."""
url = f"{BASE}/{reporter}/tradestats/{flow}/partner/ALL/product/TOTAL/year/{year}/"
response = requests.get(url, headers={"Accept": "application/json"})
response.raise_for_status()
data = response.json()
rows = []
for item in data.get("TradeStats", {}).get("tradestats", []):
partner = item.get("p")
if partner == "WLD":
continue # skip world aggregate
rows.append({
"partner": partner,
"value_usd": float(item.get("TradeValue", 0)) * 1000,
})
df = pd.DataFrame(rows)
df = df.sort_values("value_usd", ascending=False).head(top_n)
return df.reset_index(drop=True)
# Top 20 export destinations for India in 2023
partners = get_top_partners("IND", "exports", "2023", top_n=20)
print(partners.to_string(index=False))
Note that partner code WLD represents the world total. Always filter it out when ranking individual countries.
Yearly Trend for a Specific HS Code
def get_product_trend(reporter, partner, product, flow, years):
"""
Pull yearly trade values for a specific HS product.
years: list of year strings, e.g. ['2018','2019','2020','2021','2022','2023']
"""
records = []
for year in years:
url = f"{BASE}/{reporter}/tradestats/{flow}/partner/{partner}/product/{product}/year/{year}/"
response = requests.get(url, headers={"Accept": "application/json"})
if response.status_code == 404:
continue
response.raise_for_status()
data = response.json()
for item in data.get("TradeStats", {}).get("tradestats", []):
records.append({
"year": int(item.get("yr")),
"value_usd": float(item.get("TradeValue", 0)) * 1000,
})
df = pd.DataFrame(records).sort_values("year")
return df
# India's imports of semiconductor devices (HS 8541) from all partners, 2018-2023
trend = get_product_trend("IND", "WLD", "8541", "imports",
["2018", "2019", "2020", "2021", "2022", "2023"])
print(trend.to_string(index=False))
HS 8541 covers diodes, transistors, and semiconductor devices. Watching this number for India gives you a proxy for domestic electronics manufacturing demand, since India imports most of its semiconductor components.
Handling the API’s Quirks
Slow responses on broad queries. Requesting all products for all partners in a single call can take 10-30 seconds. The API does not support async or streaming. For bulk work, batch by year and product category rather than requesting everything at once.
Inconsistent year coverage. WITS data goes back to 1988 for some country pairs and only to 2010 for others. Coverage depends on what the reporting country submitted to UN Comtrade. A 404 does not always mean the data does not exist. It sometimes means the specific year/country combination has not been processed.
Data revisions. Countries revise trade statistics after initial submission. The 2022 data you pull in 2025 may differ slightly from what you pulled in 2023. If you are building a longitudinal database, record the pull date alongside the figures.
The partner code WLD is inconsistent. For some queries, WLD returns a world total. For others, it triggers a query that returns all individual partners. Test both behaviors for your specific endpoint.
Use Cases
Supply chain analysis. Map where specific components originate. Pull HS-level imports for the products you care about across multiple reporting countries to identify supplier concentration and alternative sourcing options.
Trade policy research. Compare bilateral flows before and after tariff changes, trade agreement implementations, or sanction regimes. WITS includes the year tariffs were applied, so you can measure trade response.
Market entry research. Before entering a market, understand who is currently supplying it. Pull imports of your product category into the target country and rank existing exporters by value. This shows you what you are competing against.
Sanctions monitoring. Track trade flows between sanctioned countries and their main partners over time. Sudden shifts in partner rankings for specific product categories can indicate sanctions circumvention patterns worth investigating.
Commodity price proxy. For bulk commodities, trade value divided by reported quantity gives an implied unit price. This is not as clean as spot prices, but for markets without liquid spot markets, the WITS unit value is often the only publicly available price signal.
The WITS API is not the most elegant interface you will use, but it covers data that is simply not available anywhere else at this price point (free). The bilateral, product-level granularity is what makes it valuable. The global-trade-data scraper wraps this API with retry handling, output normalization, and scheduled run support for teams that need this data on a recurring basis without managing the API quirks themselves.
Try the scraper referenced in this article — live on Apify, pay only for results.
Open global-trade-data on Apify →How to Scrape AmbitionBox Company Reviews and Ratings
AmbitionBox is India largest employer review platform with 300,000 companies. Learn how to pull ratings, review counts, salary data, and dimension scores as structured JSON without any official API.
AliExpress Product Data API: Prices, Ratings, and Orders in Python
AliExpress affiliate API has restricted coverage. Learn how to scrape AliExpress product listings for prices, ratings, order counts, and seller data as structured JSON — no affiliate approval needed.
ClinicalTrials.gov API v2: How to Search 500,000 Studies and Track Trial Status
ClinicalTrials.gov upgraded to a v2 REST API in 2024. Here is how to use it, what changed from v1, and how to build automated trial monitoring pipelines in Python.