Tarifflo
  • Pricing
  • Refunds
  • IEEPA Refunds
Sign In

Get started

  • Overview
  • Authentication
  • Errors
  • Rate limits

Build

  • REST API
  • Webhooks
  • MCP connector
  • Entry shape

Help

  • Request a feature

Build

REST API

Every endpoint lives under https://api.tarifflo.com/api/v1, takes JSON and authenticates with X-API-Key. Long-running work answers 202 with a jobId and delivers the result to your webhook.

ClassificationsBulk classificationTariff ratesAuditExport controlOriginEntries

Classifications

Classify one product to an HTS code for each destination. The US code is computed first, then mapped to the other destinations.

POST/api/v1/classificationsscope: classifications

Body

FieldTypeDescription
description
required
stringProduct description, 10 to 2000 characters.
destinations
required
string[]1 to 10 destination countries, 2-letter ISO codes.
name
optional
stringProduct name, 3 to 200 characters.
partialHtsCode
optional
stringA known 4- or 6-digit prefix that constrains the result.
webhookUrl
optional
stringPublic HTTPS URL that receives the signed result. Omit it to poll the GET endpoint instead.
Request
bash
curl -X POST "https://api.tarifflo.com/api/v1/classifications" \
  -H "X-API-Key: $TARIFFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Wireless over-ear headphones, plastic housing",
    "destinations": ["US", "CA"],
    "webhookUrl": "https://your-server.com/webhooks/tarifflo"
  }'
202 Accepted
json
{
  "jobId": "0193c1f2-...",
  "status": "queued",
  "destinationsQueued": 2,
  "totalClassifications": 2,
  "estimatedCompletionTime": 90,
  "message": "Classification job queued. ..."
}
GET/api/v1/classifications/{jobId}scope: classifications

Returns status queued, processing, complete (with data) or needs_info (with questions). To answer questions, add the answers to the description and classify again.

Bulk classification

Classify many short descriptions in one batch. Send up to 10,000 items inline, or upload a JSONL file of { "id", "text" } rows. The webhook carries a compact completion event; page through the results with GET.

POST/api/v1/classifications/batchscope: classifications

Body

Send exactly one of items or inputKey.

FieldTypeDescription
webhookUrl
required
stringHTTPS URL that receives classification_batch.completed.
items
optional
{ id?, text }[]Inline items, at most 10,000.
inputKey
optional
stringThe key of a JSONL file uploaded through /upload-url.
POST/api/v1/classifications/batch/upload-urlscope: classifications

Takes filename and returns uploadUrl and inputKey. PUT the file (up to 100 MB) to uploadUrl within 15 minutes, then POST the batch with the inputKey.

GET/api/v1/classifications/batch/{batchId}?page=0scope: classifications

Status, then results 1,000 per page once the batch is complete. Each result carries id, hts10, confidence and top5.

Tariff rates

Rate up to 50 lines. Each line returns the effective ad valorem rate with Chapter 99 stacking (Section 301, 232, IEEPA) and a cost breakdown, priced as of its date. Unknown field names are rejected, so a typo fails instead of returning a wrong rate.

POST/api/v1/tariff-ratesscope: tariff_rates

Body

FieldTypeDescription
rates
required
object[]1 to 50 lines, described below.
webhookUrl
required
stringHTTPS URL that receives tariff_rate.completed.
effectiveDate
optional
stringDefault date for every line, YYYY-MM-DD. Defaults to today.
loadingDate
optional
stringLoading date for time-based provisions, YYYY-MM-DD.
modeOfTransport
optional
stringocean, air, truck or rail.

rates[] item

FieldTypeDescription
htsCode
required
stringHTS code, dots optional.
origin
required
stringCountry of origin, 2-letter ISO code.
destination
required
stringDestination country, 2-letter ISO code.
value
optional
numberLine value in USD.
date
optional
stringThis line's date, YYYY-MM-DD.
metals
optional
objectSection 232 content shares: { steel?, aluminum?, copper? }, 0 to 100.
usContentPercentage
optional
numberUS-origin content share, 0 to 100.
steelCountryOfMelt
optional
stringMelt-and-pour country, 2-letter ISO code.
aluminumCountryOfSmelt
optional
stringSmelt-and-cast country, 2-letter ISO code.
uomQuantities
optional
objectQuantity per unit of measure, for specific duties.
appliedExclusions
optional
string[]Chapter 99 exclusion codes to apply.
chosenSpiCodes
optional
string[]Special program indicators to evaluate.
setKind
optional
stringFor a set provision: how the set is rated.
components
optional
object[]For a set provision: up to 50 components { code, description?, valueShare?, quantity? }.
Request
bash
curl -X POST "https://api.tarifflo.com/api/v1/tariff-rates" \
  -H "X-API-Key: $TARIFFLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "webhookUrl": "https://your-server.com/webhooks/tarifflo",
    "modeOfTransport": "ocean",
    "rates": [
      { "htsCode": "7318.15.8060", "origin": "CN", "destination": "US", "value": 25000, "metals": { "steel": 100 } }
    ]
  }'
GET/api/v1/tariff-rates/{jobId}scope: tariff_rates

Progress while running; once complete, data holds one result per line, the same object the webhook carries.

Audit

Run a pre-audit over an entry's documents. Upload each file to a signed URL (the bytes never pass through our API), then start a run with the file ids. PDF, Excel, Word, CSV and images are accepted; a file whose content does not match its type is refused.

POST/api/v1/audit/uploadsscope: audit

Takes filename and mimeType; returns fileId and uploadUrl, valid for 15 minutes. POST /api/v1/audit/uploads/bulk takes files (up to 50) and returns one upload per file.

POST/api/v1/audit/runsscope: audit

Body

FieldTypeDescription
config
required
string"pre" for a pre-audit. "post" (PSC) is not available yet.
fileIds
required
string[]1 to 50 uploaded file ids.
webhookUrl
optional
stringPublic HTTPS URL that receives the signed result. Omit it to poll the GET endpoint instead.
clientName
optional
stringClient the run is filed under in the dashboard.
requestName
optional
stringName of the run in the dashboard.
destinationCountries
optional
string[]2-letter ISO codes. Defaults to US.
GET/api/v1/audit/runs/{jobId}scope: audit

Stage progress while running; once complete, the same data as pre_audit.completed.

Export control

Determine the export-control classification (ECCN, or a foreign control code) of up to 50 products.

POST/api/v1/export-controlscope: eccn

Body

FieldTypeDescription
products
required
object[]1 to 50 products, described below.
webhookUrl
optional
stringPublic HTTPS URL that receives the signed result. Omit it to poll the GET endpoint instead.

products[] item

FieldTypeDescription
description
required
stringWhat the product is and does, 3 to 5000 characters.
origin
required
stringCountry of origin, 2-letter ISO code.
id
optional
stringYour reference, echoed on the result.
name
optional
stringProduct name.
context
optional
stringExtra technical detail.
GET/api/v1/export-control/{jobId}scope: eccn

Origin

Determine a finished good's country of origin under the rules of origin from its bill of materials. Each job takes minutes, so a request carries at most 5.

POST/api/v1/originscope: origin

Body

FieldTypeDescription
jobs
required
object[]1 to 5 determinations, described below.
webhookUrl
optional
stringPublic HTTPS URL that receives the signed result. Omit it to poll the GET endpoint instead.

jobs[] item

FieldTypeDescription
finished_good
required
object{ description, hts?, value_usd?, ex_works_price_usd? }
country_of_finished_production
required
stringWhere the good was finished, 2-letter ISO code.
bom
required
object[]1 to 200 lines { item, origin, hts?, value_usd? }.
import_into
optional
stringImporting country, 2-letter ISO code.
claimed_country_of_origin
optional
stringThe origin you claim, to be checked.
processing
optional
stringThe manufacturing steps.
id
optional
stringYour reference, echoed on the result.
GET/api/v1/origin/{jobId}scope: origin

Entries

File an entry summary with CBP. The entry is validated in full first: if anything is wrong, the response lists every error by its path in your payload and nothing is saved. A valid entry is saved, encoded and sent to CBP in the same request.

POST/api/v1/entriesscope: entries:write

Body

FieldTypeDescription
entry
required
EntryApiInputThe entry summary. See Entry shape for every field.
webhookUrl
optional
stringPublic HTTPS URL that receives entry.disposition when CBP answers.
  • Field reference: Entry shape.
  • An Idempotency-Key header is required. Repeating a key returns the first answer with Idempotent-Replayed: true and never files twice. A repeat while the first request is still filing returns 409 IDEMPOTENCY_KEY_IN_USE.
  • Entries need a live key for now: a test key (tflo_test_) is refused with 403 TEST_KEY_NOT_SUPPORTED.
  • CBP's answer arrives later as an entry.disposition event on your webhook. See Webhooks.
201 Created
json
{
  "efid": "0193c1f2-...",
  "entryNumber": 1234567,
  "shortJobId": "AB12CD",
  "status": "AWAITING_CBP"
}
422 Unprocessable Entity — nothing was filed
json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The entry is not valid; nothing was filed",
    "errors": [
      { "path": "lineItems[3].tariffRows[0].htsNumber", "message": "..." }
    ]
  }
}

If the entry was saved but could not be sent to CBP, the answer is 422 or 502 with code SUBMIT_FAILED and the efid of the saved entry.

Tarifflo

AI-driven trade automation for modern importers and brokers.

Get started free

Platform

  • Audit
  • ABI Filing
  • PGA
  • Suppliers

Customs

  • HTS Classification
  • Schedule B
  • ECCN
  • Tariff Rates
  • Customs Clearance

Developers

  • Docs
  • REST API
  • Webhooks
  • MCP Connector

Product

  • Pricing
  • Refunds
  • IEEPA Refunds
  • Explore data

Company

  • FAQ
  • Contact Us
  • Book a Demo

© 2026 Tarifflo, Inc. All rights reserved.

Privacy PolicyTerms & Conditions