Global Trade Alert
Global Trade Alert
API Quickstart

GTA data endpoints

Five endpoints cover the Global Trade Alert policy database: mappings resolves names to the numeric ids every filter expects, data answers filtered questions, ticker reports what changed, and the two impact-chains endpoints break exposure down to HS codes and sectors. Counts on this page drift as the database updates; a different number on your screen is not an error.

Updated 2026-07-12

Mappings: POST /api/v1/gta/mappings/

Business question: What vocabulary does the database use? Which jurisdiction and intervention-type ids do I need before I can filter anything else?

Every other GTA data endpoint filters on numeric ids, not names (implementer/affected take jurisdiction ids, intervention_types takes intervention-type ids). This endpoint resolves the names an analyst thinks in ("China", "Import tariff") to those ids; call it once and cache the result.

The request

curl -s -X POST https://api.globaltradealert.org/api/v1/gta/mappings/ \
  -H "Content-Type: application/json" \
  -H "Authorization: APIKey $GTA_API_KEY" \
  -d '{"keys": ["jurisdictions", "intervention_types"]}'
import os

import requests

API_KEY = os.environ["GTA_API_KEY"]

response = requests.post(
    "https://api.globaltradealert.org/api/v1/gta/mappings/",
    headers={"Authorization": f"APIKey {API_KEY}"},
    json={"keys": ["jurisdictions", "intervention_types"]},
)
response.raise_for_status()
records = response.json()

Result: 234 jurisdictions and 80 intervention types, complete in one call

As of 2026-07-11:

  • jurisdictions: 234 entries, e.g. {"id": 4, "name": "Afghanistan", "type": "country", "iso_code": "AFG"}
  • intervention_types: 80 entries, e.g. {"intervention_type_id": 2, "intervention_type_name": "State loan", ...}

Both lists return in full, in one call: every jurisdiction and every intervention type GTA currently tracks, not a sample.

Data Endpoint: POST /api/v2/gta/data/

Business question: How many harmful measures have hit critical raw materials since 2020, and is the trend rising or falling?

Critical raw materials sit under three overlapping pressures right now: EU policy, US mineral-security rules, and China's export licensing for the inputs feeding EV battery supply chains.

The request

curl -s -X POST https://api.globaltradealert.org/api/v2/gta/data/ \
  -H "Content-Type: application/json" \
  -H "Authorization: APIKey $GTA_API_KEY" \
  -d '{
        "request_data": {
          "query": "critical raw materials",
          "gta_evaluation": [1],
          "announcement_period": ["2020-01-01", null]
        },
        "limit": 100,
        "offset": 0
      }'
import os

import requests

API_KEY = os.environ["GTA_API_KEY"]

response = requests.post(
    "https://api.globaltradealert.org/api/v2/gta/data/",
    headers={"Authorization": f"APIKey {API_KEY}"},
    json={
        "request_data": {
            "query": "critical raw materials",
            "gta_evaluation": [1],
            "announcement_period": ["2020-01-01", None],
        },
        "limit": 100,
        "offset": 0,
    },
)
response.raise_for_status()
records = response.json()

Executed live 2026-07-11: 82 records returned.

Every parameter, against the live schema

  • request_data: the filter payload (object, required); everything narrowing the search lives inside it, while limit/offset outside it control how much comes back.
  • request_data.query: free-text search; a multi-word value like "critical raw materials" is matched as an exact phrase (also supports # for spelling variants, |/&/() for boolean combinations).
  • request_data.gta_evaluation: GTA's own harm rating (array of int, enum 1-5). 1 is Red, "harmful to trade", used alone rather than the broader 4 ("Harmful", which folds in Amber), since the question asks about harmful measures specifically.
  • request_data.announcement_period: date range on announcement date (array of 2 dates or nulls). ["2020-01-01", null] means 1 January 2020 to present; null on either end is unfiltered.
  • limit: page size (integer, sibling of request_data, default 10, range 0-1000). Set to 100: the probe returned 82 matches, comfortably under one page.
  • offset: pagination cursor (integer, sibling of request_data, default 0); see the access-pattern note for live proof it moves the window.

Result: harmful measures rising sharply since 2022

Grouping the 82 records by year announced (as of 2026-07-11): 2020: 0, 2021: 1, 2022: 5, 2023: 21, 2024: 19, 2025: 16, 2026 (partial year): 20. Harmful measures on critical raw materials have risen sharply since 2022, and the partial-2026 count already matches full prior years.

Access pattern: server-side filtering via request_data, then limit/offset pagination

The filtering happens on GTA's servers, not in your client: the three request_data keys above narrowed GTA's full corpus down to 82 rows, and only those 82 crossed the wire. Pagination handles anything larger; we verified live that offset actually moves the window (limit: 1, offset: 0 and offset: 1 returned two different interventions). For a result set exceeding 1000, the per-request maximum, increment offset by limit until a call returns fewer rows than requested.

Full-access keys receive four fields public-tier keys do not

This request ran against a production SGEPT key. Access-level 3 ("full") keys receive four fields limited keys do not: affected_products with prior/new tariff levels, full intervention_description text, state_act_source citations, and is_official_source. A trial key shows them thinner or absent, though row counts are unaffected either way.

Ticker: POST /api/v1/gta/ticker/

Business question: What changed in the GTA database this week?

An integration holding a GTA snapshot does not need to re-pull the whole corpus to stay current: it needs to know what moved since its last check. The ticker returns intervention update records, newest first, filterable to a date window.

The request

curl -s -X POST https://api.globaltradealert.org/api/v1/gta/ticker/ \
  -H "Content-Type: application/json" \
  -H "Authorization: APIKey $GTA_API_KEY" \
  -d '{
        "request_data": {
          "update_period": ["2026-07-04", null]
        },
        "limit": 500,
        "offset": 0,
        "sorting": "-datetime_modified"
      }'
import os

import requests

API_KEY = os.environ["GTA_API_KEY"]

response = requests.post(
    "https://api.globaltradealert.org/api/v1/gta/ticker/",
    headers={"Authorization": f"APIKey {API_KEY}"},
    json={
        "request_data": {
            "update_period": ["2026-07-04", None],
        },
        "limit": 500,
        "offset": 0,
        "sorting": "-datetime_modified",
    },
)
response.raise_for_status()
records = response.json()

Every parameter, against the live schema

  • request_data.update_period: date range on when the intervention the update belongs to was last updated (array of 2 dates or nulls); ["2026-07-04", null] means the days since 4 July 2026. This filters which interventions qualify, not which individual rows fall in the window; see the access-pattern note below.
  • limit: page size. The schema's own text advertises 1000 as the max, but live validation caps this endpoint at 500 (HTTP 400 above that); trust the live validator over the prose.
  • sorting: sort order. The schema types this as an array; live validation requires a plain string instead (HTTP 400 when sent as an array). Send "-datetime_modified" as a bare string, as printed here, for newest-first.
  • offset: same mechanism as the data endpoint.

Result: 316 updates in the last 7 days

In the 7 days to 11 July 2026: changed: 249 (description or fields edited); new: 51 (newly published); static: 16 (unchanged history row returned because its parent intervention qualified, see below); total 316.

Three most recent rows at execution time:

  • 2026-07-10T20:39:48.078557Z, new: Russia, zero export duties on wheat and meslin (1-7 July 2026) and on barley and corn (1-21 July 2026) (Green)
  • 2026-07-10T20:39:48.074756Z, changed: Russia, same state act, description revision (Green)
  • 2026-07-10T20:39:48.074756Z, new: Russia, same state act, a second row from the same batch update (Green)

Access pattern: delta-sync, poll the ticker, do not re-pull the corpus

Store the modified timestamp of the newest row processed; on the next poll, set update_period to [<that timestamp>, null] and pull only what changed. This scales to a daily cron job that pulls only the rows changed that day instead of a full re-download.

Worth designing around: update_period filters by when the intervention was touched, not the row's own modified timestamp: the 16 static rows here have modified timestamps as old as 2025-12-15 because they belong to interventions with other rows updated this week. Use status to distinguish new content (new/changed) from resurfaced history (static).

Impact Chains, Product: POST /api/v1/gta/impact-chains/product/

Business question: Which HS codes are exposed to electric-vehicle-related harmful measures, and imposed by whom?

Electric vehicles sit at the centre of the current industrial-policy wave: battery-input export controls, EV tariffs, subsidy races between the EU, US, and China. Scoping exposure needs HS-code granularity, not just "how many measures."

The request

curl -s -X POST https://api.globaltradealert.org/api/v1/gta/impact-chains/product/ \
  -H "Content-Type: application/json" \
  -H "Authorization: APIKey $GTA_API_KEY" \
  -d '{
        "request_data": {
          "query": "electric vehicle",
          "gta_evaluation": [1],
          "announcement_period": ["2025-01-01", null]
        },
        "limit": 1000,
        "offset": 0
      }'
import os

import requests

API_KEY = os.environ["GTA_API_KEY"]

response = requests.post(
    "https://api.globaltradealert.org/api/v1/gta/impact-chains/product/",
    headers={"Authorization": f"APIKey {API_KEY}"},
    json={
        "request_data": {
            "query": "electric vehicle",
            "gta_evaluation": [1],
            "announcement_period": ["2025-01-01", None],
        },
        "limit": 1000,
        "offset": 0,
    },
)
response.raise_for_status()
records = response.json()

Executed live 2026-07-11: 294 rows returned.

Parameters

query, gta_evaluation, limit, and offset work exactly as on the data endpoint. One choice needs explaining:

  • request_data.announcement_period: ["2025-01-01", null] was chosen by live probe: 2024-01-01 hits the endpoint's 1,000-row page cap, while 2025-01-01 returns 294, a complete set. See the access-pattern note for why this endpoint fills up faster than the data endpoint.

Result: lithium-ion accumulators lead the 191 exposed HS codes

Top 5 as of 2026-07-11 (of 191 distinct HS codes in the result): 850760, electric accumulators/lithium-ion (18); 870380, vehicles with only electric motor for propulsion (11); 280470, phosphorus (11); 850440, electrical static converters (6); 850133, electric motors and generators, DC 75-375kW (5).

Access pattern: one row per intervention-product pair, flattened server-side

The data endpoint returns one row per intervention, with affected_products nested as a list you must flatten to count by product. This endpoint flattens server-side: one row per (intervention, product) pair, ready to tally directly, at the cost of more rows per intervention.

Cost of that trade-off: the identical filter returns 111 interventions via the data endpoint against 294 rows here, roughly 2.6 product tuples per intervention. Widen the window and this compounds fast (the same query hits the 1,000-row cap at 2024-01-01); budget for pagination or narrow the filter to a single-page set, as done here.

Access tier: unlike the data endpoint above, both impact-chains endpoints require a full-access key (access level 3); a limited or demo-tier key gets 403 Forbidden here, not a thinner response.

Impact Chains, Sector: POST /api/v1/gta/impact-chains/sector/

Business question: Which sectors bear the burden of semiconductor-related harmful measures?

Semiconductor policy (chipmaking-equipment export controls, fab-capacity subsidy races, downstream restrictions) rarely stays confined to the chip industry. Sector-level aggregation shows which specific CPC sectors carry the exposure.

The request

curl -s -X POST https://api.globaltradealert.org/api/v1/gta/impact-chains/sector/ \
  -H "Content-Type: application/json" \
  -H "Authorization: APIKey $GTA_API_KEY" \
  -d '{
        "request_data": {
          "query": "semiconductor",
          "gta_evaluation": [1],
          "announcement_period": ["2025-11-01", null]
        },
        "limit": 1000,
        "offset": 0
      }'
import os

import requests

API_KEY = os.environ["GTA_API_KEY"]

response = requests.post(
    "https://api.globaltradealert.org/api/v1/gta/impact-chains/sector/",
    headers={"Authorization": f"APIKey {API_KEY}"},
    json={
        "request_data": {
            "query": "semiconductor",
            "gta_evaluation": [1],
            "announcement_period": ["2025-11-01", None],
        },
        "limit": 1000,
        "offset": 0,
    },
)
response.raise_for_status()
records = response.json()

Executed live 2026-07-11: 209 rows returned.

Parameters

All fields work as on the product impact-chains endpoint. The window ["2025-11-01", null] was chosen the same way: 2025-10-01 still hits the 1,000-row cap, while 2025-11-01 returns 209, complete.

Result: storage and computing carry 75% of the semiconductor burden

Top 5 as of 2026-07-11: 475, disks/tapes/solid-state non-volatile storage devices (101); 452, computing machinery and parts and accessories (55); 471, electronic valves and tubes/electronic components (11); 476, audio/video and other disks, tapes and physical media (10); 342, basic inorganic chemicals n.e.c. (8). The 209 rows collapse to just 18 distinct sectors; the two storage/computing sectors alone (475 and 452) account for 156 of the 209 tuples, 75%.

Access pattern: the same tuple pattern, at CPC-sector granularity

The product endpoint's pattern, one level up: one row per (intervention, sector) pair, server-flattened the same way. Use this endpoint for "which industries are exposed" rather than "which specific goods": sector counts are lower-cardinality and chart more cleanly (18 distinct sectors here vs. 191 HS codes at product level), at the cost of customs-level specificity.

Access tier: the same full-access requirement as the product endpoint above applies here; a limited or demo-tier key gets 403 Forbidden rather than a working call.

For agents and LLMs: this page as markdown, llms.txt index, OpenAPI schema.