Every API here is available over the APIs.io API and to AI agents over MCP.
{
"openapi": "3.0.3",
"info": {
"title": "WARP API Documentation",
"description": "[Get The Postman Collection](https://api.postman.com/collections/43153707-51d60bdf-d837-474b-a3d4-4e6522ad81a8?access_key=PMAT-01JPH7GR5Y1Q3JAT2J8DHJEK4T) <br/><br/>\n*Please read the Authentication instructions carefully to ensure you can integrate our API with the correct authentication header!*\n\n\n**Authentication** <br/>\n \n An API key can be requested from a member of the WARP Engineering team. Once the API key has been delivered to the client, it will need to be included as a **“apikey”** in the header of each API request. <br/>\n\n API keys should be safely and securely stored by the client. Please notify a member of the WARP Engineering team immediately if the API key is compromised. The compromised API key will be revoked and a new one will generated in the event that an API key is compromised. <br/><br/>\n **Headers:** <br/>\n \n **apikey** *\\<replace with api key>* <br/><br/>\n **Endpoint-specific errors** <br/>\n \n Example: Status Code: 400 (Bad Request)\n ```\n {\n \"code\": \"required_field_missing\",\n \"message\": \"pickupDate is required!\"\n }\n ```\n The response body for any API response status code of 4xx/5xx is formatted as follows: \n | Http Status | Code | Description |\n | -------- | ------- | ----------------|\n | 500 | internal_server_error | An unknown error has occurred. |\n | 400 | required_field_missing | Required Fields are Missing | \n | 400 | invalid_field_data | Invalid field data |\n | 401 | request_unauthorized | The **apikey** header is missing or invalid. Message: \"Invalid authorization. Requires API key.\" |\n | 403 | *(no code)* | The customer account is suspended. The response carries `message` only, without `code`: *\"Your account has been suspended, please contact Warp for assistance.\"* |\n | 429 | rate_limit_exceeded | More requests sent than the time rate limit defined. Only the quoting endpoints are rate limited (POST /freights/quote, /freights/freight-quote, /freights/quote/multi-stops), per API key, per UTC hour and per UTC day; the `Retry-After` header holds the number of seconds until the window resets. |\n",
"contact": {
"email": "api-support@wearewarp.com",
"name": "WARP API Support",
"url": "https://developer.wearewarp.com/docs/freight/"
},
"version": "1.0.0",
"license": {
"name": "Proprietary",
"url": "https://wearewarp.com/terms"
},
"x-logo": {
"url": "https://i.imgur.com/0tTxUmj.png",
"altText": "WARP"
}
},
"externalDocs": {
"description": "Find out more about WARP",
"url": "https://wearewarp.com"
},
"servers": [
{
"url": "https://stg.wearewarp.com/api/v1"
},
{
"url": "https://gw.wearewarp.com/api/v1"
}
],
"tags": [
{
"name": "Freight",
"description": "Everything about your Freight"
},
{
"name": "Multi-Stops",
"description": "FTL Multi-Stops quote and booking with intermediate transit points"
}
],
"paths": {
"/freights/quote": {
"post": {
"tags": [
"Freight"
],
"summary": "Get quote for your shipment",
"description": "\nReturns the **single cheapest rate** for the shipment. To compare every available option (carriers, service levels, parcel services) use POST /freights/freight-quote instead.\n\n**Rate limit:** this endpoint counts towards the quoting rate limit of your API key (per UTC hour and per UTC day). Above the limit the API answers **429** `rate_limit_exceeded` and the `Retry-After` header tells how many seconds remain until the window resets.\n\n**Request parameters**\n\n| Name | Type | Required/Optional | Description |\n|----------------------------|-------------------------------------|-------------------|------------------------------------------------------------------------------------------------------------------------|\n| pickupDate | String | Required | The earliest date when a carrier can pickup the shipment, in **YYYY-MM-DD** format. Date is in the timezone of the pickup stop. |\n| pickupInfo | Object | Required | The details of the pick up stop. |\n| pickupInfo.zipcode | String | Required | The postal code of the pick up stop. The pick up stop is where the shipment will be picked up. |\n| pickupInfo.country | String | Optional | The country code (ISO 3166-1 alpha-2) of the pick up stop. Supported: \"US\", \"CA\". Defaults to \"US\" if not provided. |\n| deliveryInfo | Object | Required | The details of the delivery stop. |\n| deliveryInfo.zipcode | String | Required | The postal code of the delivery stop. The delivery stop is where the shipment will be delivered. |\n| deliveryInfo.country | String | Optional | The country code (ISO 3166-1 alpha-2) of the delivery stop. Supported: \"US\", \"CA\". Defaults to \"US\" if not provided. |\n| pickupServices | Array<**PickupService**> | Optional | Any pickup services required to service the shipment in the pickup location. |\n| deliveryServices | Array<**DeliveryService**> | Optional | Any delivery services required to service the shipment in the delivery location. |\n| additionalServices | Array<**AdditionalService**> | Optional | Any additional services required to service the shipment. |\n| listItems | Array<**Item**> | Required | The list of commodities being shipped. |\n| shipmentType | String (\"LTL\", \"FTL\" or \"PARCEL\") | Optional | The type of shipment. Defaults to \"LTL\" when not provided. PARCEL returns a single FedEx rate (use POST /freights/freight-quote to compare every parcel service level); for PARCEL the items may be sent as `listItems[]` (or `items[]`) and each package must respect the FedEx limits (see **PARCEL limits** below). |\n| vehicleType | VehicleType | Optional | The vehicle. If not provided, the system will automatically select the best vehicle based on the items. Ignored for PARCEL. |\n| insuranceInfo | Object | Optional | Provide to receive an insurance quote alongside the freight quote. If either field below is missing or invalid, the insurance block is silently skipped and the freight quote is still returned. |\n| insuranceInfo.commodity | String | Required when insuranceInfo is provided | A description of the commodity being shipped. |\n| insuranceInfo.insuredValue | Number | Required when insuranceInfo is provided | The declared value of the goods to be insured (in USD). |\n\n\n<br /> \n**Item** schema:\n\n| Name | Type | Required/Optional | Description |\n|-----------------------|-----------------|-------------------|---------------------------------------------------------------------------------------|\n| name | String | Optional | The name of the shipment item. |\n| height | Number | Required | The height of the shipment item. |\n| length | Number | Required | The length of the shipment item. |\n| width | Number | Required | The width of the shipment item. |\n| sizeUnit | String | Required | The unit for the length, height, width. One of \"IN\" (inches) or \"FT\" (feets). |\n| quantity | Number | Required | The quantity of this particular shipment item. |\n| totalWeight | Number | Required | Total weight of all packages composing this line item |\n| weightUnit | String | Required | The unit for the weight. One of \"lbs\" (pounds) or \"kgs\" (kilograms). |\n| packaging | String | Optional | Packaging unit of the line item (e.g. \"Pallet\"). Defaults to \"Pallet\". |\n| temperature_limit | Object | Optional | **Do not send.** Temperature-controlled (reefer) freight is not supported yet: any non-zero min/max is rejected with 400 `Reefer Shipment is not supported yet!`. |\n| temperature_limit.min | Number | Optional | The minimum temperature, if applicable (see above). |\n| temperature_limit.max | Number | Optional | The maximum temperature, if applicable (see above). |\n| stackable | Boolean | Optional | stackable = True if the shipment item can be stacked on the trailer, False otherwise. |\n| notes | String | Optional | any notes. |\n| freightClass | String | Optional | NMFC freight class of the line item (e.g. \"70\"). |\n| barcodes | Array<*String*> | Optional | The barcodes of the shipment items. |\n\n<br /> \n**PARCEL limits** (checked per package, after converting to inches and pounds): weight per package (`totalWeight` / `quantity`) <= 150 lbs, longest side <= 108 in, length + girth (longest side + 2 x (the other two sides)) <= 165 in. Length, width, height, weight and quantity must all be greater than 0, otherwise the request is rejected with 400 `invalid_field_data`.\n\n<br /> \n**Response notes**\n\n- `quote_id` is the value to pass as `quoteId` to POST /freights/booking, before `expiration_time_utc` (epoch seconds). The booking payload must match this request exactly (zipcodes, every item's dimensions/weight/quantity, and the service lists), otherwise the booking is rejected. For PARCEL quotes send the items in `IN` and `lbs` on both the quote and the booking: the quote stores parcel items converted to inches/pounds and the booking compares the raw values.\n- `transit_time` is in **days**. `transit_time_without_team` (days, nullable) is the transit time when the load is driven by a single driver instead of a team.\n- `shipmentType` echoes the type that was priced: LTL, FTL or PARCEL.\n- `charges`: the TOTAL row equals `price.amount`; each SERVICE_OPTION row (the `code` may also be the carrier-specific accessorial code) is an accessorial and the TRANSIT row is the base freight, so the non-TOTAL rows sum to the TOTAL row.\n- `insurance` is only present when `insuranceInfo` was sent. When the insurance quote fails the block is `{ \"insuranceQuoteId\": null, \"errorMessage\": \"...\" }` and the freight quote is still returned.\n",
"operationId": "quote",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QuoteBody"
}
}
}
},
"responses": {
"200": {
"description": "successful creation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QuoteResult"
}
}
}
},
"400": {
"description": "Bad Request - the request payload is missing fields or contains invalid data.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
},
"examples": {
"required_field_missing": {
"summary": "Required fields are missing",
"value": {
"code": "required_field_missing",
"message": "pickupDate is required!"
}
},
"invalid_field_data": {
"summary": "Invalid field data",
"value": {
"code": "invalid_field_data",
"message": "weightUnit must be one of lbs, kgs"
}
}
}
}
}
},
"401": {
"description": "Unauthorized - the apikey header is missing or does not match any active API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
},
"examples": {
"request_unauthorized": {
"summary": "Missing or invalid API key",
"value": {
"code": "request_unauthorized",
"message": "Invalid authorization. Requires API key."
}
}
}
}
}
},
"403": {
"description": "Forbidden - the customer account is suspended. The body carries `message` only, without `code`.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
},
"examples": {
"account_suspended": {
"summary": "Customer account suspended (no code field)",
"value": {
"message": "Your account has been suspended, please contact Warp for assistance."
}
}
}
}
}
},
"429": {
"description": "Too Many Requests - the quoting rate limit of the API key was exceeded (only POST /freights/quote, /freights/freight-quote and /freights/quote/multi-stops are rate limited; limits apply per UTC hour and per UTC day). The `Retry-After` header holds the number of seconds until the window resets.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
},
"examples": {
"rate_limit_exceeded": {
"summary": "Rate limit exceeded",
"value": {
"code": "rate_limit_exceeded",
"message": "You have reached your WARP quoting API rate limit of 200 requests per hour (UTC). Your quota resets in 1380 seconds (see the Retry-After response header). If your integration requires a higher limit, please contact your WARP account manager or email support@wearewarp.com with your expected request volume."
}
}
}
}
}
},
"500": {
"description": "Internal Server Error - an unknown error has occurred.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
},
"examples": {
"internal_server_error": {
"summary": "Internal server error",
"value": {
"code": "internal_server_error",
"message": "An unknown error has occurred."
}
}
}
}
}
}
},
"security": [
{
"api_key": []
}
]
}
},
"/freights/booking": {
"post": {
"tags": [
"Freight"
],
"summary": "book a shipment",
"description": "\n**Request parameters**\n| Name | Type | Required/Optional | Description |\n|--------------------|-------------------------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| quoteId | String | Required unless WARP has enabled booking without a quote for your account | The `quote_id` returned by a previous call to POST /freights/quote. The quote must not be expired and must not have been used by an earlier booking. The booking must match the quote **exactly**: pickup/delivery zipcodes, every item's height, length, width, sizeUnit, totalWeight, weightUnit and quantity, and the pickup/delivery/additional service lists - otherwise the request is rejected with 400 `invalid_field_data` (e.g. `Pickup Zipcode 90001 does not match with quoting request 90058.`). For PARCEL quotes send the items in `IN` and `lbs` on both the quote and the booking. |\n| shipmentType | String (\"LTL\", \"FTL\" or \"PARCEL\") | Optional | Default is \"LTL\". Ignored when `quoteId` is provided: the shipment type of the quote is used. |\n| pickupInfo | Object <**StopInfo**> | Required | The details of the pick up stop. |\n| deliveryInfo | Object <**StopInfo**> | Required | The details of the delivery stop. |\n| listItems | Array<**Item**> | Required | The list of commodities being shipped. Same **Item** schema as POST /freights/quote; `height` must be <= 108 and `temperature_limit` is accepted here (stored on the shipment). |\n| pickupServices | Array<**PickupService**> | Optional | Any pickup services required to service the shipment in the pickup location. |\n| deliveryServices | Array<**DeliveryService**> | Optional | Any delivery services required to service the shipment in the delivery location. |\n| additionalServices | Array<**AdditionalService**> | Optional | Any additional services required to service the shipment. |\n| dedicatedLane | String | Optional | Only relevant for accounts that WARP has configured for dedicated-lane booking (the value is the lane code provided by WARP). Dedicated lanes are set up by WARP for the account - please contact the Warp team. |\n| vehicleType | VehicleType | Optional | The vehicle. If not provided, the system will automatically select the best vehicle based on the items. |\n| refNum | String | Optional | An optional external reference assigned by the customer when creating the shipment. This identifier helps link the shipment in this platform with records maintained in other systems such as order management, warehouse, transportation, or accounting systems. |\n| insuranceQuoteId | String | Optional | The insuranceQuoteId returned in the insurance block of POST /freights/quote. Provide it to purchase insurance for this shipment. |\n\n<br /> \n**StopInfo** schema:\n| Name | Type | Required/Optional | Description |\n|----------------------|---------------------|-------------------|-------------------------------------------------------------------------------------------------------------------|\n| locationName | String | Optional | Location Name/Shipper Name/Consignee Name. |\n| contactName | String | Optional | The pickup contact name. |\n| contactPhone | String | Required | The pickup contact phone. |\n| phoneExtension | String | Optional | The contact phone extension. |\n| contactEmail | String | Optional | The pickup contact email. |\n| address | Object<**Address**> | Required | Pickup Address information |\n| requiresAppointment | Boolean | Optional | **true** if this stop requires appointment, |\n| appointmentInfo | Object | Optional | The range of times for which this stop is scheduled. Provide it when requiresAppointment is true. |\n| appointmentInfo.from | String | Optional | The start time of the appointment window (ISO 8601 format). |\n| appointmentInfo.to | String | Optional | The end time of the appointment window (ISO 8601 format). |\n| windowTime | Object | Required for pickupInfo, optional for deliveryInfo | The window time. `from` must not be later than `to`. |\n| windowTime.from | String | Required when windowTime is provided | Timestamp at which stop window starts (ISO 8601 format). |\n| windowTime.to | String | Required when windowTime is provided | Timestamp at which stop window ends (ISO 8601 format). |\n| instructions | String | Optional | Instructions to follow at stop |\n| refNum | String | Optional | Shipper-defined reference codes to facilitate the stop. |\n\n<br /> \n**Address** schema:\n| Name | Type | Required/Optional | Description |\n|---------|--------|-------------------|------------------------|\n| street2 | String | Optional | Line 2 of the address. |\n| street | String | Required | Line 1 of the address. |\n| city | String | Required | City of the address. |\n| state | String | Required | State of the address. |\n| zipcode | String | Required | Postal code. |\n\n<br /> \n**Response parameters**\n| Name | Type | Description |\n|------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| message | String | \"Success\" when the booking is fully completed, otherwise the payment required message (see **Payment required** below). |\n| trackingNumber | String | Identifier to track the shipment with POST /freights/tracking. Currently this is the shipment code (e.g. `S-00524-2635`), i.e. the same value as shipmentNumber. |\n| orderNumber | String | The display number (code) of the order, e.g. `P-01723-2449`. |\n| orderId | String | The ID of the created order. |\n| shipmentId | String | The ID of the created shipment. |\n| shipmentNumber | String | The display number (code) of the shipment, e.g. `S-00524-2635`. |\n| refNum | String | The unique reference numbers of the pickup and delivery stops, comma separated (e.g. `PO-001, DO-001`). |\n| insuranceStatus | String | Only present when insuranceQuoteId was provided. \"booked\" if the insurance was booked successfully, \"failed\" if it could not be booked. |\n| paymentLink | String | Only present when the customer balance is not enough to cover this booking. Open this link to add funds and complete the payment. |\n| payment | Object | Only present when the booking was paid with the saved card (see **Pay by saved card** below): `{ method: \"card\", amount_charged, card_fee, last4 }`. |\n\n<br /> \n**Payment required** <br />\n\nIf the customer balance is not enough to cover this booking, the order is still created but it is put on hold: the shipment is not processed until the payment is completed. In that case the response returns **paymentLink** together with the message *\"Your booking has been created successfully. Please add funds to your balance to complete payment and continue with the shipment.\"*\n\nAlways check for **paymentLink** in the response - when it is present, open the link to add funds and complete the payment.\n\n<br /> \n**Pay by saved card** <br />\n\nIf an admin of your organization turned on *Pay by card for API bookings* in the customer portal (Settings > API Access), a booking that the balance cannot cover is charged to the selected saved card instead: the amount charged is the booking total plus the card processing fee, and the response includes **payment**. If the card cannot be charged, no order is created and the API returns:\n\n| HTTP | code | Meaning |\n|------|--------------------------|-------------------------------------------------------------------------|\n| 402 | CHARGE_FAILED | The card was declined. Update the card in the customer portal and retry. |\n| 402 | PAYMENT_ACTION_REQUIRED | The card requires authentication (3D Secure) and cannot be charged automatically. |\n| 409 | BOOKING_IN_PROGRESS | Another booking request for the same quote is still being processed. |\n| 400 | CARD_INSURANCE_NOT_SUPPORTED | insuranceQuoteId cannot be used on a booking paid by saved card. |\n\n",
"operationId": "booking",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BookingShipment"
}
}
}
},
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BookingSuccess"
}
}
}
},
"400": {
"description": "Bad Request - the request payload is missing fields or contains invalid data.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
},
"examples": {
"required_field_missing": {
"summary": "Required fields are missing",
"value": {
"code": "required_field_missing",
"message": "pickupDate is required!"
}
},
"invalid_field_data": {
"summary": "Invalid field data",
"value": {
"code": "invalid_field_data",
"message": "weightUnit must be one of lbs, kgs"
}
}
}
}
}
},
"401": {
"description": "Unauthorized - the apikey header is missing or does not match any active API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
},
"examples": {
"request_unauthorized": {
"summary": "Missing or invalid API key",
"value": {
"code": "request_unauthorized",
"message": "Invalid authorization. Requires API key."
}
}
}
}
}
},
"403": {
"description": "Forbidden - the customer account is suspended. The body carries `message` only, without `code`.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
},
"examples": {
"account_suspended": {
# --- truncated at 32 KB (211 KB total) ---
# Full source: https://artifacts.apis.io/wearewarp-com/openapi/_original/wearewarp-com-freight-openapi.json