MOD.DOCSDeveloper documentation

Build production trade
infrastructure.

Authentication, endpoints, webhooks, errors, SDKs, and changelog. Everything required to wire TariffOS into ERPs, quoting engines, and freight platforms.

0101 · Introduction

The TariffOS API

The TariffOS API is a JSON over HTTPS interface for tariff intelligence, landed-cost computation, and trade compliance. It is the same engine that powers our dashboards, AI assistant, and enterprise integrations — exposed as primitives you can wire into any quoting engine, ERP, or freight platform.

All requests are made against https://api.tariffos.com and require a Bearer token. Responses are JSON, latencies are sub-100ms p95, and the surface area is versioned via the URL.

HEADS UP
These docs describe a preview of the public API. Field names are stable but coverage of less-common HS chapters is still rolling out. Production keys are granted on enterprise plans.
01.501.5 · Try it

Run a sample request right here

The console below executes against an in-browser sandbox using mocked responses modeled on the production schema. Swap the placeholder API key for a real sk_test_… sandbox key to hit sandbox.api.tariffos.com directly.

Try it · Sandbox TOSMock
GEThttps://sandbox.api.tariffos.com/v2/tariff/lookup?hs=8703.80&origin=CN&destination=US

Demo only. Production keys grant per-workspace scope.

Response
[ awaiting request ]
Configure inputs and press Send request.
DEMO ONLY
No traffic leaves your browser. Responses are deterministic mocks shaped from your inputs, not live tariff data.
0202 · Quickstart

From zero to landed cost in 60 seconds

  1. Request a key from enterprise sales or hit our self-serve sandbox.
  2. Export it as TARIFFOS_KEY.
  3. Call POST /v2/landed-cost with an HS code and shipment value.
  4. Subscribe to tariff.changed webhooks for ongoing intelligence.
POST /v2/landed-cost · bash● 47ms · 200 OK
curl https://api.tariffos.com/v2/landed-cost \
  -H "Authorization: Bearer $TARIFFOS_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: shp_4kJ29fA" \
  -d '{
    "hs_code": "8703.80",
    "origin": "CN",
    "destination": "US",
    "value_usd": 48000,
    "incoterm": "FOB"
  }'
0303 · Environments

Sandbox and production

EnvironmentBase URLDataRate limit
Sandboxhttps://sandbox.api.tariffos.comFrozen Q1 dataset60 r/min
Productionhttps://api.tariffos.comLive, multi-regionBy plan
EU residencyhttps://eu.api.tariffos.comLive, EU-only egressBy plan
0404 · Versioning

URL-versioned, additive by default

Major versions live in the URL (/v2/…). Field additions and new enum values are non-breaking. Removals or rename ship as /v3 with a 12-month overlap and deprecation headers.

DEPRECATION
Endpoints scheduled for removal return Sunset and Deprecation response headers per RFC 8594.
AUTHAUTH · 01

Authentication overview

TariffOS supports three auth modes. Use API keys for server-side integrations, OAuth 2.0 for third-party apps acting on behalf of a tenant, and request signing when calling from untrusted edges.

ModeUse caseHeader
API keyServer → APIAuthorization: Bearer sk_live_…
OAuth 2.0Third-party appAuthorization: Bearer <access_token>
HMAC signingEdge / browserX-TariffOS-Signature: t=…,v1=…
AUTHAUTH · 02

API keys

Keys are scoped to an environment and a workspace. Live keys are prefixed sk_live_; sandbox keys are sk_test_. Treat keys as secrets — store them in your platform's secret manager, never in source control.

Authorization header · http
GET /v2/tariff/lookup?hs=8703.80&origin=CN&destination=US HTTP/1.1
Host: api.tariffos.com
Authorization: Bearer sk_live_REPLACE_ME
Accept: application/json
ROTATION
Rotate keys quarterly. Suspended keys return 401 key_revoked within 5 seconds globally.
AUTHAUTH · 03

OAuth 2.0 (Authorization Code + PKCE)

For partner apps acting on behalf of a TariffOS tenant. Standard OAuth 2.1 with PKCE; access tokens expire in 1 hour, refresh tokens in 60 days.

EndpointPath
Authorizehttps://auth.tariffos.com/oauth/authorize
Tokenhttps://auth.tariffos.com/oauth/token
Revokehttps://auth.tariffos.com/oauth/revoke
Discovery/.well-known/openid-configuration
ScopeGrants
tariff:readRead tariff lookups + landed cost
shipments:writeCreate shipment intents and quotes
alerts:manageSubscribe and manage webhook endpoints
adminFull workspace administration
AUTHAUTH · 04

Request signing (HMAC-SHA256)

For environments where a key cannot be embedded (browser SDK, partner edge), sign each request with a short-lived signing secret derived server-side.

Canonical signing string · text
{timestamp}.{method}.{path}.{sha256(body)}

X-TariffOS-Signature: t=1714694400,v1=4f2e…c0a1
GET/v2/tariff/lookup

Tariff lookup

Resolve the live applicable duty rate for a given HS code, origin, and destination — including special programs (Section 232/301, IEEPA, reciprocal tariffs).

FieldTypeReqDescription
hsstringrequiredHS code, 6–10 digits.
originstringrequiredISO 3166-1 alpha-2 origin country.
destinationstringrequiredISO 3166-1 alpha-2 destination country.
as_ofstringoptionalISO date — historical lookup.
Request · http
GET /v2/tariff/lookup?hs=8703.80&origin=CN&destination=US
Response · 200 · json● 47ms
{
  "hs_code": "8703.80",
  "origin": "CN",
  "destination": "US",
  "applied_rate_pct": 44.5,
  "components": [
    { "kind": "mfn",         "rate_pct": 2.5  },
    { "kind": "section_301", "rate_pct": 25.0 },
    { "kind": "reciprocal",  "rate_pct": 17.0 }
  ],
  "effective": "2025-04-01",
  "_meta": { "latency_ms": 38, "version": "v2.4.1" }
}
POST/v2/landed-cost

Landed cost

Full landed-cost decomposition: duty, fees (MPF/HMF/VAT), freight, brokerage, and FTA-eligible savings. Returns alternative-sourcing recommendations when material savings exist.

FieldTypeReqDescription
hs_codestringrequiredHS code.
originstringrequiredISO origin country.
destinationstringrequiredISO destination country.
value_usdnumberrequiredCommercial invoice value.
incotermstringoptionalFOB, CIF, DDP, EXW, …
weight_kgnumberoptionalUsed for freight modeling.
Request · http
POST /v2/landed-cost
Content-Type: application/json
Idempotency-Key: shp_4kJ29fA

{
  "hs_code": "8703.80",
  "origin": "CN",
  "destination": "US",
  "value_usd": 48000,
  "incoterm": "FOB"
}
Response · 200 · json● 47ms
{
  "shipment_id": "shp_4kJ29fA",
  "currency": "USD",
  "value": 48000.00,
  "duty": {
    "mfn": 1200.00,
    "section_301": 12000.00,
    "reciprocal": 8160.00,
    "total": 21360.00
  },
  "fees": { "mpf": 538.40, "hmf": 60.00 },
  "freight_estimate": 2840.00,
  "brokerage": 425.00,
  "total_landed": 73223.40,
  "fta_eligible": [],
  "recommendations": [
    { "action": "shift_origin", "to": "VN", "savings_usd": 8420.00 }
  ]
}
POST/v2/classify

AI classification

Map a free-text product description (and optional attributes) to the most likely HS code, with confidence and citations to the explanatory notes.

FieldTypeReqDescription
descriptionstringrequiredPlain-text product description.
attributesobjectoptionalMaterial, intended use, weight, etc.
destinationstringoptionalTunes classification to local nomenclature.
Request · http
POST /v2/classify

{
  "description": "Cordless impact driver, lithium-ion, 18V, with carry case",
  "attributes": { "powered_by": "battery" },
  "destination": "US"
}
Response · 200 · json● 47ms
{
  "candidates": [
    { "hs_code": "8467.21", "confidence": 0.92, "title": "Drills, electromechanical, hand-held, …" },
    { "hs_code": "8467.29", "confidence": 0.05, "title": "Other tools, with self-contained electric motor" }
  ],
  "citations": ["WCO Explanatory Note 84.67 (II)(B)"],
  "_meta": { "model": "tariff-classifier-v3", "latency_ms": 612 }
}
GET/v2/fta/eligibility

FTA eligibility

Check whether a shipment qualifies for preferential treatment under any active free trade agreement between the origin and destination.

FieldTypeReqDescription
hsstringrequiredHS code.
originstringrequiredOrigin ISO.
destinationstringrequiredDestination ISO.
Request · http
GET /v2/fta/eligibility?hs=6109.10&origin=VN&destination=US
Response · 200 · json● 47ms
{
  "eligible_agreements": [],
  "near_misses": [
    {
      "agreement": "GSP",
      "blocked_by": "expired_2020-12-31",
      "would_save_pct": 16.5
    }
  ]
}
GET/v2/origin/rules

Rules of origin

Returns the substantial-transformation tests and regional value content thresholds for an HS code under a given agreement.

FieldTypeReqDescription
hsstringrequiredHS code.
agreementstringrequiredUSMCA, CPTPP, EU-VN, …
Request · http
GET /v2/origin/rules?hs=8703.80&agreement=USMCA
Response · 200 · json● 47ms
{
  "agreement": "USMCA",
  "tests": [
    { "kind": "tariff_shift", "from": "8708", "to": "8703" },
    { "kind": "rvc",          "method": "net_cost", "threshold_pct": 75 },
    { "kind": "labor_value",  "threshold_pct": 40, "wage_floor_usd": 16 }
  ]
}
POST/v2/scenarios/simulate

Scenario simulate

Run a what-if across one or many shipments with hypothetical tariff schedules, sourcing changes, or FX shocks. Returns deltas and worst/best case ranges.

FieldTypeReqDescription
shipmentsarrayrequiredArray of shipment intents.
overridesobjectrequiredTariff, FX, or sourcing overrides.
Request · http
POST /v2/scenarios/simulate

{
  "shipments": [{ "hs_code": "8703.80", "origin": "CN", "destination": "US", "value_usd": 48000 }],
  "overrides": { "reciprocal_tariff_pct": { "CN": 30 } }
}
Response · 200 · json● 47ms
{
  "baseline_total_landed": 73223.40,
  "scenario_total_landed": 79463.40,
  "delta_usd": 6240.00,
  "delta_pct": 8.52
}
GET/v2/changes/since

Tariff changes

Pull all schedule changes that affect your subscribed HS codes / lanes since a given timestamp. Designed for nightly batch reconciliation.

FieldTypeReqDescription
sincestringrequiredISO 8601 timestamp.
lanesstringoptionalComma-separated origin>destination pairs.
Request · http
GET /v2/changes/since?since=2025-04-01T00:00:00Z&lanes=CN>US,VN>US
Response · 200 · json● 47ms
{
  "changes": [
    {
      "id": "chg_91kfA2",
      "kind": "rate_change",
      "hs": "8703.80",
      "lane": "CN>US",
      "from_pct": 27.5,
      "to_pct": 44.5,
      "effective": "2025-04-09",
      "source": "USTR Federal Register 90 FR 12345"
    }
  ],
  "next_cursor": "cur_…"
}
REALTIMEREALTIME · 01

Webhooks

Subscribe an HTTPS endpoint to receive event notifications. Deliveries are signed with HMAC-SHA256 over the raw request body and a per-endpoint signing secret. Retries follow exponential backoff (1m → 24h) for up to 72 hours.

Subscribe an endpoint · bash
curl https://api.tariffos.com/v2/alerts/subscribe \
  -H "Authorization: Bearer $TARIFFOS_KEY" \
  -d '{
    "url": "https://hooks.acme.com/tariffos",
    "events": ["tariff.changed", "shipment.recommendation"],
    "filters": { "lanes": ["CN>US", "VN>US"] }
  }'
Verify the signature (Node.js) · ts
import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(req: { headers: Record<string,string>, rawBody: string }, secret: string) {
  const sig = req.headers["x-tariffos-signature"]; // t=...,v1=...
  const parts = Object.fromEntries(sig.split(",").map(p => p.split("=")));
  const expected = createHmac("sha256", secret)
    .update(`${parts.t}.${req.rawBody}`)
    .digest("hex");
  return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
REALTIMEREALTIME · 02

Event reference

EventFires when
tariff.changedA duty rate on a subscribed lane is updated.
policy.announcedA policy memo is published before becoming effective.
fta.changedAn agreement enters/exits force or rules update.
shipment.recommendationAn optimization is found for a recurring lane.
alert.exposure_breachAggregate exposure crosses a configured threshold.
REALTIMEREALTIME · 03

Streaming API (SSE)

For low-latency dashboards, stream the same events over Server-Sent Events on GET /v2/stream. Authenticate with a short-lived stream token issued by POST /v2/stream/token.

Open the stream · ts
const es = new EventSource(`https://api.tariffos.com/v2/stream?token=${streamToken}`);
es.addEventListener("tariff.changed", (e) => {
  const change = JSON.parse(e.data);
  console.log("New rate:", change.to_pct);
});
OPSOPS · 01

Errors

Errors return a stable shape. The code field is the contract — do not branch on message, which is for humans.

Error envelope · json
{
  "error": {
    "code": "tariff_not_found",
    "message": "No tariff schedule for HS 9999.99 on lane XX>US.",
    "request_id": "req_01HZ…",
    "doc_url": "https://docs.tariffos.com/errors#tariff_not_found"
  }
}
StatusCodeMeaning
400invalid_requestMalformed input or missing required field.
401unauthorizedMissing or invalid API key.
403scope_requiredToken lacks the required OAuth scope.
404tariff_not_foundNo schedule for the requested HS / lane.
409idempotency_conflictSame Idempotency-Key, different payload.
422validation_failedSchema valid, business rule violated.
429rate_limitedThrottled — see Retry-After header.
500internal_errorSurface as retryable; we are paged.
503upstream_unavailableA government data source is degraded.
OPSOPS · 02

Rate limits

PlanSustainedBurstConcurrency
Sandbox60 r/min120 r/min4
Growth1,200 r/min3,000 r/min32
EnterpriseCustomCustomCustom

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. On 429, respect Retry-After.

OPSOPS · 03

Idempotency

All POST endpoints accept an Idempotency-Key header (UUID v4 recommended). Replays within 24 hours return the original response, including status code. Different payloads under the same key return 409 idempotency_conflict.

OPSOPS · 04

Pagination

List endpoints use cursor pagination. Pass ?limit=100&cursor=… — responses include next_cursor when more pages exist. Maximum page size is 500.

RESRES · 01

SDKs & libraries

LanguagePackageStatus
TypeScript / Node@tariffos/sdkGA
PythontariffosGA
Gogithub.com/tariffos/tariffos-goBeta
Javacom.tariffos:sdkBeta
.NETTariffOS.SdkPreview
RubytariffosPreview
RESRES · 02

Postman collection

Import the live collection — every endpoint, pre-request scripts for HMAC signing, and example sandbox keys.

Collection URL · text
https://docs.tariffos.com/postman/tariffos.postman_collection.json
RESRES · 03

OpenAPI 3.1 specification

The full machine-readable spec — generate clients, mock servers, or contract tests directly from it.

Spec · text
https://api.tariffos.com/v2/openapi.json
sha256: 9f4c…1ab2
RESRES · 04

Changelog

  • 2025-04-12ADDEDReciprocal tariff component

    Tariff lookup and landed cost now decompose the new reciprocal-tariff component. Existing fields are unchanged.

  • 2025-03-30ADDEDEU residency endpoint

    eu.api.tariffos.com — all data plane traffic stays within EU regions.

  • 2025-02-18CHANGEDStable webhook signing v1

    x-tariffos-signature now uses the stable t=…,v1=… format. Legacy x-signature is deprecated for removal 2025-08-01.

  • 2025-01-04ADDEDScenario simulate endpoint

    POST /v2/scenarios/simulate — model tariff, FX, and sourcing overrides across portfolios.

Need a sandbox key?

Approval in 24 hours. Production keys gated to enterprise plans.

Request access →