FreightUtils Composite API

The Composite API from FreightUtils — 1 operation(s) for composite.

GitHub OpenAPI

Operations 1

POST /api/shipment/summary Composite shipment summary #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/freightutils-com:freightutils-com-composite-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

freightutils-com-composite-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: FreightUtils Composite API
  description: 'The neutral freight reference layer for AI agents: reference and calculation APIs for dangerous goods, customs, locations and freight math that agents can call and cite. No freight to sell, no carrier to push. Anon 25/day per IP, free key 100/day, Pro 50k/month — freightutils.com/pricing.'
  version: 1.0.0
  contact:
    name: FreightUtils
    url: https://www.freightutils.com
    email: contact@freightutils.com
  license:
    name: Free to use
    url: https://www.freightutils.com/api-docs
servers:
- url: https://www.freightutils.com
  description: Production
security:
- {}
- ApiKeyHeader: []
- BearerAuth: []
tags:
- name: Composite
paths:
  /api/shipment/summary:
    post:
      summary: Composite shipment summary
      description: Chains CBM, chargeable weight, LDM, ADR compliance, and UK duty estimation into one response. The flagship composite endpoint.
      operationId: shipmentSummary
      tags:
      - Composite
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
              - type: object
                required:
                - mode
                - items
                properties:
                  mode:
                    type: string
                    enum:
                    - road
                    - air
                    - sea
                    - multimodal
                  items:
                    type: array
                    items:
                      type: object
                      required:
                      - length
                      - width
                      - height
                      - weight
                      properties:
                        description:
                          type: string
                        length:
                          type: number
                        width:
                          type: number
                        height:
                          type: number
                        weight:
                          type: number
                          description: Gross weight in kg PER ITEM (per piece) — multiplied by quantity.
                        quantity:
                          type: integer
                          minimum: 1
                          description: 'Number of pieces: a whole number from 1 to 1,000,000, sent as a number. Omit it for 1; null, 0, fractions or text are a 400.'
                          maximum: 1000000
                        stackable:
                          type: boolean
                        pallet_type:
                          type: string
                          enum:
                          - euro
                          - uk
                          - us
                          - custom
                          - none
                          description: Pallet standard the item sits on, if any (sets the pallet footprint for the road LDM).
                        hs_code:
                          type: string
                        un_number:
                          type: string
                        customs_value:
                          type: number
                          description: Customs value in GBP PER ITEM (per piece), 0 or more — multiplied by quantity for the line; the duty estimate uses the sum over all lines (echoed as customs.customsValueTotal). Left out, null or blank means none; a negative, NaN or infinite value is refused with 400 naming the item.
                          minimum: 0
                        adr_quantity:
                          type: number
                          description: ADR 1.1.3.6.3 quantity for this dangerous-goods line — the TOTAL for the whole line, all pieces together, never per piece. Separate from weight (gross package mass). Supply it with adr_quantity_unit on every DG line and adrFlags.totalPoints is calculated.
                          exclusiveMinimum: 0
                          maximum: 1000000000
                        adr_quantity_unit:
                          type: string
                          enum:
                          - L
                          - kg
                          description: Dimension of adr_quantity. Checked against the dimension 1.1.3.6.3 counts for the row — a litres row given kilograms still withholds the total.
                  origin:
                    type: object
                    properties:
                      country:
                        type: string
                      locode:
                        type: string
                    additionalProperties: false
                  destination:
                    type: object
                    properties:
                      country:
                        type: string
                      locode:
                        type: string
                    additionalProperties: false
                  incoterm:
                    type: string
                  freight_cost:
                    type: number
                    minimum: 0
                    description: Freight cost in GBP, 0 or more (added to the CIF value of the UK duty estimate). Left out, null or blank means 0. A negative, NaN or infinite value is refused with 400 naming the field.
                  insurance_cost:
                    type: number
                    minimum: 0
                    description: Insurance cost in GBP, 0 or more (added to the CIF value of the UK duty estimate). Left out, null or blank means 0. A negative, NaN or infinite value is refused with 400 naming the field.
                  edition:
                    type: string
                    enum:
                    - '2025'
                    - '2027'
                    description: 'ADR edition "2025" or "2027"; wins over as_of. Omitted, as_of picks it: before 2027-01-01 ADR 2025; to 2027-06-30 ADR 2027 with an EDITION_TRANSITIONAL notice (ADR 2025 still allowed, 1.6.1.1); from 2027-07-01 ADR 2027 only (2025 refused, EDITION_UNSUPPORTED, 422). /api-docs#adr-editions'
                  as_of:
                    type: string
                    pattern: ^\d{4}-\d{2}-\d{2}$
                    example: '2027-01-15'
                    description: YYYY-MM-DD the answer is for (default today, UTC). Picks the ADR edition when edition is omitted; echoed in adr_edition, the 1.2 envelope and the check receipt.
              - $ref: '#/components/schemas/ConsignmentRequest'
      responses:
        '200':
          description: Complete shipment summary
          headers:
            X-FreightUtils-Upstream:
              $ref: '#/components/headers/X-FreightUtils-Upstream'
        '400':
          description: Invalid input — e.g. a piece count that is not a whole number ≥ 1, an adr_quantity / adr_quantity_unit that is not a number > 0 / "L" or "kg", a cost that is negative or not a finite number, or a field the route does not read (refused by name, never ignored). The error names what arrived.
        '405':
          description: Use POST
        '424':
          description: 'Only with ?if_stale=refuse: a dataset of the answer missed its upstream window.'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/StaleUpstreamProblem'
        '429':
          $ref: '#/components/responses/RateLimited'
      parameters:
      - $ref: '#/components/parameters/Envelope'
      - $ref: '#/components/parameters/ClientLabel'
      - $ref: '#/components/parameters/IfStale'
components:
  schemas:
    StaleUpstreamProblem:
      type: object
      description: HTTP 424 problem details, only for a caller who sent ?if_stale=refuse while a dataset of the answer missed its upstream window. Not retryable in seconds. Without the parameter the same request is answered, marked stale.
      required:
      - type
      - title
      - status
      - code
      - detail
      - datasets
      properties:
        type:
          type: string
        title:
          type: string
        status:
          type: integer
          enum:
          - 424
        code:
          type: string
          enum:
          - stale_upstream
        detail:
          type: string
        datasets:
          type: array
          items:
            type: object
            properties:
              dataset:
                type: string
              state:
                type: string
              last_success:
                type:
                - string
                - 'null'
              window_days:
                type:
                - number
                - 'null'
              editions_held:
                type: array
                items:
                  type: string
        state_read_at:
          type:
          - string
          - 'null'
        instance:
          type: string
    ConsignmentObject:
      title: FreightUtils consignment object v1
      description: 'The consignment object (consignment-object.v1): lines[] (required), journey, vehicle, options. The consignment argument of consignment_calculator, shipment_summary and adr_exemption_calculator; the body of POST /api/adr/consignment-check; validated by POST /api/validate. No parties.'
      type: object
      properties:
        lines:
          minItems: 1
          maxItems: 50
          type: array
          items:
            type: object
            properties:
              description:
                description: What the line is, at most 200 characters.
                type: string
                maxLength: 200
              un_number:
                description: UN number of a dangerous-goods line, or an ID-prefixed air-only number ("ID 8000").
                type: string
                pattern: ^(?:(?:UN\s?)?\d{4}|ID\s?\d{4})$
              packing_group:
                description: Packing group, to pin one ADR Table A row of a multi-row UN.
                type: string
                enum:
                - I
                - II
                - III
              variant_index:
                description: ADR Table A variant index (as adr_lookup returns it), to pin one row.
                type: integer
                minimum: 0
                maximum: 1000
              quantity:
                description: The dangerous-goods quantity (ADR 1.1.3.6.3), separate from the gross mass of the packages.
                type: object
                properties:
                  value:
                    type: number
                    minimum: 0
                    maximum: 1000000000
                    description: The dangerous-goods quantity for the whole line, all packages together. 0 = the goods are not carried (the line is left out of the 1.1.3.6 count and named in a warning).
                  unit:
                    description: '"L" or "kg" — checked against the dimension ADR 1.1.3.6.3 counts for the row.'
                    type: string
                    enum:
                    - L
                    - kg
                  basis:
                    description: '"net" (the goods) or "gross" (with packaging). 1.1.3.6.3 counts net; a gross figure scores no points.'
                    type: string
                    enum:
                    - net
                    - gross
                required:
                - value
                additionalProperties: false
              packages:
                description: 'The pieces: how many, of what type, and their total gross mass.'
                type: object
                properties:
                  count:
                    type: integer
                    exclusiveMinimum: 0
                    maximum: 100000
                    description: Number of identical packages (pieces) on the line.
                  type:
                    description: Package type, e.g. "pallet", "drum", "carton".
                    type: string
                    maxLength: 40
                  gross_kg:
                    description: Gross mass of ALL the line's packages together, in kg.
                    type: number
                    exclusiveMinimum: 0
                    maximum: 1000000
                  un_mark:
                    description: 'UN packaging mark as printed (ADR 6.1.3.1), e.g. "UN 4G/Y145/S/02/NL/VL823": (a) the symbol, (b) the 6.1.2.7 code, (c) the packing-group letter X / Y / Z and density or mass, (d) S or test pressure, (e) the year, (f) the State, (g) the maker; the letter is held against the line''s packing group.'
                    type: string
                    minLength: 1
                    maxLength: 80
                required:
                - count
                additionalProperties: false
              hs_code:
                description: HS / tariff commodity code, 6–10 digits.
                type: string
                pattern: ^\d{6,10}$
              value:
                description: Customs value of the whole line (all packages together).
                type: object
                properties:
                  amount:
                    type: number
                    minimum: 0
                    maximum: 1000000000000
                    description: The amount, 0 or more.
                  currency:
                    type: string
                    pattern: ^[A-Z]{3}$
                    description: ISO 4217 currency code, e.g. "GBP".
                required:
                - amount
                - currency
                additionalProperties: false
              dims:
                description: 'Dimensions of ONE package: { l, w, h, unit: mm | cm | m | in }.'
                type: object
                properties:
                  l:
                    type: number
                    exclusiveMinimum: 0
                    maximum: 100000
                  w:
                    type: number
                    exclusiveMinimum: 0
                    maximum: 100000
                  h:
                    type: number
                    exclusiveMinimum: 0
                    maximum: 100000
                  unit:
                    type: string
                    enum:
                    - mm
                    - cm
                    - m
                    - in
                required:
                - l
                - w
                - h
                - unit
                additionalProperties: false
              stackable:
                description: Whether the packages may be stacked.
                type: boolean
              icao_limited_quantity:
                description: 'On an ID-prefixed line only: the packages are limited quantities to the ICAO Technical Instructions (3.4.8 mark / 3.4.10). Without it such a line has no 1.1.3.6 verdict.'
                type: boolean
              inner_packaging:
                description: The inner packaging of a line, for the limited / excepted quantity check (Table A columns (7a) / (7b)).
                type: object
                properties:
                  quantity:
                    type: number
                    exclusiveMinimum: 0
                    maximum: 1000000
                    description: The quantity in ONE inner packaging.
                  unit:
                    type: string
                    enum:
                    - ml
                    - L
                    - g
                    - kg
                    description: ml | L | g | kg.
                  per_outer:
                    description: Inner packagings in one outer packaging (default 1) — the excepted-quantity outer limit.
                    type: integer
                    minimum: 1
                    maximum: 100000
                  regime:
                    description: 'The exemption the line is meant to use: limited (lq) or excepted (eq) quantity. A stated regime that is missed fails. Omitted: both are checked, and a line that fits neither is not_applicable (the full requirements apply).'
                    type: string
                    enum:
                    - lq
                    - eq
                required:
                - quantity
                - unit
                additionalProperties: false
            additionalProperties: false
          description: The lines of the load. Required.
        journey:
          type: object
          properties:
            origin:
              description: UN/LOCODE or ISO country code of the origin.
              type: string
              pattern: ^[A-Za-z]{2}(?:\s?[A-Za-z2-9]{3})?$
            destination:
              description: UN/LOCODE or ISO country code of the destination.
              type: string
              pattern: ^[A-Za-z]{2}(?:\s?[A-Za-z2-9]{3})?$
            date:
              description: Date of carriage, YYYY-MM-DD.
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
            tunnels_on_route:
              description: ADR tunnel categories on the route (A–E).
              maxItems: 20
              type: array
              items:
                type: string
                enum:
                - A
                - B
                - C
                - D
                - E
            mode:
              description: road | air | sea | multimodal.
              type: string
              enum:
              - road
              - air
              - sea
              - multimodal
          additionalProperties: false
        vehicle:
          type: object
          properties:
            type:
              description: Vehicle type, e.g. "artic", "rigid 7.5 t".
              type: string
              maxLength: 60
            max_mass_t:
              description: 'Maximum permissible mass, tonnes — read by adr_consignment_check as the transport unit''s maximum permissible mass (ADR 8.1.4.1 column (1): the extinguisher band; 3.4.13: the limited-quantity mark on units over 12 t).'
              type: number
              exclusiveMinimum: 0
              maximum: 100
            axles:
              type: integer
              minimum: 1
              maximum: 12
            foodstuffs_carried:
              description: 'Whether packages known to contain foodstuffs, other articles of consumption or animal feeds are carried in the same vehicle or container as the lines (ADR 7.5.4, read by adr_consignment_check for goods with CV28). Omitted: the foodstuffs precaution is answered as a condition.'
              type: boolean
            fire_extinguishers_kg:
              description: 'The capacity in kg (dry powder, or the equivalent for another agent) of each portable fire extinguisher on board (ADR 8.1.4.1: number, total and largest by the transport unit''s maximum permissible mass; 8.1.4.2: one of 2 kg under 1.1.3.6).'
              maxItems: 20
              type: array
              items:
                type: number
                exclusiveMinimum: 0
                maximum: 100
            orange_plates_displayed:
              description: Whether the transport unit displays the two rectangular orange-coloured plates, one at the front and one at the rear (ADR 5.3.2.1.1).
              type: boolean
            placards_displayed:
              description: Whether the vehicle displays the placards ADR 5.3.1.5 requires of a vehicle carrying packages (Class 1 other than 1.4S; Class 7 other than excepted packages), on both sides and at the rear.
              type: boolean
            equipment_8_1_5:
              description: The ADR 8.1.5.2 / 8.1.5.3 items on board, by name (vest, lighting, gloves, eye protection and escape mask for each crew member; escape mask for labels 2.3 / 6.1; shovel, drain seal, collecting container for labels 3, 4.1, 4.3, 8, 9). An item not listed is read as not on board.
              maxItems: 11
              type: array
              items:
                type: string
                enum:
                - wheel_chock
                - warning_signs
                - eye_rinsing_liquid
                - warning_vest
                - portable_lighting
                - protective_gloves
                - eye_protection
                - emergency_escape_mask
                - shovel
                - drain_seal
                - collecting_container
            instructions_in_writing:
              description: Whether the instructions in writing of ADR 5.4.3 are carried in the driver's cab (8.1.2.1 (b)).
              type: boolean
          additionalProperties: false
        crew:
          description: The vehicle crew, for adr_consignment_check's driver-training and document checks (ADR 8.2, 8.1.2). Facts only — no name.
          type: object
          properties:
            adr_training_certificate:
              description: Whether the driver holds the ADR driver training certificate (8.2.1.1, the model of 8.2.2.8), valid on the date of carriage.
              type: boolean
            specialisations:
              description: The specialisations the driver's certificate carries (8.2.1.3 tanks; 8.2.1.4 Class 1, Class 7).
              maxItems: 3
              type: array
              items:
                type: string
                enum:
                - class_1
                - class_7
                - tanks
            photo_identification:
              description: Whether each member of the vehicle crew carries a means of identification which includes a photograph (8.1.2.1 (d), 1.10.1.4).
              type: boolean
            awareness_training_1_3:
              description: Whether the driver has received training according to ADR Chapter 1.3 (8.2.3) — what a load carried under 1.1.3.6 keeps for a driver without the 8.2.1 certificate.
              type: boolean
          additionalProperties: false
        options:
          type: object
          properties:
            air_volumetric_divisor:
              description: IATA volumetric divisor, cm³/kg (default 6000).
              type: number
              exclusiveMinimum: 0
              maximum: 10000
            container_number:
              description: ISO 6346 container number (check digit validated, advisory).
              type: string
              maxLength: 20
            awb_number:
              description: IATA air waybill number (check digit validated, advisory).
              type: string
              maxLength: 20
            incoterm:
              description: Incoterms 2020 rule.
              type: string
              enum:
              - EXW
              - FCA
              - FAS
              - FOB
              - CFR
              - CIF
              - CPT
              - CIP
              - DAP
              - DPU
              - DDP
            freight_cost:
              description: Freight cost for the customs value.
              type: object
              properties:
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  description: The amount, 0 or more.
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                  description: ISO 4217 currency code, e.g. "GBP".
              required:
              - amount
              - currency
              additionalProperties: false
            insurance_cost:
              description: Insurance cost for the customs value.
              type: object
              properties:
                amount:
                  type: number
                  minimum: 0
                  maximum: 1000000000000
                  description: The amount, 0 or more.
                currency:
                  type: string
                  pattern: ^[A-Z]{3}$
                  description: ISO 4217 currency code, e.g. "GBP".
              required:
              - amount
              - currency
              additionalProperties: false
          additionalProperties: false
      required:
      - lines
      additionalProperties: false
    RateLimitError:
      type: object
      required:
      - error
      - message
      properties:
        error:
          type: string
          example: rate_limited
        message:
          type: string
        tier:
          type: string
          example: anon
        limit:
          type: integer
        window:
          type: string
          example: 1d
        reset_at:
          type: string
          description: UTC time the allowance resets.
        upgrade_url:
          type: string
        signup_url:
          type: string
        docs_url:
          type: string
        retry_after_seconds:
          type: integer
    ConsignmentRequest:
      type: object
      required:
      - consignment
      additionalProperties: false
      description: 'The consignment object alone, instead of this tool''s own inputs: same result as the equivalent request. A needed field it lacks is a 400 MISSING_INPUT naming the path in missing_inputs ("lines[0].dims"); unread fields are listed in normalized_input.consignment.not_read.'
      properties:
        consignment:
          $ref: '#/components/schemas/ConsignmentObject'
  parameters:
    Envelope:
      name: envelope
      in: query
      required: false
      description: 'Response envelope: 1 (byte-stable), 1.1, or 1.2 (adds status, missing_inputs, edition, as_of). Omit for the plain body.'
      schema:
        type: string
        enum:
        - '1'
        - '1.1'
        - '1.2'
    ClientLabel:
      name: client
      in: query
      required: false
      description: Optional caller label (up to 40 characters of A-Za-z0-9._-) so your calls are recognisable in our usage figures. Changes no answer. The X-FreightUtils-Client header does the same.
      schema:
        type: string
        maxLength: 40
        pattern: ^[A-Za-z0-9._-]{1,40}$
    IfStale:
      name: if_stale
      in: query
      required: false
      description: 'refuse: answer HTTP 424 (stale_upstream) instead of serving stale while a dataset of this answer missed its upstream check window. Omit it (the default) to be served from the last verified edition with stale: true.'
      schema:
        type: string
        enum:
        - refuse
  headers:
    X-FreightUtils-Upstream:
      description: 'The upstream state of the datasets this answer was drawn from: the UpstreamMeta object as compact JSON, on every REST answer of a record lookup and of a calculator that read a served dataset (absent when it read none, e.g. a container check digit).'
      schema:
        type: string
  responses:
    RateLimited:
      description: 'Rate limited: the daily (or monthly) allowance or a burst window is spent. Retry after Retry-After seconds, or send a key.'
      headers:
        Retry-After:
          schema:
            type: integer
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitError'
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: 'Free or Pro API key (fu_…). Optional: without one a call is anonymous (25/day per address).'
    BearerAuth:
      type: http
      scheme: bearer
      description: 'The same key as Authorization: Bearer fu_…'