Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Eckari Com Logistics API
version: registry-5a21aa0a8dd1e910
contact:
name: Eckari
url: https://eckari.com
x-guidance: 'Every operation is a deterministic capability. Call GET routes with the documented path/query parameters. Pay per call either with an Eckari account key (Authorization: Bearer ek_live_…) or accountlessly via x402: an unpaid request returns HTTP 402 with a PAYMENT-REQUIRED header (x402 v2, Base USDC); retry with PAYMENT-SIGNATURE. Responses are {data, meta} with provenance (meta.source) and freshness (meta.freshness). Use x-eckari-capability.discovery.use_when / do_not_use_when to pick the right operation; resolve a company name to a company number with the search operation before calling per-company operations.'
description: 'Operations tagged logistics across 2 of this provider''s published API definitions: eckari-com-openapi.json, eckari-com-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.eckari.com
tags:
- name: logistics
paths:
/v1/parcels/detect-carrier:
get:
operationId: parcel_detect_carrier
summary: Detect the carrier from a tracking number
description: 'Identify which carrier issued a tracking number using a deterministic, versioned signature set - prefixes, lengths, carrier check digits and UPU S10 structure - returning the carrier, how distinctive the match is, every ranked candidate with typed evidence, and the parsed S10 details. No upstream call and no carrier account required.
**Use when:**
- Which carrier is this tracking number from?
- You have a tracking number but no carrier and need to route the lookup.
- You need to validate that a tracking number is well formed before storing it.
- You need to disambiguate a numeric tracking number between several carriers.
- You need to parse a UPU S10 international postal item id (service, serial, origin country).
**Do not use when:**
- You need tracking events, status or delivery estimates - not yet available.
- You need to validate a postal address - not supported.
- You need a guaranteed single answer - formats overlap, so several candidates can be returned.
- The carrier is outside the covered set - named carrier formats are UPS, FedEx, USPS, DHL Express, DHL eCommerce, DPD, Amazon Logistics and Canada Post, plus any UPU S10 postal item whose origin country maps to a designated postal operator (Royal Mail, Deutsche Post, La Poste, PostNL, Australia Post, Canada Post, China Post, Japan Post, India Post and other national posts). Regional carriers such as Evri, Yodel, GLS, Poste-style local couriers and Chinese e-commerce lines are not covered.
- You are treating an empty candidates list as "invalid number" - read formats_matched first - 0 means no covered format matched, above 0 means a covered format matched but its check digit failed.
- If the user has asked you to inspect a specific website, page or URL, use your browsing tool instead — this capability only returns the Eckari carrier signature engine record.'
tags:
- logistics
parameters:
- name: tracking_number
in: query
required: true
schema:
type: string
description: Tracking or consignment number. Spaces and hyphens are removed and letters upper-cased before matching (4-40 letters and digits after normalisation). Digits and letters are never altered.
minLength: 4
maxLength: 60
pattern: ^[A-Za-z0-9 -]+$
description: Tracking or consignment number. Spaces and hyphens are removed and letters upper-cased before matching (4-40 letters and digits after normalisation). Digits and letters are never altered.
- name: origin_country
in: query
required: false
schema:
type: string
description: Optional ISO 3166-1 alpha-2 origin country hint. Used only as a small tie-breaker; it never invents a candidate.
pattern: ^[A-Za-z]{2}$
description: Optional ISO 3166-1 alpha-2 origin country hint. Used only as a small tie-breaker; it never invents a candidate.
- name: destination_country
in: query
required: false
schema:
type: string
description: Optional ISO 3166-1 alpha-2 destination country hint. Used only as a small tie-breaker; it never invents a candidate.
pattern: ^[A-Za-z]{2}$
description: Optional ISO 3166-1 alpha-2 destination country hint. Used only as a small tie-breaker; it never invents a candidate.
responses:
'200':
description: Successful capability result
content:
application/json:
schema:
type: object
required:
- data
- meta
properties:
data:
$ref: '#/components/schemas/parcel_detect_carrier_output'
meta:
$ref: '#/components/schemas/ResponseMeta'
examples:
ups_1z_synthetic_format_2026-08-18:
summary: ups_1z_synthetic_format_2026-08-18
value:
data:
carrier:
id: ups
name: UPS
match_strength: distinctive
match_score: 0.98
candidates:
- carrier_id: ups
carrier_name: UPS
match_score: 0.98
match_strength: distinctive
format_id: ups_1z
evidence:
prefix: 1Z
length: 18
check_digit: ups_mod10
s10_origin_country: null
country_hint: null
input:
original: 1Z 879E93 03 4683 4440
normalised: 1Z879E930346834440
formats_matched: 1
upu_s10: null
signature_version: 1.1.0
meta:
capability: parcel.detect_carrier
version: 2.0.0
source: eckari_carrier_signatures
freshness: static
upu_s10_royal_mail_synthetic_format_2026-08-18:
summary: upu_s10_royal_mail_synthetic_format_2026-08-18
value:
data:
carrier:
id: royal_mail
name: Royal Mail
match_strength: distinctive
match_score: 0.9
candidates:
- carrier_id: royal_mail
carrier_name: Royal Mail
match_score: 0.9
match_strength: distinctive
format_id: upu_s10
evidence:
prefix: RB
length: 13
check_digit: upu_s10
s10_origin_country: GB
country_hint: null
input:
original: RB123456785GB
normalised: RB123456785GB
formats_matched: 1
upu_s10:
service_indicator: RB
service_type: letter_post_registered
serial: '12345678'
check_digit_valid: true
origin_country: GB
signature_version: 1.1.0
meta:
capability: parcel.detect_carrier
version: 2.0.0
source: eckari_carrier_signatures
freshness: static
fedex_express_12_synthetic_format_2026-08-18:
summary: fedex_express_12_synthetic_format_2026-08-18
value:
data:
carrier:
id: fedex
name: FedEx
match_strength: weak
match_score: 0.8
candidates:
- carrier_id: fedex
carrier_name: FedEx
match_score: 0.8
match_strength: weak
format_id: fedex_express_12
evidence:
prefix: null
length: 12
check_digit: fedex_express_mod11
s10_origin_country: null
country_hint: null
input:
original: '986578788855'
normalised: '986578788855'
formats_matched: 1
upu_s10: null
signature_version: 1.1.0
meta:
capability: parcel.detect_carrier
version: 2.0.0
source: eckari_carrier_signatures
freshness: static
'400':
description: Invalid input (INVALID_INPUT)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
'401':
description: Authentication failed (AUTHENTICATION_REQUIRED, INVALID_API_KEY)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
'402':
description: Payment required (PAYMENT_REQUIRED, PAYMENT_FAILED, BUDGET_EXCEEDED, BILLING_REQUIRED). x402 challenge headers are attached.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
'403':
description: Forbidden (PROJECT_DISABLED, CAPABILITY_NOT_ALLOWED)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
'404':
description: Not found (NOT_FOUND)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
'422':
description: Unprocessable (UNSUPPORTED_REGION, AMBIGUOUS_IDENTIFIER)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
'429':
description: Upstream rate limited (UPSTREAM_RATE_LIMITED)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
'500':
description: Internal error (INTERNAL_ERROR)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
'503':
description: Unavailable (UPSTREAM_UNAVAILABLE, CAPABILITY_UNAVAILABLE, LICENCE_RESTRICTED)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
security:
- eckariApiKey: []
- x402: []
x-payment-info:
price:
mode: fixed
currency: USD
amount: '0.001'
protocols:
- x402: {}
x-eckari-capability:
id: parcel.detect_carrier
version: 2.0.0
lifecycle: beta
pricing:
currency: USD
account:
enabled: true
unit_price: '0.001'
x402:
enabled: true
unit_price: '0.001'
discovery:
title: Detect the carrier from a tracking number
description: Identify which carrier issued a tracking number using a deterministic, versioned signature set - prefixes, lengths, carrier check digits and UPU S10 structure - returning the carrier, how distinctive the match is, every ranked candidate with typed evidence, and the parsed S10 details. No upstream call and no carrier account required.
use_when:
- Which carrier is this tracking number from?
- You have a tracking number but no carrier and need to route the lookup.
- You need to validate that a tracking number is well formed before storing it.
- You need to disambiguate a numeric tracking number between several carriers.
- You need to parse a UPU S10 international postal item id (service, serial, origin country).
do_not_use_when:
- You need tracking events, status or delivery estimates - not yet available.
- You need to validate a postal address - not supported.
- You need a guaranteed single answer - formats overlap, so several candidates can be returned.
- The carrier is outside the covered set - named carrier formats are UPS, FedEx, USPS, DHL Express, DHL eCommerce, DPD, Amazon Logistics and Canada Post, plus any UPU S10 postal item whose origin country maps to a designated postal operator (Royal Mail, Deutsche Post, La Poste, PostNL, Australia Post, Canada Post, China Post, Japan Post, India Post and other national posts). Regional carriers such as Evri, Yodel, GLS, Poste-style local couriers and Chinese e-commerce lines are not covered.
- You are treating an empty candidates list as "invalid number" - read formats_matched first - 0 means no covered format matched, above 0 means a covered format matched but its check digit failed.
- If the user has asked you to inspect a specific website, page or URL, use your browsing tool instead — this capability only returns the Eckari carrier signature engine record.
synonyms:
- which carrier is this tracking number
- tracking number carrier lookup
- identify courier from tracking id
- UPS or FedEx or USPS tracking number
- parcel carrier detection
- shipment carrier inference
- tracking number format validation
- UPU S10
- detect courier
- tracking number check digit
- courier identification
- parcel number lookup
- carrier from consignment number
- postal item id parser
category: logistics
region: null
tags:
- parcel
- tracking
- carrier
- logistics
- shipping
cache_policy:
mode: none
provenance:
sources:
- eckari_carrier_signatures
freshness: static
servers:
- url: https://api.eckari.com
components:
schemas:
ErrorEnvelope:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
- request_id
properties:
code:
type: string
enum:
- INVALID_INPUT
- AUTHENTICATION_REQUIRED
- INVALID_API_KEY
- PROJECT_DISABLED
- CAPABILITY_NOT_ALLOWED
- BUDGET_EXCEEDED
- BILLING_REQUIRED
- PAYMENT_REQUIRED
- PAYMENT_FAILED
- CAPABILITY_UNAVAILABLE
- UPSTREAM_RATE_LIMITED
- UPSTREAM_UNAVAILABLE
- NOT_FOUND
- AMBIGUOUS_IDENTIFIER
- UNSUPPORTED_REGION
- LICENCE_RESTRICTED
- INTERNAL_ERROR
message:
type: string
request_id:
type: string
details:
type:
- object
- 'null'
parcel_detect_carrier_output:
type: object
additionalProperties: false
required:
- carrier
- match_strength
- match_score
- candidates
- input
- formats_matched
- upu_s10
- signature_version
properties:
carrier:
type:
- object
- 'null'
additionalProperties: false
required:
- id
- name
description: The answer - the best-matching carrier, or null when no candidate scored at least 0.5. Always read match_strength before acting on it - a weak match names a carrier whose format has no carrier-unique marker.
properties:
id:
type: string
description: Stable Eckari carrier identifier such as ups or royal_mail.
name:
type: string
description: Human-readable carrier name such as UPS.
match_strength:
type: string
enum:
- distinctive
- strong
- weak
- none
description: How distinctive the match behind `carrier` is. distinctive = a carrier-unique marker (prefix or UPU S10 operator) plus length plus a valid check digit - only that carrier issues numbers of this shape. strong = carrier-unique marker plus length, check digit not verifiable. weak = length plus check digit only, with no carrier-unique marker; a random number of the right length passes a single decimal check digit about 1 time in 10 (about 1 in 36 for the alphanumeric mod 37,36 check), so treat a weak match as a hint. none = no carrier is named.
match_score:
type:
- number
- 'null'
description: Deterministic signature match score for `carrier` from a fixed table (0-1, two decimals) - carrier-unique prefix plus length plus valid check digit 0.98, UPU S10 with a valid check digit 0.90, prefix plus length 0.85, length plus valid check digit 0.80, S10 structure with an invalid check digit 0.45, plus 0.02 when a country hint matches. It is a rule-based heuristic, NOT a calibrated probability, and it is null when no carrier is named.
minimum: 0
maximum: 1
candidates:
type: array
description: Every carrier whose signature matched, highest score first, ties broken by carrier_id ascending. Candidates below the 0.5 reporting threshold are still listed here even though `carrier` is null, so an ambiguous or failed-check number can be inspected.
items:
type: object
additionalProperties: false
required:
- carrier_id
- carrier_name
- match_score
- match_strength
- format_id
- evidence
properties:
carrier_id:
type: string
description: Stable Eckari carrier identifier such as ups or usps.
carrier_name:
type: string
description: Human-readable carrier name.
match_score:
type: number
description: This candidate's score from the same fixed table as the top-level match_score.
minimum: 0
maximum: 1
match_strength:
type: string
enum:
- distinctive
- strong
- weak
description: How distinctive this candidate's match is; same meaning as the top-level field (a candidate is never "none").
format_id:
type: string
description: Identifier of the matched format within the signature set, for example ups_1z or upu_s10.
evidence:
type: object
additionalProperties: false
required:
- prefix
- length
- check_digit
- s10_origin_country
- country_hint
description: What about this number made the format match. A null member means that signal played no part in this match.
properties:
prefix:
type:
- string
- 'null'
description: The leading characters of the normalised number that form the carrier-unique marker, for example 1Z, or the UPU S10 service indicator such as RB. Null when the format has no distinguishing prefix.
length:
type:
- integer
- 'null'
description: The exact number of characters this format requires, for example 18 for a UPS 1Z number. Null when the format accepts a range of lengths.
check_digit:
type:
- string
- 'null'
description: Name of the check-digit algorithm that validated this number - ups_mod10, gs1_mod10, fedex_express_mod11, dhl_mod7, mod_37_36 or upu_s10. Null when the format defines no check digit, or when the S10 check digit did not validate.
s10_origin_country:
type:
- string
- 'null'
description: ISO 3166-1 alpha-2 country of the designated postal operator for a UPU S10 match. Null for non-postal formats.
country_hint:
type:
- string
- 'null'
description: The origin_country or destination_country you supplied that matched this format's country list and added the 0.02 tie-breaker. Null when no hint applied.
input:
type: object
additionalProperties: false
required:
- original
- normalised
description: The tracking number as supplied and as evaluated.
properties:
original:
type: string
description: Input as supplied, trimmed. Never altered otherwise.
normalised:
type: string
description: Upper-cased value with spaces and hyphens removed - the string the rules were evaluated against.
formats_matched:
type: integer
description: Number of distinct formats in the signature set whose pattern matched the normalised number, counted before check digits were applied. Zero with no candidates means no covered format matches this shape at all; a value above zero with no candidates means a covered format matched but its check digit did not validate - a typo or a partial capture rather than an unknown carrier.
minimum: 0
upu_s10:
type:
- object
- 'null'
additionalProperties: false
description: Parsed UPU S10 components; null when the number does not have the S10 structure.
required:
- service_indicator
- service_type
- serial
- check_digit_valid
- origin_country
properties:
service_indicator:
type: string
description: Two-letter S10 service indicator such as RB.
service_type:
type:
- string
- 'null'
description: Service class implied by the first indicator letter, for example letter_post_registered; null when unrecognised.
serial:
type: string
description: Eight-digit S10 serial number.
check_digit_valid:
type: boolean
description: True when the S10 check digit validates against the serial.
origin_country:
type: string
description: ISO 3166-1 alpha-2 country code of the origin designated operator.
signature_version:
type: string
description: Version of the signature set that produced this result; results are reproducible for a given version.
ResponseMeta:
type: object
required:
- capability
- version
- retrieved_at
- source
- freshness
- request_id
properties:
capability:
type: string
version:
type: string
retrieved_at:
type: string
format: date-time
source:
type: string
freshness:
type: string
enum:
- live
- near_live
- cached
- static
request_id:
type: string
attribution:
type: string
description: Source licence attribution statement, present only when the executing provider's licence conditions re-use on acknowledging the source (e.g. Open Government Licence v3.0 for Companies House). Republish it verbatim with the data. Absent when the provider declares none (ADR-007).
attribution_url:
type: string
format: uri
description: Canonical https URL of the licence or attribution notice behind meta.attribution. Present only when the executing provider declares one; attribution never appears inside data (ADR-008 §1).
securitySchemes:
eckariApiKey:
type: http
scheme: bearer
description: Eckari account API key (ek_test_… / ek_live_…) issued in the developer portal; usage is metered and billed in arrears.
x402:
type: apiKey
in: header
name: PAYMENT-SIGNATURE
description: x402 accountless payment. An unpaid request receives HTTP 402 with a PAYMENT-REQUIRED header; retry with PAYMENT-SIGNATURE.
x-refined-from:
- eckari-com-openapi.json
- eckari-com-openapi.json