{
 "openapi": "3.1.0",
 "info": {
  "title": "Honour Ocean shipping tools API",
  "version": "1.0.0",
  "summary": "Duty, transit, chargeable-weight and HS-chapter duty lookups for imports from China.",
  "description": "Read-only endpoints over the same data published on https://hofreight.com/tools/ and the route pages. Every response carries its sources and caveats. Figures are published positions with a review date, not live carrier data and not a quotation. Where a lane publishes no transit range the value is null rather than estimated. Results include a pre-filled quotation link so a caller can hand the user to a human.",
  "contact": {
   "name": "Honour Ocean",
   "url": "https://hofreight.com/contact/"
  },
  "license": {
   "name": "Quote with attribution and a link to the route page named in each record."
  }
 },
 "servers": [
  {
   "url": "https://hofreight.com"
  }
 ],
 "tags": [
  {
   "name": "tools",
   "description": "Lookups and calculators."
  },
  {
   "name": "dataset",
   "description": "The whole dataset in one document."
  }
 ],
 "paths": {
  "/api/tools": {
   "get": {
    "tags": [
     "tools"
    ],
    "operationId": "listEndpoints",
    "summary": "List the available endpoints and dataset counts.",
    "responses": {
     "200": {
      "description": "Endpoint index."
     }
    }
   }
  },
  "/api/tools/lanes": {
   "get": {
    "tags": [
     "tools"
    ],
    "operationId": "listLanes",
    "summary": "List every destination lane and the fields it publishes.",
    "responses": {
     "200": {
      "description": "Lane list."
     }
    }
   }
  },
  "/api/tools/lane": {
   "get": {
    "tags": [
     "tools"
    ],
    "operationId": "getLane",
    "summary": "Published customs, compliance and logistics positions for one destination.",
    "description": "Returns the sentences the route page publishes, under stable keys: dutyAndTax, importLevies, deMinimis, ftaPreference, importerOfRecord, certification, preShipmentInspection, preArrivalRegistration, loadingFrom, destinationPorts, directSailings, containerOptions, inlandDelivery, clearance, parcels, surcharges, quoteTurnaround.",
    "parameters": [
     {
      "name": "country",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "example": "kenya"
     },
     {
      "name": "fields",
      "in": "query",
      "required": false,
      "description": "Comma-separated subset of rule keys.",
      "schema": {
       "type": "string"
      },
      "example": "importerOfRecord,certification"
     }
    ],
    "responses": {
     "200": {
      "description": "Lane rules."
     },
     "400": {
      "description": "country missing."
     },
     "404": {
      "description": "No lane published for that market."
     }
    }
   }
  },
  "/api/tools/transit": {
   "get": {
    "tags": [
     "tools"
    ],
    "operationId": "getTransit",
    "summary": "Transit range by destination and mode.",
    "description": "Ocean ranges are port to port and air ranges are airport to airport. A null days value means no carrier or forwarder figure is published for that lane and mode.",
    "parameters": [
     {
      "name": "country",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "example": "malaysia"
     },
     {
      "name": "mode",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "ocean-fcl",
        "ocean-lcl",
        "air",
        "express"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Transit rows."
     },
     "400": {
      "description": "country missing or mode unknown."
     },
     "404": {
      "description": "No transit data for that market."
     }
    }
   }
  },
  "/api/tools/landed-cost": {
   "get": {
    "tags": [
     "tools"
    ],
    "operationId": "getLandedCost",
    "summary": "Duty, import tax, country levies and landed cost.",
    "description": "Duty is assessed line by line in every market covered. Where a market publishes a single rate it is used as the default; where duty varies by line the response says so and warns when the figure used is only the low end of the range. A certificate of origin removes duty only, never import tax.",
    "parameters": [
     {
      "name": "country",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "example": "kenya"
     },
     {
      "name": "goods",
      "in": "query",
      "required": true,
      "description": "Declared goods value in USD.",
      "schema": {
       "type": "number"
      },
      "example": 5000
     },
     {
      "name": "freight",
      "in": "query",
      "required": false,
      "schema": {
       "type": "number"
      },
      "example": 800
     },
     {
      "name": "insurance",
      "in": "query",
      "required": false,
      "schema": {
       "type": "number"
      },
      "example": 0
     },
     {
      "name": "dutyRate",
      "in": "query",
      "required": false,
      "description": "Percent. Defaults to the published rate or the bottom of the published range.",
      "schema": {
       "type": "number"
      }
     },
     {
      "name": "taxRate",
      "in": "query",
      "required": false,
      "description": "Percent. Defaults to the published import-tax rate.",
      "schema": {
       "type": "number"
      }
     },
     {
      "name": "certificate",
      "in": "query",
      "required": false,
      "description": "True when a valid certificate of origin (Form E, Form F, ChAFTA) is available.",
      "schema": {
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Cost breakdown."
     },
     "400": {
      "description": "country or goods missing."
     },
     "404": {
      "description": "No import-tax position for that market."
     }
    }
   }
  },
  "/api/tools/chargeable-weight": {
   "get": {
    "tags": [
     "tools"
    ],
    "operationId": "getChargeableWeight",
    "summary": "Volumetric and chargeable weight for air, courier and ocean LCL.",
    "description": "Air divides cubic centimetres by 6,000 and courier networks by 5,000; ocean LCL bills on W/M. Chargeable weight is the greater of actual and volumetric. No freight price is returned.",
    "parameters": [
     {
      "name": "pieces",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 1,
       "default": 1
      }
     },
     {
      "name": "length",
      "in": "query",
      "required": true,
      "description": "Centimetres.",
      "schema": {
       "type": "number"
      },
      "example": 100
     },
     {
      "name": "width",
      "in": "query",
      "required": true,
      "description": "Centimetres.",
      "schema": {
       "type": "number"
      },
      "example": 100
     },
     {
      "name": "height",
      "in": "query",
      "required": true,
      "description": "Centimetres.",
      "schema": {
       "type": "number"
      },
      "example": 100
     },
     {
      "name": "weight",
      "in": "query",
      "required": true,
      "description": "Total gross weight in kilograms.",
      "schema": {
       "type": "number"
      },
      "example": 100
     }
    ],
    "responses": {
     "200": {
      "description": "Weight breakdown."
     },
     "400": {
      "description": "Missing dimensions or weight."
     }
    }
   }
  },
  "/api/tools/hs-duty": {
   "get": {
    "tags": [
     "tools"
    ],
    "operationId": "getHsChapterDuty",
    "summary": "Official HS-chapter duty ranges for a market, before classification.",
    "description": "Duty is assessed per commodity code, not per chapter, so a chapter range is a screening aid and NOT a declarable rate. Each chapter carries the lowest, highest and most common ad-valorem rate across every duty-bearing leaf line in the official schedule, how many lines enter duty free, and how many carry a specific or compound duty that is counted but never folded into the percentage range. The response names the schedule, the revision read, the rate basis and the retrieval date.",
    "parameters": [
     {
      "name": "country",
      "in": "query",
      "required": true,
      "description": "Market slug.",
      "schema": {
       "type": "string",
       "enum": [
        "united-states",
        "united-kingdom",
        "brazil"
       ]
      },
      "example": "united-states"
     },
     {
      "name": "chapter",
      "in": "query",
      "required": false,
      "description": "Two-digit HS chapter (01-97; 77 is reserved). Omit to return every chapter.",
      "schema": {
       "type": "string"
      },
      "example": "64"
     }
    ],
    "responses": {
     "200": {
      "description": "One chapter, or every chapter when chapter is omitted."
     },
     "400": {
      "description": "country missing."
     },
     "404": {
      "description": "No schedule published for that market, or no such chapter in it."
     }
    }
   }
  },
  "/tool-data.json": {
   "get": {
    "tags": [
     "dataset"
    ],
    "operationId": "getDataset",
    "summary": "The complete dataset in one document.",
    "description": "All lanes, import-tax positions, transit ranges and HS-chapter duty schedules, each with its source page and review date.",
    "responses": {
     "200": {
      "description": "Dataset."
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "QuoteLink": {
    "type": "string",
    "description": "Pre-filled quotation URL carrying the caller’s inputs into the enquiry form."
   }
  }
 }
}