Storefront API
Shopper-facing lookups that power delivery choices on your webstore or app. Fetch the delivery options a shopper can pick, live carrier rates for a route, a per-product delivery promise for product pages, the eligible fulfillment or collection locations near a customer, and phone-number validation. Every call is stateless: none of them creates an order or a shipment.
Storefront
Shopper-facing evaluations for your webstore or app. Given a cart, a product, or a customer location, these lookups return the delivery choices, rates, promises, and pickup or fulfillment locations to show the shopper.
They are stateless: no order or shipment is created. Storefront frontends and headless commerce middleware call them, so they run at higher volume than the per-shipment management endpoints. To manage the delivery options behind these lookups, see the delivery-options endpoints in the Core API.
4 operations · 0 objects
/storefront/delivery-optionsGet delivery options
Returns the delivery options that match the supplied cart or order details at checkout time.
Delivery options are configured per merchant in the Carriyo Dashboard. Each option declares the carrier account that fulfils it, a shipping fee, an estimated delivery window, and a set of optional conditions. This endpoint evaluates the configured conditions against the order details you supply inline and returns the matching options, typically rendered to the shopper as the delivery choices on the checkout page.
Both DELIVERY and COLLECTION options can be returned. The shopper has not chosen between
them at this point, so customer represents where the customer is, not where the order is
being delivered. For DELIVERY options the customer's location is also the delivery
destination; for COLLECTION options it's used to find applicable collection points.
Supplying order details
Pass the order details inline in the request body. merchant and line_items (with at
least one item) are required; a request without line items is rejected with a 400.
Populate the remaining fields based on which conditions the merchant has configured. This
endpoint does not look up existing orders; all order data must be provided directly in the
request.
Restricting by delivery method
Pass delivery_methods to limit the response to only the methods you can render. For
example, send ["DELIVERY"] from a storefront that doesn't support pickup points, or
["COLLECTION"] from a click-and-collect locator screen. Omit the field to receive all
matching methods.
What gets evaluated
Each condition only applies when the merchant has configured it on a delivery option. The corresponding order field is read only if such a condition exists, so callers only need to populate the fields relevant to the rules in use.
| Condition (configured on the option) | Evaluated against |
|---|---|
| Working days / blackout days | order_date (defaults to now); timezone derived from
customer.country |
| Customer geography | customer.{country, state, city, area} |
| Order value range | payment.order_total |
| Weight range | Total order weight: sum of line_items[].weight × quantity (converted to
kg) |
| Payment type | Derived from payment.payment_on_delivery: CASH_ON_DELIVERY when it is
greater than 0, otherwise PRE_PAID |
| Product categories | The line-item categories in the cart, judged for the whole
order. Each category is resolved request-first (line_items[].category), then from the
product catalog by product_id. An includes rule matches when at least one line item has
a listed category; an excludes rule matches when no line item has one. Matching is
case-insensitive |
| Item product categories | The same categories, judged per line item: instead of showing or hiding the option, the condition scopes which items the option can deliver (see Item-level category scoping below) |
| Fulfillment location | fulfillment_locations[]. Pass one or more candidate
fulfillment locations. An option matches if at least one of the supplied locations is in the
option's allowlist (or the option has no allowlist). For a configured Carriyo location,
supply either partner_location_code (your own code, recommended for storefront
integrations) or partner_location_id (Carriyo's internal ID); free-form address fields
are also accepted |
Item-level category scoping
An option configured with item_product_categories applies per item, not to the whole
order. With includes, the option applies only to items whose category is listed; with
excludes, items with a listed category are excluded and every other item qualifies. An
item with no category fails a non-empty includes list and passes an excludes-only
condition; matching is case-insensitive and ignores surrounding whitespace.
Excluded items are marked availability: NONE with fulfillable_quantity: 0 in every
entry of the option — even when stock-aware filtering is not effective. A condition
exclusion is an evaluation, so it is the one exception to "absent means not evaluated":
the mark appears without any stock read, and it overrides UNKNOWN. Excluded items count
toward the entry's verdict — a scoped option on a mixed cart reads PARTIAL — and an
option whose condition excludes every cart item is not returned at all.
Sorting the results
Results are always availability-banded first. Entries that can provide the whole cart
(availability: FULL — or, when stock isn't evaluated, entries listing every line item)
come before the rest; within the partial band, entries are ordered by how many line items
they can at least partly provide (most first). This keeps the choices a shopper can fully
order at the top.
Within each band, sort_by orders the entries:
SPEED(default): earliestestimated_arrival_tofirst.COST: lowest shipping fee first.
Shipping fee resolution
Each returned option carries a shipping_fee computed from its configured pricing
strategy:
FREE_OF_COST: alwaysamount: 0, in the option's default currency when one is configured.PAID: resolved from the option's pricing configuration. Carriyo picks the pricing entry matchingpayment.currency, falling back to the entry matching the option's default currency (or to the first configured entry when no default currency is set). AFIXED_PRICEoption returns that entry's amount; aTIERED_ORDER_VALUEoption returns the amount of the first tier whose range containspayment.order_total.PASS_THROUGH: a live carrier rate quote from the option's carrier account, computed from the supplied order details (parcelsand the extended line-item fields). An option saved asPASS_THROUGHwithout a carrier account is downgraded toFREE_OF_COSTat save time, so it never reaches this endpoint asPASS_THROUGH.
A TIERED_ORDER_VALUE fee whose final, unbounded tier charges 0 also reports that
tier's min_value as free_shipping_threshold — the order value at and above which the
option ships free. To offer "free shipping above X", configure exactly that shape: a
tiered fee ending in a free tier. A separate free option gated by an order-value
condition cannot report a threshold. The threshold is derived from the matched pricing
configuration, not from the cart, so it is returned regardless of the current order
value.
In edge cases an option is returned with an empty shipping_fee ({}): when a
TIERED_ORDER_VALUE fee finds no tier containing the order total (or the request omits
payment.order_total), when a default currency is configured but neither it nor
payment.currency matches any pricing entry, or when a PASS_THROUGH rate lookup fails
(for example, the carrier account no longer exists). Treat a fee without an amount as
"no price available", not as free shipping. In the first case the matched tier table
still derives its free_shipping_threshold, so the fee may carry
free_shipping_threshold with no amount or currency — which is exactly what an
"add X more for free shipping" prompt needs when the cart value is not yet known. When
no pricing entry matched at all, there is no table to derive from and the fee is truly
empty.
Fees are always evaluated against the request as supplied: a TIERED_ORDER_VALUE fee on
a PARTIAL entry is still looked up against the cart's payment.order_total, not the
value of the entry's available subset. For exact per-consignment fees, requote each chosen
subset with its own payment.
A failure while computing an option's fee drops that option from the response — a missing
fee would read as free shipping downstream. A failure after the fee resolves (for
example, in the arrival estimate) fails open instead: the option is returned with its
shipping_fee, no arrival estimate, and availability: UNKNOWN when stock was being
evaluated.
Collection points for COLLECTION options
For each matching COLLECTION option, Carriyo also returns a list of eligible collection
points (configured Carriyo locations with the collection_location flag enabled) under
customer_collection_locations on the response item.
The candidate set comes from the option's configuration. An option that links an explicit
list of collection locations offers exactly those locations (filtered to ACTIVE,
collection-enabled ones). An option with an empty or omitted list means any
location: it resolves to every ACTIVE collection-enabled location the merchant can use,
restricted to the customer's country (customer.country). If nothing resolves — for
example, no collection-enabled location exists in the customer's country — the option is
omitted from the response.
The country semantics differ deliberately between the two configurations. The any-location
behaviour is always same-country: customers collect where they are, so Carriyo bounds the
resolved set to customer.country. An explicit list is not country-filtered — it is
the merchant's deliberate selection, and may include cross-border collection points (for
example, a store just across a border from the customer's city); the distance cap, when in
effect, is a proximity bound rather than a country bound. Note this contrasts with
fulfillment_locations, where an empty list means any fulfilling location regardless of
country — fulfillment can legitimately be cross-border, and each fulfillment location
carries its own configurable coverage (zones or radius).
Three pieces of input then shape the result:
customer.coords: when supplied (latitude/longitude), Carriyo computes the distance from the customer to each location and sorts the result nearest-first. Locations without coordinates are excluded from a distance-bound result. When customer coordinates aren't supplied, locations are returned in the merchant-configured order (location-code order for options without a configured list) with no distance field.max_collection_distance(request): a client-supplied upper bound on the returned distance. Effective only when customer coordinates are supplied.customer_collection_max_distance(per-option, configured by the merchant): a hard upper bound the merchant authored for this option. Carriyo applies the smaller of this and the request'smax_collection_distancewhen filtering.
The result list is capped at max_collection_locations (defaults to 10 when omitted,
capped server-side at 50).
Stock-aware filtering
Set inventory_check to true to evaluate delivery options against real-time stock. The
check is effective only when all of the following hold:
inventory_checkistruein the request.Inventory management is enabled for the tenant in Carriyo settings.
The line items carry a
product_id, or aproduct_refthat resolves to one (seeline_items).
When effective, every entry in the response is a single-delivery fact: the items it
marks as available are deliverable together in one delivery, from any one of the
entry's fulfillment_locations, at the entry's shipping_fee. No entry ever claims
fulfilment across several locations; composing a multi-delivery checkout is the caller's
explicit act (see include_variations below).
Each entry carries:
items— every cart line item, each marked with anavailability(FULL,PARTIAL,NONE, orUNKNOWN) and, when evaluated, thefulfillable_quantitythis entry can provide. Items the entry cannot supply are listed asNONE, not dropped.fulfillment_locations— the locations this entry can be fulfilled from, as{partner_location_id, partner_location_code, partner_location_name}objects. Each listed location can on its own fulfil everything the entry marks as available.availability— the entry's verdict for the whole cart:FULL,PARTIAL, orUNKNOWN.
An absent availability field — at any level — always means not evaluated (the stock
check is off, or a line has no resolvable product), never "unavailable". UNKNOWN means
the check ran and failed to answer: treat it as "no answer", never as out of stock. The
one mark that appears without a stock read is the NONE forced by an option's
item_product_categories condition (see Item-level category scoping above).
When the request supplies fulfillment_locations, they narrow the whole evaluation: the
stock read, the returned fulfillment_locations lists, and the location used for the fee
and arrival estimate all consider only the requested locations. Pass a single location and
an option's presence means that location can serve this cart.
Location eligibility honors each location's fulfillment coverage, the same zone and radius
gating described in Get eligible locations. Radius
coverage is matched by distance, so it needs customer.coords in the request. Without
customer coordinates, a radius-covered location is never eligible and its stock is
invisible to this endpoint. Pass customer coordinates whenever the merchant fulfills from
radius-covered locations.
Delivery options that cannot fulfill any of the requested items are omitted entirely
from the response — unless an item's inventory read failed, in which case the option is
returned marked UNKNOWN rather than hidden.
When stock-aware filtering is not effective (inventory_check is false or omitted,
inventory management is disabled, or no product_id is supplied), the endpoint does not
evaluate stock:
itemsechoes back all request line items, carrying no availability marks (not evaluated) — except items excluded by the option'sitem_product_categoriescondition, which are still markedNONEwithfulfillable_quantity: 0.fulfillment_locationsreturns the option's configured fulfillment locations as{partner_location_id, partner_location_code, partner_location_name}objects (or is omitted if none are configured).
Cart splitting (include_variations)
By default each option appears at most once: the entry with the best coverage (most fully
covered items, then most covered quantity, then the option's configured location order).
When no single location can supply the whole cart, that best entry is PARTIAL — the
response never silently promises a split delivery.
Set include_variations to true to receive every maximal single-delivery variation
of each option as its own entry — same code, different items marks and
fulfillment_locations. Entries whose coverage is contained in another entry's are
dropped, so the response is bounded at one entry per candidate location. Entries sharing a
code are distinct single-delivery alternatives of the same option, not duplicates: pick
one, or compose several into a multi-delivery checkout, requoting each chosen subset for
its exact fee.
Routing-rules preview (allocation_check)
allocation_check controls whether the merchant's order-allocation routing rules are
applied on top of the stock read. It defaults to the value of inventory_check, so
omitting it changes nothing. Set it to false alongside inventory_check: true for a
pure stock answer with no routing policy applied. Setting it to true without
inventory_check is rejected with a 400 — the rules operate on the stock table, so the
combination has no meaning.
Response
An array of single-delivery entries, each with its carrier account, computed shipping fee,
and estimated arrival window, availability-banded then ordered by sort_by. By default
each matching option appears once; with include_variations: true an option can appear
several times (same code, different items and fulfillment_locations). The array is
empty if no configured option matches the supplied order.
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| Content-Type | application/json | Yes | Media type of the request body. |
Request body
application/jsonSchema: delivery-options-requestrequired- The sales channel the cart originates from, matching
sales_channelon the order you create afterwards. Used during stock-aware filtering to evaluate allocation rules conditioned on sales channel, so the cart sees the same rule decisions the order will. When omitted, channel-scoped allocation rules do not match. - The items in the order. At least one item is required.
weight.valueis the weight of a single unit; the total weight for a line isweight.value × quantity. The total order weight used for weight range conditions is the sum of those per-line totals, converted to kg. Identify each line withproduct_idorproduct_refto make stock-aware filtering effective (seeinventory_check). Setcategoryto drive product-category conditions; when omitted, the category comes from the resolved catalog product. - Candidate locations the order could be fulfilled from (origin/warehouse/store). Pass one or more, and Carriyo returns the options whose fulfillment-location allowlist contains at least one of these (options without an allowlist are unconstrained). Per option, the first matching location is used to drive origin-country-based estimated arrival and, for
PASS_THROUGHpricing, the carrier rate quote. Each entry may be a free-form address, or, for a configured Carriyo location, supplypartner_location_code(your own code, recommended) orpartner_location_id(Carriyo's internal ID), and the rest of the address is populated from the location record. An entry referencing a location that does not exist (e.g. a typo'd code) is rejected with a400naming the offending entry. When stock-aware filtering is effective (seeinventory_check), the supplied locations narrow everything: which options match, which locations the stock evaluation considers, and the location lists in the response. Pass a single location and an option's presence means that location can serve this cart. - The customer's location. Drives customer-geography conditions and the timezone used for working-day / blackout-day evaluation. Strongly recommended for any non-trivial result. For
DELIVERYoptions this is also the implicit delivery destination. ForCOLLECTIONoptions it's used to find applicable collection points. The shopper has not chosen between the two at this stage; the field captures where the customer is, not where the order is being delivered. - Whether the merchant's order-allocation routing rules are applied on top of the stock read. Defaults to the value of
inventory_check, so omitting it changes nothing. Set tofalsealongsideinventory_check: truefor a pure stock answer with no routing policy applied.truewithoutinventory_check: trueis rejected with a400. - Set to
trueto return every maximal single-delivery variation of each option as its own entry — samecode, differentitemsmarks andfulfillment_locations— instead of only the best-coverage entry per option. Entries sharing acodeare distinct single-delivery alternatives of the same option: pick one, or compose several into a multi-delivery checkout, requoting each chosen subset for its exact fee. Meaningful only when stock-aware filtering is effective (seeinventory_check); otherwise each option yields a single entry anyway. - Restrict the response to options of the listed methods. When omitted or empty, all methods are returned. Useful when the storefront has separate UI tabs for delivery and click-and-collect, or when the integration only supports one method (e.g., Shopify's standard Carrier Service API has no pickup-point concept, so the Shopify connector sets this to
["DELIVERY"]). - Client-supplied upper bound on the distance from the customer's location to a returned collection point. The effective cap used by Carriyo is the smaller of this value and any per-option
customer_collection_max_distanceconfigured by the merchant. When the customer's coordinates aren't supplied, this cap can't be enforced and is ignored.
Responses
An array of delivery-options-response-item. Each item has the following fields:
- The fulfilment method for this option: -
DELIVERY: courier delivers to the customer's address. -COLLECTION: customer collects from a designated location. -DIGITAL: no physical fulfilment. Aligns withFulfillmentOrder.delivery_methodon the order model.Values:COLLECTIONDELIVERYDIGITAL - The shipping fee computed for the option. In edge cases it is returned empty (
{}), or with onlyfree_shipping_threshold— see "Shipping fee resolution" on Get delivery options. Treat a fee without anamountas "no price available", not as free shipping. - Earliest estimated arrival date/time (ISO 8601). Absent when the option configures no delivery window, leaving
estimated_arrival_toas the only arrival value — render the estimate as a single point rather than a range. Both arrival fields are absent when the option configures no delivery estimate at all, and on an entry that failed after its fee resolved. - Every line item from the request, each marked with what this entry can provide of it and keyed by
line_item_id(the line'sid, or the one Carriyo assigned when you omitted it — seeline_items[].id). When stock-aware filtering is effective (inventory_checkistrue, inventory management is enabled, and the line items carryproduct_id), each item carries anavailability(FULL,PARTIAL,NONE, orUNKNOWN) and, when evaluated, afulfillable_quantityfor this entry. Items the entry cannot supply are listed asNONE, not dropped; the marked items are deliverable together in one delivery from any one of the entry'sfulfillment_locations. When stock-aware filtering is not effective, all request line items are returned here with no availability marks — absence means "not evaluated", never unavailable. Items excluded by the option'sitem_product_categoriescondition are the exception: they are markedNONEwithfulfillable_quantity: 0in every entry, stock read or not. An option that can provide none of the items is omitted from the response entirely (unless the answer is unknown — seeavailability), so a returned entry always lists at least one line item. - The locations this entry can be fulfilled from, each as a
{partner_location_id, partner_location_code, partner_location_name}object. When stock-aware filtering is effective, each listed location can on its own fulfil everything this entry marks as available — the entry is a single delivery from any one of them. Locations that can only cover a different subset of the cart surface as separate entries (seeinclude_variations); the list is never a union of partially-capable locations. When stock-aware filtering is not effective, this returns the option's configured fulfillment locations. Omitted (null) if the option has no configured fulfillment locations. - This entry's verdict for the whole cart:
FULLwhen every line item is fully available from this entry,PARTIALwhen some aren't,UNKNOWNwhen any line's inventory read failed (the cart-level answer is unknowable — treat as "no answer", never as out of stock). Lines that were never evaluated (no resolvable product) don't count against the verdict; lines excluded by the option'sitem_product_categoriescondition do — they areNONE, so a scoped option on a mixed cart readsPARTIAL, even when stock-aware filtering is not effective. Otherwise absent when stock-aware filtering was not effective — absence means "not evaluated", never unavailable. An option that fails while being assembled after its fee resolved is returned as a minimal entry —availability: UNKNOWN(when stock was being evaluated), itsshipping_fee, and no arrival estimate — rather than dropped.Values:FULLPARTIALUNKNOWN - Eligible collection points for this option. Populated only when
delivery_methodisCOLLECTION. Sorted nearest-first when the customer's coordinates are supplied; otherwise returned in the merchant-configured order (location-code order for options without a configured list). An option configured without a location list resolves to anyACTIVEcollection-enabled location in the customer's country.COLLECTIONoptions with no resolvable collection points (none configured and eligible, or none within the effective distance cap) are omitted from the response entirely.
Need the full machine-readable spec? Download the OpenAPI document →
/storefront/validate/phoneValidate a phone number
Validates a customer phone number and returns its parsed parts.
Carriyo parses the number with libphonenumber. Pass the number and, when the number is in national format, the country whose dialling rules apply. Use this at checkout to catch a mistyped number before the shopper places the order.
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| Content-Type | application/json | Yes | Media type of the request body. |
Request body
application/jsonSchema: validate-phone-requestrequiredResponses
validate-phone-responseNeed the full machine-readable spec? Download the OpenAPI document →
/storefront/product-delivery-optionsGet per-product delivery options
Returns the delivery options available for each product in a list, so you can show a delivery promise (for example "Get it in 45 minutes") on a product listing or product detail page.
Unlike Get delivery options, which evaluates one cart as a whole, this endpoint evaluates each product on its own from its own fulfillment location. Send the products and the location each one ships from; Carriyo returns the matching delivery options per product.
Choosing the fulfillment location
Set fulfillment_locations at the top level as the default for every product, and override
it per product under products[].fulfillment_locations. Reference a configured Carriyo
location by partner_location_id or partner_location_code. To find the nearest eligible
locations for a customer first, call Get eligible
locations.
Category and value
Each product's category is resolved request-first (products[].category), then from the
catalog entry the product resolved to. The product's value is unit_price × quantity.
Both feed the same option conditions as the cart endpoint. An option whose
item_product_categories condition excludes the product's category is omitted from that
product's delivery_options — the per-product counterpart of the cart endpoint marking
the item NONE. Options priced PASS_THROUGH (a live carrier quote) are omitted from
this endpoint.
Shipping fee
Fees resolve exactly as they do on the cart endpoint — see "Shipping fee resolution" on
Get delivery options — with the product's
unit_price × quantity standing in for the cart's order total, and PASS_THROUGH options
excluded before pricing runs.
The request currency selects which of the option's configured pricing entries applies; it
does not force the currency of the answer. When no entry matches, Carriyo falls back to
the option's default-currency entry, then to its first configured entry — so
shipping_fee.currency can differ from the currency you sent. Always render the returned
currency, never the requested one. An option that resolves no fee at all returns an empty
shipping_fee ({}); treat that as "no price available", not as free shipping.
free_shipping_threshold carries over from the cart endpoint unchanged: a tiered fee
whose final, unbounded tier charges 0 reports that tier's min_value as the order
value at and above which the option ships free. It is derived from the matched pricing
configuration, not from this product's value, and stays present even on an entry whose
fee amount could not be resolved.
Stock
Set inventory_check to true to mark each delivery-option entry with an availability
verdict (FULL, PARTIAL, or NONE against the requested quantity) and a
fulfillable_quantity capped at the requested quantity. It is effective only when
inventory management is enabled for the tenant. Absolute stock counts are never returned —
the verdict and the request-capped quantity are the whole answer.
A product with no stock anywhere still returns its eligible options, each marked
availability: NONE with fulfillable_quantity: 0 — options are never dropped for being
out of stock. An option is absent from a product's delivery_options only when it does
not match the product (conditions, item_product_categories) or serves none of the
product's fulfillment locations.
When the check is effective, availability also honors each location's fulfillment coverage
(zones or radius, as described in Get eligible
locations). A location outside coverage has no stock
to offer, so it can only appear on entries marked NONE. Radius coverage is matched by
distance, so it needs customer.coords: pass customer coordinates when working with
radius-covered locations.
allocation_check controls whether the merchant's order-allocation routing rules are
applied on top of the stock read. It defaults to the value of inventory_check, so
omitting it changes nothing. Set it to false alongside inventory_check: true for a
pure stock answer with no routing policy applied; true without inventory_check is
rejected with a 400.
If the stock read fails, the endpoint never fails closed: entries are returned as if no
stock check ran (no fulfillable_quantity, delivery options evaluated normally), marked
with availability: UNKNOWN — treat that as unknown, never as out of stock.
Limits
At most 50 products per request.
At most 5 fulfillment locations per product.
A product may not be requested twice.
Response
A bare array, one object per requested product: the resolved product_id, your
product_ref when you supplied one, the requested quantity, and its
delivery_options. Each eligible option appears exactly once per product, as a
single-delivery fact mirroring the cart endpoint's contract: the option's display fields
and shipping_fee, one delivery window, one availability verdict with its
fulfillable_quantity, and the fulfillment_locations that can each alone provide
exactly that availability and window.
When an option's locations differ in what they can offer, its entry reports the best of them — best availability verdict, then fastest delivery window, then highest fulfillable quantity, then the option's configured location order — and lists only the locations sharing that best answer. The selection is deterministic.
Each product's delivery_options is availability-banded when stock was evaluated —
FULL entries first, then PARTIAL, then UNKNOWN, then NONE — with sort_by /
sort_direction applied within each band. When inventory was not evaluated, ordering is
pure sort_by / sort_direction. With the default SPEED, delivery_options[0] is the
product's fastest deliverable option whenever stock was checked — the PLP read.
(Filter on availability only if you also want to exclude PARTIAL entries.) Products
whose delivery_options is empty (no option matches) are kept, so every requested
product is represented.
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| Content-Type | application/json | Yes | Media type of the request body. |
Request body
application/jsonSchema: product-delivery-options-requestrequired- Whether the merchant's order-allocation routing rules are applied on top of the stock read. Defaults to the value of
inventory_check, so omitting it changes nothing. Set tofalsealongsideinventory_check: truefor a pure stock answer with no routing policy applied.truewithoutinventory_check: trueis rejected with a400. - Default fulfillment locations applied to every product. Reference a configured Carriyo location by
partner_location_idorpartner_location_code. Override per product underproducts[].fulfillment_locations. Required for any product that does not carry its own override: a product with no effective fulfillment location is rejected with a400.
Responses
product-delivery-options-responseAn array of product-delivery-result. Each item has the following fields:
- The delivery options for this product, one entry per option. When availability was evaluated, entries are banded
FULL→PARTIAL→UNKNOWN→NONEwithsort_by/sort_directionapplied within each band; otherwise ordered purely bysort_by/sort_direction. Always an array:[]when no option matches the product, never null and never omitted. An out-of-stock option is not dropped — it appears markedavailability: NONE.
Need the full machine-readable spec? Download the OpenAPI document →
/storefront/locationsGet eligible locations
Returns the configured Carriyo locations that can serve a customer, so you can find the nearest store or warehouse to fulfill from or offer for collection.
A location is eligible when it is active, the merchant has access to it, and it carries the
requested functions flag. How its geography is checked then depends on the function:
FULFILLMENTlocations are gated by their configured coverage. Zone coverage (fulfillment_zones) qualifies a location when its zones cover the customer's country, state, city, or area terms. Radius coverage (fulfillment_radius) qualifies it when the customer is within the radius; this needs coordinates on both sides, so a location with radius coverage but no coordinates, or a request with nocustomer.coords, is ineligible. A fulfillment location with neither zones nor radius serves everywhere.COLLECTIONlocations are not gated by zones or radius. A location qualifies on its collection flag alone; the only geographic constraint ismax_distance, which caps how far a pickup point can be from the customer.
Distance and selection order
Supply customer.coords to get a distance on each location and nearest-first selection.
The order is fixed: nearest-first when coordinates are supplied, location_code order
otherwise; locations with no computable distance select last. Use max_distance (needs
coordinates) to cap how far out to look.
Filtering and the cap
Filter by location_type (STORE or WAREHOUSE) and by functions (FULFILLMENT,
COLLECTION; defaults to [FULFILLMENT]). One call returns the complete answer, capped by
max_locations (default 10, maximum 50) — there are no pages and no way to fetch "the
rest"; receiving exactly max_locations items means more may exist, so narrow the filters
or raise the cap. page/page_size and sort_by/sort_direction are rejected with
400.
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| Content-Type | application/json | Yes | Media type of the request body. |
Request body
application/jsonSchema: eligible-locations-requestrequired- Cap on returned locations. The response is one complete, capped answer in fixed selection order (nearest-first with
customer.coords,location_codeorder otherwise) — there are no pages. Receiving exactlymax_locationsitems means more may exist; narrow the filters or raise the cap.
Responses
eligible-locations-responseAn array of eligible-location. Each item has the following fields:
Need the full machine-readable spec? Download the OpenAPI document →