Hydra is now in beta|Get started free|Follow our journey on X.com

Shipping API
On this page

Shipping

Hydra supports flat-rate and carrier-calculated shipping through zones and rates. A shipping zone defines which countries a set of rates applies to. Rates within a zone can be filtered by order subtotal, weight, and currency. The storefront rate lookup endpoint matches a destination to the best zone and returns available rates.

Base URL: https://api.hydrajs.dev

Endpoints

Method Path Auth Description
GET /v1/shipping/zones Secret List shipping zones
POST /v1/shipping/zones Secret Create a shipping zone
GET /v1/shipping/zones/{id} Secret Get a shipping zone
PATCH /v1/shipping/zones/{id} Secret Update a shipping zone
DELETE /v1/shipping/zones/{id} Secret Delete a shipping zone
POST /v1/shipping/zones/{id}/rates Secret Create a rate in a zone
PATCH /v1/shipping/rates/{id} Secret Update a rate
DELETE /v1/shipping/rates/{id} Secret Delete a rate
POST /v1/shipping/rates Publishable Get available rates for a destination

List shipping zones

GET /v1/shipping/zones

Returns a paginated list of shipping zones. Use expand=rates to include each zone’s rates inline.

Query parameters

Parameter Type Default Description
limit integer 25 Results per page (1-100)
cursor string - Pagination cursor from a previous response
sort string position Sort field: position, created_at
order string asc Sort direction: asc, desc
expand string - Comma-separated: rates
fields string - Comma-separated fields to return

Request

curl "https://api.hydrajs.dev/v1/shipping/zones?expand=rates" \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Response 200

{
	"data": [
		{
			"id": "shz_abc123",
			"name": "United States",
			"countries": ["US"],
			"is_rest_of_world": false,
			"is_active": true,
			"carrier_callback_url": null,
			"position": 0,
			"rate_count": 2,
			"rates": [
				{
					"id": "shr_def456",
					"zone_id": "shz_abc123",
					"name": "Standard Shipping",
					"description": "5-7 business days",
					"price": 599,
					"currency": "USD",
					"min_order_subtotal": null,
					"max_order_subtotal": null,
					"min_order_weight": null,
					"max_order_weight": null,
					"min_delivery_days": 5,
					"max_delivery_days": 7,
					"is_active": true,
					"position": 0,
					"created_at": "2026-08-10T14:00:00Z",
					"updated_at": "2026-08-10T14:00:00Z"
				},
				{
					"id": "shr_ghi789",
					"zone_id": "shz_abc123",
					"name": "Express Shipping",
					"description": "1-2 business days",
					"price": 1499,
					"currency": "USD",
					"min_order_subtotal": null,
					"max_order_subtotal": null,
					"min_order_weight": null,
					"max_order_weight": null,
					"min_delivery_days": 1,
					"max_delivery_days": 2,
					"is_active": true,
					"position": 1,
					"created_at": "2026-08-10T14:00:00Z",
					"updated_at": "2026-08-10T14:00:00Z"
				}
			],
			"created_at": "2026-08-10T14:00:00Z",
			"updated_at": "2026-08-10T14:00:00Z"
		}
	],
	"pagination": {
		"cursor": null,
		"has_more": false,
		"total": 1
	}
}

Pagination

All list endpoints use cursor-based pagination. Pass the cursor value from the response to fetch the next page.


Create a shipping zone

POST /v1/shipping/zones

Creates a new shipping zone. Each zone covers a set of countries (ISO 3166-1 alpha-2 codes). You can also create a “rest of world” zone as a fallback for unmatched countries.

Request body

Field Type Required Description
name string Yes Zone name (max 255 chars)
countries string[] No Array of 2-letter country codes (max 250, default [])
is_rest_of_world boolean No Fallback zone for unmatched countries (default false)
is_active boolean No Whether the zone is active (default true)
carrier_callback_url string No HTTPS URL for carrier-calculated rates (max 2048 chars)
position integer No Display order (default 0)

One rest-of-world zone

Only one rest-of-world zone is allowed per project. Creating a second one returns a 409 Conflict error.

Request

curl -X POST https://api.hydrajs.dev/v1/shipping/zones \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "United States",
    "countries": ["US"],
    "is_active": true,
    "position": 0
  }'

Response 201

{
	"data": {
		"id": "shz_abc123",
		"name": "United States",
		"countries": ["US"],
		"is_rest_of_world": false,
		"is_active": true,
		"carrier_callback_url": null,
		"position": 0,
		"rate_count": 0,
		"rates": [],
		"created_at": "2026-08-17T10:00:00Z",
		"updated_at": "2026-08-17T10:00:00Z"
	}
}

Get a shipping zone

GET /v1/shipping/zones/{id}

Returns a single shipping zone by ID. Use expand=rates to include the zone’s rates inline.

Query parameters

Parameter Type Description
expand string Comma-separated: rates
fields string Comma-separated fields to return

Request

curl "https://api.hydrajs.dev/v1/shipping/zones/shz_abc123?expand=rates" \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Response 200

{
	"data": {
		"id": "shz_abc123",
		"name": "United States",
		"countries": ["US"],
		"is_rest_of_world": false,
		"is_active": true,
		"carrier_callback_url": null,
		"position": 0,
		"rate_count": 2,
		"rates": [
			{
				"id": "shr_def456",
				"zone_id": "shz_abc123",
				"name": "Standard Shipping",
				"description": "5-7 business days",
				"price": 599,
				"currency": "USD",
				"min_order_subtotal": null,
				"max_order_subtotal": null,
				"min_order_weight": null,
				"max_order_weight": null,
				"min_delivery_days": 5,
				"max_delivery_days": 7,
				"is_active": true,
				"position": 0,
				"created_at": "2026-08-10T14:00:00Z",
				"updated_at": "2026-08-10T14:00:00Z"
			}
		],
		"created_at": "2026-08-10T14:00:00Z",
		"updated_at": "2026-08-10T14:00:00Z"
	}
}

Update a shipping zone

PATCH /v1/shipping/zones/{id}

Updates a shipping zone. All fields are optional. Send only the fields you want to change.

Request body

Field Type Description
name string Zone name (max 255 chars)
countries string[] Array of 2-letter country codes (replaces entire array)
is_rest_of_world boolean Fallback zone flag
is_active boolean Active state
carrier_callback_url string | null Carrier callback URL. Set to null to remove
position integer Display order

Request

curl -X PATCH https://api.hydrajs.dev/v1/shipping/zones/shz_abc123 \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "US & Canada",
    "countries": ["US", "CA"]
  }'

Response 200

Returns the full updated shipping zone object (same shape as Get a shipping zone).


Delete a shipping zone

DELETE /v1/shipping/zones/{id}

Permanently deletes a shipping zone and all its rates. Fires a shipping.zone.deleted webhook event.

Request

curl -X DELETE https://api.hydrajs.dev/v1/shipping/zones/shz_abc123 \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Response 204

Empty body.


Create a rate

POST /v1/shipping/zones/{id}/rates

Creates a shipping rate within a zone. Rates can be constrained by order subtotal, order weight, and currency.

Request body

Field Type Required Description
name string Yes Rate name (max 255 chars)
description string No Short description (max 1000 chars)
price integer No Price in cents (default 0 for free shipping)
currency string Yes 3-letter ISO currency code
min_order_subtotal integer No Minimum order subtotal in cents
max_order_subtotal integer No Maximum order subtotal in cents
min_order_weight integer No Minimum total weight in grams
max_order_weight integer No Maximum total weight in grams
min_delivery_days integer No Minimum estimated delivery days
max_delivery_days integer No Maximum estimated delivery days
is_active boolean No Active state (default true)
position integer No Display order within the zone (default 0)

Free shipping threshold

To offer free shipping above a subtotal, create a rate with price: 0 and min_order_subtotal set to the threshold (e.g. 5000 for orders over $50).

Request

curl -X POST https://api.hydrajs.dev/v1/shipping/zones/shz_abc123/rates \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Standard Shipping",
    "description": "5-7 business days",
    "price": 599,
    "currency": "USD",
    "min_delivery_days": 5,
    "max_delivery_days": 7,
    "position": 0
  }'

Response 201

{
	"data": {
		"id": "shr_def456",
		"zone_id": "shz_abc123",
		"name": "Standard Shipping",
		"description": "5-7 business days",
		"price": 599,
		"currency": "USD",
		"min_order_subtotal": null,
		"max_order_subtotal": null,
		"min_order_weight": null,
		"max_order_weight": null,
		"min_delivery_days": 5,
		"max_delivery_days": 7,
		"is_active": true,
		"position": 0,
		"created_at": "2026-08-17T10:00:00Z",
		"updated_at": "2026-08-17T10:00:00Z"
	}
}

Update a rate

PATCH /v1/shipping/rates/{id}

Updates a shipping rate. All fields are optional. Set nullable fields to null to clear them.

Request body

Field Type Description
name string Rate name (max 255 chars)
description string | null Short description
price integer Price in cents
currency string 3-letter ISO currency code
min_order_subtotal integer | null Minimum order subtotal in cents
max_order_subtotal integer | null Maximum order subtotal in cents
min_order_weight integer | null Minimum weight in grams
max_order_weight integer | null Maximum weight in grams
min_delivery_days integer | null Minimum delivery days
max_delivery_days integer | null Maximum delivery days
is_active boolean Active state
position integer Display order

Request

curl -X PATCH https://api.hydrajs.dev/v1/shipping/rates/shr_def456 \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "price": 499,
    "max_delivery_days": 8
  }'

Response 200

Returns the full updated rate object.


Delete a rate

DELETE /v1/shipping/rates/{id}

Permanently deletes a shipping rate.

Request

curl -X DELETE https://api.hydrajs.dev/v1/shipping/rates/shr_def456 \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Response 204

Empty body.


Get available rates

POST /v1/shipping/rates

Returns all shipping rates available for a destination. This is the storefront-facing endpoint used during checkout to display shipping options to the customer.

Hydra matches the destination country to the first active zone (by position) that includes it. If no zone matches, the rest-of-world zone is used as a fallback. Rates are filtered by currency, subtotal, and weight, then sorted by price ascending.

If the matched zone has a carrier_callback_url, Hydra also calls the carrier endpoint and merges those rates into the results.

Request body

Field Type Required Description
country string Yes ISO 3166-1 alpha-2 country code (2 letters)
state string No State or province code (max 100 chars)
postal_code string No Postal code (max 20 chars)
subtotal integer Yes Order subtotal in cents
currency string Yes 3-letter ISO currency code
items object[] No Cart items for weight calculation. Each: weight_grams (int), quantity (int)

Request

curl -X POST https://api.hydrajs.dev/v1/shipping/rates \
  -H "Authorization: Bearer pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "country": "US",
    "state": "CA",
    "postal_code": "94102",
    "subtotal": 8999,
    "currency": "USD",
    "items": [
      { "weight_grams": 500, "quantity": 2 }
    ]
  }'

Response 200

{
	"data": [
		{
			"id": "shr_def456",
			"name": "Standard Shipping",
			"description": "5-7 business days",
			"price": 599,
			"currency": "USD",
			"min_delivery_days": 5,
			"max_delivery_days": 7,
			"source": "flat"
		},
		{
			"id": "shr_ghi789",
			"name": "Express Shipping",
			"description": "1-2 business days",
			"price": 1499,
			"currency": "USD",
			"min_delivery_days": 1,
			"max_delivery_days": 2,
			"source": "flat"
		}
	]
}

Rate sources

Each rate includes a source field: flat for rates defined in the Hydra admin, or carrier for rates returned by a carrier callback URL. Carrier rates have generated IDs prefixed with carrier_.


Carrier callbacks

When a shipping zone has a carrier_callback_url, Hydra sends a POST request to that URL during rate lookup with the destination and cart details. Your endpoint must return a JSON response within 5 seconds.

Callback request body

{
	"destination": {
		"country": "US",
		"state": "CA",
		"postal_code": "94102"
	},
	"items": [{ "weight_grams": 500, "quantity": 2 }],
	"subtotal": 8999,
	"currency": "USD"
}

Expected callback response

{
	"rates": [
		{
			"name": "FedEx Ground",
			"description": "3-5 business days",
			"price": 899,
			"currency": "USD",
			"min_delivery_days": 3,
			"max_delivery_days": 5
		}
	]
}

The rates array accepts up to 10 rates. If the callback fails, times out, or returns invalid data, Hydra silently falls back to flat rates only.


Webhooks

Shipping zone changes fire the following webhook events:

Event Trigger
shipping.zone.created A shipping zone is created
shipping.zone.updated A shipping zone is updated
shipping.zone.deleted A shipping zone is deleted

See Webhooks for subscription setup.


The shipping zone object

Field Type Description
id string Unique ID (prefix: shz_)
name string Zone name
countries string[] ISO 3166-1 alpha-2 country codes
is_rest_of_world boolean Whether this is the fallback zone
is_active boolean Whether the zone is active
carrier_callback_url string | null URL for carrier-calculated rates
position integer Display order
rate_count integer Number of rates in the zone
rates object[] Expanded with ?expand=rates
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

The shipping rate object

Field Type Description
id string Unique ID (prefix: shr_)
zone_id string Parent zone ID
name string Rate name
description string | null Short description
price integer Price in cents
currency string 3-letter ISO currency code
min_order_subtotal integer | null Minimum subtotal for this rate to apply
max_order_subtotal integer | null Maximum subtotal for this rate to apply
min_order_weight integer | null Minimum weight in grams
max_order_weight integer | null Maximum weight in grams
min_delivery_days integer | null Minimum estimated delivery days
max_delivery_days integer | null Maximum estimated delivery days
is_active boolean Whether the rate is active
position integer Display order within the zone
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp