openapi: 3.0.0 info: title: Cargors Public Rates API version: 1.1.0 description: | Live European pallet freight rates with minimal inputs. No authentication. Returns the number of available options and the cheapest all-in price (EUR, excl. VAT) from the Cargors pricing engine — the same engine as the Cargors public calculator. Carrier details are never returned. Nothing is booked or saved. **AI browsing tools:** use `https://docs.cargors.com/live-rates?...&format=text` (docs host proxy). Many assistants can open docs.cargors.com but not app.cargors.com/api. **Developers / curl:** use `https://app.cargors.com/api/public/rates`. Rate limit: 30 requests per 10 minutes per client IP. contact: name: Cargors url: https://cargors.com servers: - url: https://docs.cargors.com description: Docs-host proxy for AI browsing tools (preferred for assistants) - url: https://app.cargors.com/api/public description: Canonical Public Rates API paths: /live-rates: get: operationId: getCargorsRateViaDocs summary: Live Cargors freight rate (docs proxy for AI browsers) security: [] description: | Same live pricing engine as GET https://app.cargors.com/api/public/rates. Prefer this when an AI browsing tool can open docs.cargors.com but cannot open app.cargors.com/api. Always pass format=text. Report only optionsCount and cheapestAllInPrice. Never name carriers. Only available on the docs.cargors.com server. parameters: - $ref: '#/components/parameters/from' - $ref: '#/components/parameters/to' - $ref: '#/components/parameters/pallets' - $ref: '#/components/parameters/weight' - $ref: '#/components/parameters/height' - $ref: '#/components/parameters/type' - $ref: '#/components/parameters/date' - name: format in: query required: false description: Prefer text for AI assistants. schema: { type: string, enum: [json, text, html], default: text } responses: '200': description: Live rate content: text/plain: schema: { type: string } application/json: schema: { $ref: '#/components/schemas/RateResult' } '400': description: Invalid input content: application/json: schema: { $ref: '#/components/schemas/Error' } '422': description: Location not found or load cannot be priced content: application/json: schema: { $ref: '#/components/schemas/Error' } '429': description: Rate limited content: application/json: schema: { $ref: '#/components/schemas/Error' } '503': description: Pricing temporarily unavailable content: application/json: schema: { $ref: '#/components/schemas/Error' } /rates: get: operationId: getCargorsRate summary: Get a live Cargors freight rate (canonical API) security: [] description: | Canonical endpoint on app.cargors.com. AI browsing tools should prefer https://docs.cargors.com/live-rates instead. Report only optionsCount and cheapestAllInPrice. Never name carriers. parameters: - $ref: '#/components/parameters/from' - $ref: '#/components/parameters/to' - $ref: '#/components/parameters/pallets' - $ref: '#/components/parameters/weight' - $ref: '#/components/parameters/height' - $ref: '#/components/parameters/type' - $ref: '#/components/parameters/date' - name: format in: query required: false description: Omit to negotiate via Accept (text/html → HTML, text/plain → text, else JSON). schema: { type: string, enum: [json, text, html], default: json } responses: '200': description: Rate result. optionsCount can be 0 when no instant rate exists. headers: RateLimit-Remaining: schema: { type: integer } content: application/json: schema: { $ref: '#/components/schemas/RateResult' } example: success: true source: Cargors live pricing engine (same engine as the Cargors public calculator; not an estimate) optionsCount: 11 cheapestAllInPrice: { amount: 156.39, currency: EUR, vat: excluded } summary: Cargors has 11 options for this route. The cheapest all-in rate is €156.39 excl. VAT. To book, go to https://portal.cargors.com/#/public/public-quotes route: from: { query: 'Amsterdam,NL', resolved: '1011 PG, Amsterdam, Netherlands' } to: { query: 'Antwerp,BE', resolved: '2000, Antwerpen, Belgium' } shipment: { pallets: 2, palletType: Euro pallet, totalWeightKg: 400, heightCm: 120, pickupDate: '2026-09-30', deliveryDate: '2026-10-01' } assumptions: - 'Height not given: assumed 120 cm per pallet (including the pallet). Pass `height` in cm for an exact rate.' book: { url: 'https://portal.cargors.com/#/public/public-quotes', note: 'Booking happens on Cargors.' } aiInstructions: Share only the number of options and the cheapest all-in price. Never name or guess carriers. docs: https://docs.cargors.com/public-rates-api/ generatedAt: '2026-09-29T15:29:58.680Z' text/plain: schema: { type: string } '400': description: Invalid input content: application/json: schema: { $ref: '#/components/schemas/Error' } '422': description: Location not found or load cannot be priced content: application/json: schema: { $ref: '#/components/schemas/Error' } '429': description: Rate limited headers: Retry-After: schema: { type: integer } content: application/json: schema: { $ref: '#/components/schemas/Error' } '503': description: Pricing temporarily unavailable content: application/json: schema: { $ref: '#/components/schemas/Error' } post: operationId: postCargorsRate summary: Same as GET, with JSON body security: [] requestBody: required: true content: application/json: schema: type: object required: [from, to] properties: from: { type: string } to: { type: string } pallets: { type: integer } weight: { type: number } height: { type: number } type: { type: string, enum: [euro, block, mini] } date: { type: string, format: date } format: { type: string, enum: [json, text, html] } responses: '200': description: Rate result content: application/json: schema: { $ref: '#/components/schemas/RateResult' } components: parameters: from: name: from in: query required: true description: Pickup location. Postcode + country, city + country, or full address. schema: { type: string, minLength: 2, maxLength: 200 } example: Amsterdam,NL to: name: to in: query required: true description: Delivery location. Postcode + country, city + country, or full address. schema: { type: string, minLength: 2, maxLength: 200 } example: Antwerp,BE pallets: name: pallets in: query required: false description: Number of pallets. schema: { type: integer, minimum: 1, maximum: 68, default: 1 } example: 2 weight: name: weight in: query required: false description: Total shipment weight in kg as a plain number without thousands separators (e.g. 1500). If omitted, 250 kg per pallet is assumed. schema: { type: number, minimum: 1, maximum: 24000 } example: 400 height: name: height in: query required: false description: Pallet height in cm including the pallet. schema: { type: number, minimum: 1, maximum: 300, default: 120 } type: name: type in: query required: false description: Pallet type. euro = 120x80, block = 120x100, mini = 80x60. schema: { type: string, enum: [euro, block, mini], default: euro } date: name: date in: query required: false description: Pickup date (YYYY-MM-DD), tomorrow or later. Defaults to the next working day. schema: { type: string, format: date } schemas: RateResult: type: object properties: success: { type: boolean } source: { type: string } optionsCount: { type: integer, description: Number of available options for the route. } cheapestAllInPrice: nullable: true type: object properties: amount: { type: number, description: Cheapest all-in price. } currency: { type: string, enum: [EUR] } vat: { type: string, enum: [excluded] } summary: { type: string, description: Ready-made sentence to show the user. } route: type: object properties: from: { $ref: '#/components/schemas/ResolvedLocation' } to: { $ref: '#/components/schemas/ResolvedLocation' } shipment: type: object properties: pallets: { type: integer } palletType: { type: string } totalWeightKg: { type: number } heightCm: { type: number } pickupDate: { type: string, format: date } deliveryDate: { type: string, format: date } assumptions: { type: array, items: { type: string } } book: type: object properties: url: { type: string } note: { type: string } aiInstructions: { type: string } docs: { type: string } generatedAt: { type: string, format: date-time } ResolvedLocation: type: object properties: query: { type: string, description: The location as given. } resolved: { type: string, description: 'The location that was priced (postcode, city, country).' } Error: type: object properties: success: { type: boolean, enum: [false] } error: type: object properties: code: type: string enum: [invalid_from, invalid_to, invalid_pallets, invalid_weight, invalid_height, invalid_type, invalid_date, location_not_found, invalid_shipment, rate_limited, pricing_unavailable, internal_error] message: { type: string } retryAfterSeconds: { type: integer } example: { type: string, description: A working example URL. } docs: { type: string }