Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/plantasur-dev/ship-quote/llms.txt

Use this file to discover all available pages before exploring further.

This endpoint mirrors the behaviour of compareByPostalCode but accepts an explicit province code instead of deriving it from a postal code lookup. It is the right choice when your application has already retrieved a province from GET /api/v1/locations/provinces and you want to avoid redundant resolution work on the server. Pass the adminFullCode value (e.g. ES-GR, ES-M) you received from the locations endpoint directly as the province field and Ship Quote will use it as-is when querying every active agency that covers the national scope.
This endpoint is optimized for Spanish provinces only. The province field must be a valid ES-XX code. For international shipments — where no province resolution is needed — use compareByPostalCode with the appropriate countryCode.

Endpoint

POST /api/v1/rates/compareByProvinceCode

Middleware chain

Requests pass through three middleware layers before reaching the controller:
OrderMiddlewareWhat it checks
1schemaValidationRequest body must be present and non-empty
2rateDestinationValidationdestinationPostalCode and countryCode must be non-null strings; when the country matches DEFAULT_COUNTRY, postal code must match the 5-digit format (\d{5})
3rateItemsValidationitems must be a non-empty array; each item must have a positive weight, positive large/width/height, and a valid typeServices value

Request body

destinationPostalCode
string
required
The destination postal code. Must be a 5-digit string for Spanish destinations (e.g. "18001"). Passed through to agency rate lookups and postal-code exception rules.
countryCode
string
required
ISO 3166-1 alpha-2 country code. Use "ES" for Spanish provinces. This value determines which agency coverage scope (national or international) is selected.
province
string
required
Pre-resolved province code in ES-XX format (e.g. "ES-GR" for Granada, "ES-M" for Madrid). Obtain valid codes from GET /api/v1/locations/provinces — use the adminFullCode field of each location object.
items
array
required
List of shipment items to price. Must contain at least one entry.

Response body

The response is a flat JSON array with one entry per active agency in the detected scope. The structure is identical to the response from compareByPostalCode.
[]
array
Array of per-agency result objects.

Examples

curl -X POST http://localhost:3000/api/v1/rates/compareByProvinceCode \
  -H "Content-Type: application/json" \
  -d '{
    "destinationPostalCode": "18001",
    "countryCode": "ES",
    "province": "ES-GR",
    "items": [
      {
        "typeServices": "pallet",
        "weight": 215,
        "large": 80,
        "width": 90,
        "height": 80
      }
    ]
  }'

HTTP status codes

CodeMeaning
200 OKRate comparison completed. The array always contains one entry per active agency in scope, even when available is false.
400 Bad RequestValidation failed. The response body contains a message field describing the failure (e.g. "destinationPostalCode and countryCode must be strings", "items cannot be empty", "Item 2: large must be a number > 0").
404 Not FoundNo rate comparison result was produced for the given inputs.
500 Internal Server ErrorAn unhandled server-side error occurred.
A 200 response does not mean every agency returned a price. Check the available flag on each result and review incidents arrays for service-level issues before surfacing rates to end users.

This endpoint is designed for workflows that already hold a resolved province. A typical two-step flow looks like this: Step 1 — Fetch available provinces:
curl http://localhost:3000/api/v1/locations/provinces
This returns a list of location objects. Each has an adminFullCode such as "ES-GR" (Granada) or "ES-M" (Madrid). Step 2 — Submit the rate comparison with the province code:
curl -X POST http://localhost:3000/api/v1/rates/compareByProvinceCode \
  -H "Content-Type: application/json" \
  -d '{
    "destinationPostalCode": "18001",
    "countryCode": "ES",
    "province": "ES-GR",
    "items": [...]
  }'
By supplying province directly, the server bypasses the internal getProvinceByPostalCode in-memory lookup entirely and passes the code straight to the rates engine.
Use this endpoint when building UI flows with a province picker. Present the results from GET /locations/provinces as a dropdown, then pass the selected adminFullCode as province — this gives you deterministic behaviour and avoids ambiguous postal codes that span province boundaries.

Build docs developers (and LLMs) love