Get Availability
POST https://api.firmly.work/api/v2/domains/{domain}/cart/shipments/get-availability
Returns availability data for a specific shipment. Despite the name, this is a POST request — the shipment_id is sent in a JSON request body, not as a query string. The response shape varies with the shipment’s fulfillment_type:
SCHEDULED_DELIVERY→ available dates with optional time slots, and optional delivery windows.PICKUP_IN_STORE→ list of pickup locations with optional pickup options (returned only for merchants that support in-store pickup).SHIP_TO_ADDRESS→ list of available delivery dates (where supported by the merchant).
This endpoint is V2-only. V1 adapters return 501 NotImplemented.
Authentication
x-firmly-authorization(string, required) — Device access token from Browser Session
Path Parameters
domain(string, required) — The merchant’s domain (e.g.staging.luma.gift).
Request Body
shipment_id(string, required) — Target shipment identifier (fromcart.shipments[].shipment_id).
Response
One of three shapes, selected by the shipment’s fulfillment_type.
Scheduled-delivery shape
-
fulfillment_type(object) — Always{ id: "SCHEDULED_DELIVERY", name, description }. -
available_dates(array, required) — Available dates the buyer can pick from.AvailableDate properties
date(string, required) — ISO date (YYYY-MM-DD).description(string) — Optional human-readable description (e.g. “Premium delivery available”).time_slots(array) — Optional list of time slots within the date.
TimeSlot properties
slot_id(string) — Optional slot identifier — pass to Set Shipping Method asselected_time_slot.start_time(object, required) — Slot start time.
Time
utc(string, required) — ISO 8601 timestamp in UTC.local(string, required) — Local time representation.local_timezone(string, required) — IANA timezone oflocal(e.g.America/New_York).display(string) — Optional pre-formatted display string.
end_time(object, required) — Slot end time. Same{ utc, local, local_timezone, display? }shape asstart_time.description(string) — Optional description (e.g. “Morning window”).price(object) — Optional surcharge for this slot (Amount object).
-
delivery_windows(array) — Optional premium delivery windows.DeliveryWindow properties
window_id(string, required) — Window identifier.name(string, required) — Window display name.description(string, required) — Detailed description.price(object, required) — Surcharge for the window (Amount).date_range(object, required) — Range during which the window is offered.
DateRange properties
start_date(string, required) — First date (YYYY-MM-DD).end_date(string, required) — Last date (YYYY-MM-DD).
Pickup shape
Returned for PICKUP_IN_STORE shipments.
-
shipment_id(string, required) — The shipment identifier. -
fulfillment_type(object) — Always{ id: "PICKUP_IN_STORE", name, description }. -
pickup_locations(array, required) — Locations where the order can be picked up. Each location includeslocation_id,name,address, optionalphone, optionaloperating_hours, optionaldistance, and apickup_optionsarray of{ date, time_slots }per location. -
pickup_options(array) — Optional, cross-location pickup options. Each entry:{ id, description, price? }.
Delivery shape
Returned for SHIP_TO_ADDRESS shipments when the merchant exposes date selection.
-
shipment_id(string, required) — The shipment identifier. -
fulfillment_type(object) — Always{ id: "SHIP_TO_ADDRESS", name, description }. -
available_dates(array, required) — SameAvailableDateshape as the scheduled-delivery response above.
Example Request
curl -X POST https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/shipments/get-availability \-H "x-firmly-authorization: YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"shipment_id": "840b0477-b913-191a-2b4f-dc232a779f0c"}'
Response Example
{"fulfillment_type": {"id": "SCHEDULED_DELIVERY","name": "Scheduled Delivery","description": "Choose a delivery date and time"},"available_dates": [{"date": "2026-06-15","description": "Premium delivery available","time_slots": [{"slot_id": "morning-premium","start_time": {"utc": "2026-06-15T12:00:00.000Z","local": "2026-06-15 08:00","local_timezone": "America/New_York"},"end_time": {"utc": "2026-06-15T16:00:00.000Z","local": "2026-06-15 12:00","local_timezone": "America/New_York"},"description": "Morning premium delivery","price": { "currency": "USD", "value": 19.99, "number": 1999, "symbol": "$" }}]}],"delivery_windows": [{"window_id": "premium-week","name": "Premium Delivery Window","description": "White glove delivery with setup","price": { "currency": "USD", "value": 199.99, "number": 19999, "symbol": "$" },"date_range": {"start_date": "2026-06-15","end_date": "2026-06-22"}}]}
Prerequisites
- Shipping address must be set on the cart (Set Shipping Info) — otherwise the cart has no shipments.
- For scheduled-delivery or pickup results, the shipment must already carry the matching
fulfillment_type. Use Set Fulfillment Type when the merchant default is different.
Error Responses
Errors return a JSON body with code, error, and description. Program against the error value — descriptions are human-readable and may change.
400 — MissingAuthHeader
The x-firmly-authorization header is missing or empty.
{ "code": 400, "error": "MissingAuthHeader", "description": "x-firmly-authorization header is missing or invalid." }
400 — InvalidToken
The authorization token is not a valid JWT structure.
{ "code": 400, "error": "InvalidToken", "description": "Jwt token is invalid." }
400 — InvalidAPIToken
The API token (server-to-server secret) is invalid or has been revoked.
{ "code": 400, "error": "InvalidAPIToken", "description": "API token is invalid." }
400 — BadRequest
Server-to-server auth was attempted but required headers are missing or malformed.
{ "code": 400, "error": "BadRequest", "description": "Bad request." }
400 — InvalidShipmentType
The shipment’s fulfillment_type is not one this endpoint can query, or the type is not supported by the merchant.
{ "code": 400, "error": "InvalidShipmentType", "description": "The specified shipment type is not valid or not supported." }
401 — Unauthorized
The authorization token was rejected.
{ "code": 401, "error": "Unauthorized", "description": "Unauthorized." }
401 — InvalidJWTToken
The device JWT signature does not verify, or required claims are missing.
{ "code": 401, "error": "InvalidJWTToken", "description": "Jwt token is invalid." }
404 — PartnerNotFound
The appid claim on the device JWT does not map to a known partner / tenant.
{ "code": 404, "error": "PartnerNotFound", "description": "Partner not found." }
404 — DomainNotFound
The {domain} path parameter does not match any merchant configured with Firmly, or the merchant has been disabled.
{ "code": 404, "error": "DomainNotFound", "description": "This domain was not found in firmly servers." }
404 — CartNotFound
No cart exists for this device on this domain.
{ "code": 404, "error": "CartNotFound", "description": "Cart was not found." }
404 — ShipmentNotFound
The supplied shipment_id does not match any shipment on the current cart.
{ "code": 404, "error": "ShipmentNotFound", "description": "Shipment not found." }
412 — MissingShippingInfo
No shipping address is set on the cart, so it has no shipments to query. Call Set Shipping Info first — this is the common cause when get-availability is called before shipping is set.
{ "code": 412, "error": "MissingShippingInfo", "description": "Shipping info needs to be set." }
400 — InvalidInputBody
Request body fails schema validation. shipment_id must be a non-empty string.
{ "code": 400, "error": "InvalidInputBody", "description": "The body is not processable" }
422 — UnprocessableEntity
The request is well-formed but cannot be processed — typically the merchant API returned data that failed Firmly’s validation.
{ "code": 422, "error": "UnprocessableEntity", "description": "The given payload has unprocessable, invalid or non-existent data. Please check the data and try again." }
501 — NotImplemented
The merchant adapter is V1 and does not implement availability queries. Pickup and scheduled-delivery features may not be available for this merchant.
{ "code": 501, "error": "NotImplemented", "description": "Operation not implemented." }
503 — StoreUnavailable
The merchant’s API returned an unexpected response and the request could not be fulfilled. Retry with backoff.
{ "code": 503, "error": "StoreUnavailable", "description": "Store is unavailable." }