Skip to content

API overview

FIRMSapi looks up, searches and validates U.S. CBP FIRMS codes: the 4-character facility codes for piers, container freight stations, bonded warehouses, foreign trade zones and exam stations. The full parameter and schema reference is generated from the code: see the API reference.

https://api.firmsapi.com/v1

All requests and responses are JSON over HTTPS.

Send your API key in the x-api-key header:

Terminal window
curl https://api.firmsapi.com/v1/firms/E430 -H "x-api-key: $FIRMSAPI_KEY"

There are two kinds of key, both created in the portal:

Key Data Counts toward your plan
fapi_test_… Fixture data: a small sample of real FIRMS rows with approximate coordinates. Not for filing. Never
fapi_live_… The latest CBP FIRMS list Yes, see Usage and quotas

Test keys behave exactly like live keys, including plan limits on Pro and Enterprise endpoints, so you can build and test your integration before you go live. Keys are shown once when you create them; store them like passwords and never ship them in browser or mobile code.

Every response has a meta object:

{
"data": { "code": "E430", "name": "MAHER TERMINAL", "status": "active", "...": "..." },
"meta": {
"data_as_of": "2026-10-23",
"source": "U.S. Customs and Border Protection (CBP) FIRMS code list",
"mode": "live",
"build_id": "20261023T060000Z-3f9a1c2e",
"request_id": "Hc1x0jYxIAMEbXw="
}
}
  • data_as_of: the date of the CBP FIRMS list the answer comes from.
  • source: where the data comes from. Test mode says it is fixture data.
  • mode: live or test, from the key you used.
  • request_id: quote it when you contact support. It is also in the x-request-id header.

Lists add meta.count, and paged lists add meta.next_cursor (pass it back as cursor; null means the last page).

Errors use one shape, described in Errors:

{ "error": { "code": "quota_exceeded", "message": "…", "links": { "docs": "…", "buy_pack": "…" } }, "meta": { … } }
Endpoint What it does Plans
GET /firms/{code} Look up a code, with the other codes at the same address All
GET /search Fuzzy search by name and/or address All
GET /autocomplete Prefix matches for type-ahead inputs All
GET /nearby Facilities near a point, another facility or an address All
POST /validate Pre-filing checks for a code All
POST /batch Up to 100 lookups, validations and searches Pro, Enterprise
GET /ports, GET /ports/{port} CBP ports and their facilities All
GET /changes Feed of FIRMS list changes Pro, Enterprise
/watchlists Codes you watch for changes Enterprise
  • Codes are not always a letter and three digits. About 31% are not, and some start with a digit. The only safe format check is four letters or digits.
  • Deleted codes stay in the data with status: "deleted", so you can tell why a filing was rejected. Search and nearby return active codes unless you pass include_deleted=true.
  • Placeholders are flagged, not removed. CBP’s “DO NOT USE” rows and CBP test records have junk: true. Lookups return them with a warning; search and nearby never do.
  • Many addresses carry several codes. A lookup lists the others in same_address.

Requests are rate limited across the API to protect the service (about 50 per second, bursts of 100). If you need more, contact us. Monthly call limits depend on your plan: see Usage and quotas.