# /korea_customs/trades/search

`POST /api/korea_customs/trades/search`

Price: 20 credits

Korean export and import totals from the Korea Customs Service, grouped by HS commodity, partner country, customs office, port, continent, economic bloc, transaction type or the Korean nature classification, for a year or month range

## How to use it

Aggregated national trade statistics for South Korea, not shipment or company records. Pick `breakdown` first: it decides the grouping and which filters exist at all, and a filter that belongs to another breakdown is rejected with 422 rather than ignored. Values are thousands of US dollars and weight follows `weight_unit`, so read both off the row instead of assuming units; the country, continent, economic_bloc, customs_office and port breakdowns carry declaration counts and no weight at all. Rows arrive in the source's own order — by code on the commodity breakdowns, by trade value elsewhere — and it cannot be reversed, so on a wide breakdown such as item_country a small `count` returns the lowest HS chapters rather than the largest flows; narrow with hs_codes or countries instead of raising count. Names are Korean, and `hs_name` is absent on 10-digit rows and on some 6-digit ones, so resolve a commodity name through the commodities endpoint rather than reading the gap as an unnamed product. `country_code` is ISO alpha-2 and goes straight back into `countries`.

## Parameters

- `access-token` (string, required)

## Request body

- `timeout` (integer) — Max scrapping execution timeout (in seconds) (default: 300; min: 20; max: 1500)
- `breakdown` (string) — Dimension the totals are grouped by; it also decides which filters apply (default: "item"; one of: "item", "item_country", "nature", "nature_country", "new_nature", "new_nature_country", "country", "customs_office", "continent", "economic_bloc", "port", "transaction_type")
- `period_type` (string) — Whether period_from/period_to are years (YYYY) or months (YYYYMM) (default: "annual"; one of: "annual", "monthly")
- `period_from` (string, required) — First period, YYYY for annual and YYYYMM for monthly. Data starts at 2003 (examples: "2024", "202401"; minLength: 4; maxLength: 6)
- `period_to` (string, nullable) — Last period, YYYY for annual and YYYYMM for monthly. Omitted means one period (examples: "2024", "202412"; minLength: 4; maxLength: 6)
- `statistics_basis` (string) — Which date puts a shipment into a period — customs clearance or departure (default: "clearance_date"; one of: "clearance_date", "departure_date")
- `weight_unit` (string) — Unit the weight fields are reported in (default: "ton"; one of: "ton", "kg")
- `hs_codes` (string, nullable) — Korean HSK codes to restrict to, comma-separated. All of them must have the same length, one of 2, 4, 6 or 10 digits. Applies to the item and item_country breakdowns (examples: "0901", "0901,0902", "09")
- `hs_level` (string, nullable) — Digit level the commodity rows are grouped at, relative to hs_codes. Requires hs_codes: without a commodity filter the source returns 2-digit chapter rows whatever level is asked for. Omitted means the level of hs_codes itself (one of: "chapter", "heading", "subheading", "tariff_line")
- `countries` (string, nullable) — Partner countries to restrict to, comma-separated, either as the two-character codes this endpoint returns in country_code (ISO 3166-1 alpha-2, plus a few the source adds for international bodies) or as the Korean country names the source publishes. Applies to the country breakdown and to every *_country breakdown (examples: "US", "US,CN", "미국")
- `continent` (string, nullable) — Continent group to restrict to on the continent breakdown (one of: "asia", "north_america", "latin_america", "europe", "middle_east", "africa", "oceania", "daeyangju")
- `economic_bloc` (string, nullable) — Economic bloc to restrict to on the economic_bloc breakdown (one of: "APEC", "ASEAN", "ASEM", "CIS", "eastern_europe", "EFTA", "EU", "EU28", "GCC", "MERCOSUR", "NAFTA", "OECD", "southeast_asia")
- `customs_office_code` (string, nullable) — Head customs office code to restrict to on the customs_office breakdown. Look codes up through the codes endpoint (examples: "030"; minLength: 1)
- `customs_office_level` (string) — Whether the customs_office breakdown returns one row per head office or one row per local branch under it (default: "head_office"; one of: "head_office", "branch")
- `port_code` (string, nullable) — Port or airport code to restrict to on the port breakdown. Look codes up through the codes endpoint (examples: "KRPUS"; minLength: 1)
- `flow` (string) — Direction the nature, nature_country and transaction_type breakdowns are built for — the source keeps a separate classification per direction and returns one of them (default: "export"; one of: "export", "import")
- `transaction_type_code` (string, nullable) — Transaction type code to restrict to on the transaction_type breakdown. Look codes up through the codes endpoint (examples: "A"; minLength: 1)
- `category_codes` (string, nullable) — Nature classification codes to restrict to on the nature and new_nature breakdowns, comma-separated. Take them from category_code on an unfiltered call; all of them must sit at the same level of the classification (examples: "10000", "10000,20000", "11010000")
- `include_category_detail` (boolean) — Expand the nature and new_nature breakdowns to their deepest levels instead of the top two (default: false)
- `count` (integer, required) — Max number of rows to return (min: 1)

## Response

### 200 — Successful Response

- `@type` (string) (default: "KoreaCustomsTrade")
- `record_key` (string, required)
- `period` (string, required)
- `breakdown` (string, required) (one of: "item", "item_country", "nature", "nature_country", "new_nature", "new_nature_country", "country", "customs_office", "continent", "economic_bloc", "port", "transaction_type")
- `hs_code` (string, nullable)
- `hs_name` (string, nullable)
- `country_code` (string, nullable)
- `country_name` (string, nullable)
- `region_group_name` (string, nullable)
- `customs_office_code` (string, nullable)
- `customs_office_name` (string, nullable)
- `customs_branch_code` (string, nullable)
- `customs_branch_name` (string, nullable)
- `port_name` (string, nullable)
- `category_code` (string, nullable)
- `category_name` (string, nullable)
- `category_level` (integer, nullable)
- `flow` (string, nullable) (one of: "export", "import")
- `export_weight` (number, nullable)
- `export_value_thousand_usd` (number, nullable)
- `export_declarations` (integer, nullable)
- `import_weight` (number, nullable)
- `import_value_thousand_usd` (number, nullable)
- `import_declarations` (integer, nullable)
- `trade_balance_thousand_usd` (number, nullable)
- `weight_unit` (string, nullable) (one of: "ton", "kg")

## Errors

### 422 — Validation Error

The request body did not validate

What to do: Check the fields against this schema. A URN with the wrong prefix is the most common cause.

- `detail` (array)
  - `loc` (array, required)
  - `msg` (string, required)
  - `type` (string, required)
  - `input` (any)
  - `ctx` (object)

### 408

The request ran past its time limit

What to do: Raise `timeout` in the request body, up to the maximum this endpoint documents. Lowering `count` or turning off the `with_*` flags also helps, because less work finishes sooner.

### 412

The entity was not found, or a precondition failed

What to do: Retrying will not help: either the entity does not exist, or the input points at a different one.

### 429

Too many requests: a rate limit or a usage window is exhausted

What to do: When the response carries an X-Retry-After header, wait that many seconds and retry: the same number is in the body as `detail.retry_after`, and the limit clears once that window passes. The message in the body names the limit that was hit.

### 500

Something broke on our side

What to do: Retrying will not help. If it keeps happening, send us the X-Request-ID from the response headers.

### 529

Rate limit reached, or the endpoint is overloaded

What to do: Wait at least 30 seconds, then retry.

## Response envelope

Success: Array of objects (may be empty if no results)

Error: Error may coexist with partial results if it occurs mid-execution. Check X-Error header and status code.

Every response carries these headers:

- `X-Error` — Error message text (present only on error)
- `X-Request-ID` — Unique request identifier
- `X-Execution-Time` — Execution time in seconds
- `X-Result-Count` — How many records the body carries. 0 means an empty result, which is a normal answer and not by itself an error. A non-zero count can come back together with X-Error when the failure happened partway through — read this header and X-Error independently.
- `X-Total-Available-Results` — How many records exist for this query, when the endpoint can say. On a `dry_run` request this is the answer and the body is empty. It saturates: the endpoint's documented maximum means 'at least that many', any smaller number is exact.
- `X-Warning` — Present when the request body carried keys this endpoint does not document. They were ignored, so any filter you meant to apply through them did not apply. Check the spelling against this schema and retry.
- `X-Retry-After` — Seconds to wait before retrying. Present only on 429.

