---
schema_version: "1"
id: 0f94d4962d91d89967326c35a72052a8f46f8668ffe35dfd32d23268e5d0d58c
title: Shopper Delivery Estimates
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/commerce-cloud/commerce-api/references/generated-api-specs/shopper-delivery-estimates.md
canonical_url: https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-delivery-estimates
source_site: developer.salesforce.com
content_type: documentation
content_hash: fad74256c2010edd01c22bfb19fc5ea488032d1643a227285ce5240880338bb0
products:
  - B2C Commerce API
  - Salesforce APIs
---
Shopper Delivery Estimates

# Shopper Delivery Estimates

[Download API specification](https://developer.salesforce.com/static/commercecloud/commerce-api/shopper-delivery-estimates/shopper-delivery-estimates-oas-v1-public.yaml)

## API Overview

Use the Shopper Delivery Estimates API to retrieve carrier-calculated delivery date ranges for a single product at a destination postal code. The API is intended for product detail pages (PDP) where shoppers want to know when an item will arrive before adding it to a basket.

For the requested product, the platform enumerates the site's applicable shipping methods. Estimates are returned only when the `sfcc.app.shipping.estimate` hook is bound to a provider via an installed Commerce App; if no provider is bound, the platform returns no estimates.

The Shopper Delivery Estimates API is currently uncached. The URL is deterministic in `productIds`, `postalCode`, and `countryCode`, and will utilize a cache layer in the future.

### Authentication & Authorization

The Shopper Delivery Estimates API requires a shopper access token.

For details on how to request an access token, see [Get a Shopper Token from SLAS](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas.html).

You must include `sfcc.shopper-delivery-estimates` and `sfcc.shopper-standard` in the client ID used to generate the token. For a full list of permissions, see the [Authorization Scopes Catalog.](https://developer.salesforce.com/docs/commerce/commerce-api/guide/auth-z-scope-catalog.html)

### Customization

#### Hooks

For details on working with hooks, see [Extensibility with Hooks.](https://developer.salesforce.com/docs/commerce/commerce-api/guide/extensibility_via_hooks.html)

### Response Details

#### Personalization

Responses from this API are not personalized via the Shopper Context API.

#### Caching

Responses from this API are not cached. The endpoint is currently uncached even though request URLs are deterministic for `productIds`, `postalCode`, and `countryCode`; a cache layer is planned for a future release. For details, see [Server-Side Web-Tier Caching.](https://developer.salesforce.com/docs/commerce/commerce-api/guide/server-side-web-tier-caching.html)

#### Timeouts

Shopper API requests must respond within 10 seconds, including any hook execution. If a response exceeds this threshold, an HTTP 504 status code is returned. For details, see [Timeouts and Limits.](https://developer.salesforce.com/docs/commerce/commerce-api/guide/timeouts-limits.html)

#### Error Handling

Error responses follow the [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) problem detail format. To trace errors, include a `correlation-id` header in your request — the response returns it as `x-correlation-id`. For details, see [HTTP Status Codes and Errors.](https://developer.salesforce.com/docs/commerce/commerce-api/guide/error-response-codes.html)

### Use Cases

#### Show "Arrives by" on a Product Detail Page

Use this API on the PDP after a shopper enters postal code and country. The response provides delivery windows by applicable shipping method so you can display messaging such as "Arrives Fri, Oct 4."

```bash
curl -X GET \
  "https://{shortCode}.api.commercecloud.salesforce.com/product/shopper-delivery-estimates/v1/organizations/{organizationId}/delivery-estimates?siteId={siteId}&productIds={productId}&postalCode=94105&countryCode=US" \
  -H "Authorization: Bearer {shopper_access_token}" \
  -H "Content-Type: application/json" \
  -H "correlation-id: pdp-delivery-estimate-001"
```

#### Choose Which Shipping Methods to Highlight

The response includes one entry per applicable shipping method for each product. If a method is deliverable, use the `deliveryWindow`; if it is not deliverable, use `nonDeliverableReason` to suppress or de-prioritize that method in your UI.

#### Hide the Estimate Module When No Estimates Are Available

If `productDeliveryEstimates` is empty, no estimates are available for requested products (for example, no applicable shipping methods or no provider response). In that case, hide the delivery estimate component to avoid showing incomplete or misleading delivery messaging.

### Best Practices

*   Keep calls scoped to PDP interactions, since the endpoint is currently uncached.
*   Respect the current one-product constraint (`productIds` currently supports one product per request) and avoid batching assumptions until multi-product support is released.
*   Gracefully handle partial availability by rendering only methods with delivery windows and clearly handling non-deliverable methods.
*   Ensure the `sfcc.app.shipping.estimate` hook is bound to a provider via an installed Commerce App — without a bound provider, no estimates are returned. Validate hook performance and timeout behavior to stay within the 10-second Shopper API limit.
*   Always include a `correlation-id` header for easier production troubleshooting.

### Related APIs

This API is commonly used with SLAS token APIs for shopper authentication and Shopper Products APIs for PDP data retrieval.

**Version:** 1.2.2

## Servers

*   `https://{shortCode}.api.commercecloud.salesforce.com/product/shopper-delivery-estimates/v1`
    *   `shortCode (default shortCode)`

## Security

*   `ShopperToken` (oauth2) ShopperToken authentication follows the authorization code grant flow, as defined by the OAuth 2.1 standard. Depending on the type of OAuth client (public or private), this authorization flow has further requirements. For a detailed description of the authorization flow, see the [SLAS overview](https://developer.salesforce.com/docs/commerce/commerce-api/references?meta=shopper-login:Summary). A shopper token allows you to access the Shopper API endpoints of both OCAPI and the B2C Commerce API. These endpoints can be used to build headless storefronts and other applications. The `ShopperToken` security scheme is a parent of other security schemes, such as `ShopperTokenTsob`. A Shopper API endpoint can require a specific child scheme (`ShopperTokenTsob`, for example) that cannot be accessed with a regular shopper token.
    *   OAuth flow clientCredentials (tokenUrl: https://{shortCode}.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/{organizationId}/oauth2/token)
    *   Scope sfcc.shopper-delivery-estimates: scope granting read-access to shopper delivery estimates endpoints
    *   Scope sfcc.shopper-standard: scope granting read-access to standard shopper endpoints
    *   OAuth flow authorizationCode (authorizationUrl: https://{shortCode}.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/{organizationId}/oauth2/authorize, tokenUrl: https://{shortCode}.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/{organizationId}/oauth2/token)
    *   Scope sfcc.shopper-delivery-estimates: scope granting read-access to shopper delivery estimates endpoints
    *   Scope sfcc.shopper-standard: scope granting read-access to standard shopper endpoints
*   `ShopperClientContextToken` (oauth2) ShopperClientContextToken is a separate security scheme used to track and validate client context information. It is valid for Guest shoppers flows only using SLAS private clients. For registered shoppers, use existing ShopperToken flows. For authentication details, see the [SLAS overview](https://developer.salesforce.com/docs/commerce/commerce-api/references?meta=shopper-login:Summary). This token allows access to Shopper API endpoints for guest shoppers only.
    *   OAuth flow clientCredentials (tokenUrl: https://{shortCode}.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/{organizationId}/oauth2/token?hint=client\_context)
    *   Scope sfcc.shopper-delivery-estimates: scope granting read-access to shopper delivery estimates endpoints
    *   Scope sfcc.shopper-standard: scope granting read-access to standard shopper endpoints

## Operations

### GET Returns delivery date estimates for the requested product.

`GET /organizations/{organizationId}/delivery-estimates`

Operation ID: `getDeliveryEstimates`. Security: ShopperToken (sfcc.shopper-delivery-estimates, sfcc.shopper-standard); ShopperClientContextToken (sfcc.shopper-delivery-estimates, sfcc.shopper-standard).

Returns delivery date estimates for the requested products at a destination postal code. Currently limited to one product per request. For each requested product, the platform enumerates all applicable site-level shipping methods. Estimates are returned only when the `sfcc.app.shipping.estimate` Commerce Apps hook is bound to a provider. If no provider is bound, the platform returns no estimates. Each entry in the response corresponds to one requested product, and contains one entry per applicable shipping method. Methods for which the provider returned an estimate carry a `deliveryWindow`. Methods for which the provider could not return an estimate include a `nonDeliverableReason`. An empty `productDeliveryEstimates` array means the platform has no estimates for any of the requested products, for example, no applicable shipping methods or the provider returned no results. In this case, clients should hide the delivery estimation block.

#### Parameters

*   `organizationId` (path, OrganizationId, required) An identifier for the Salesforce Commerce Cloud organization the request is being made by. It consists of a prefix 'f\_ecom\_' followed by a 4-character [realm identifier](https://developer.salesforce.com/docs/commerce/commerce-api/guide/base-url.html#realm-id) and a 3-character [instance type identifier](https://developer.salesforce.com/docs/commerce/commerce-api/guide/base-url.html#instance-id).
    
    _Example_
    
    ```
    f_ecom_zzxy_prd
    ```
    
*   `productIds` (query, array of ProductId, required, style: form, explode: false) The IDs of the products for which to retrieve delivery estimates. Each product must be online and site-assigned. Currently limited to one ID per request; multi-product support is reserved for a future release.  
    Minimum items: 1. Maximum items: 1.
    
    _Example_
    
    ```
    apple-ipod-shuffle
    ```
    
    _Example_
    
    ```
    [
      "apple-ipod-shuffle"
    ]
    ```
    
*   `postalCode` (query, string, required) The destination postal code for which to compute delivery estimates. Format depends on the destination country (for example, a 5-digit ZIP for US, a 6-character alphanumeric code for CA).  
    Minimum length: 1. Maximum length: 20. Example: `10001`.
    
    _Example_
    
    ```
    10001
    ```
    
*   `countryCode` (query, CountryCode, required) The destination country as an ISO 3166-1 alpha-2 country code (for example, `US`, `CA`, `GB`). Required for unambiguous resolution of the destination — postal codes are not globally unique.
    
    _Example_
    
    ```
    US
    ```
    
*   `siteId` (query, SiteId, required) The identifier of the site that a request is being made in the context of. Attributes might have site specific values, and some objects may only be assigned to specific sites.
    
    _Example: SiteId_
    
    ```
    RefArch
    ```
    
*   `sfdc_usid` (header, string (uuid)) A unique shopper identifier (USID) for tracking client context. Used with endpoints secured with ShopperClientContextToken. This header is required for all endpoints secured with ShopperClientContextToken.  
    Example: `550e8400-e29b-41d4-a716-446655440000`.
*   `personalized` (query, string) Controls whether personalization is applied to the response. When set to `none`, the server skips applying personalization to the response.  
    Allowed values: `none`. Example: `none`.
*   `sfdc_shopper_context` (header, string) Shopper context information (for example clientIP, sourceCode, and customQualifiers) passed in from a trusted backend application.

#### Responses

*   **200** Success
    
    Media type: `application/json`. Schema: `DeliveryEstimatesResult`.
    
    _Example: GetDeliveryEstimatesResponseExample_ Happy path — one product with two shipping options, both deliverable.
    
    ```
    {
      "productDeliveryEstimates": [
        {
          "productId": "apple-ipod-shuffle",
          "destination": {
            "postalCode": "10001",
            "countryCode": "US"
          },
          "shippingOptions": [
            {
              "shippingMethodId": "GroundShipping",
              "name": "Ground",
              "description": "Standard ground shipping",
              "carrier": "UPS",
              "price": 5.99,
              "currency": "USD",
              "deliveryWindow": {
                "startAt": "2026-04-30T14:00:00Z",
                "endAt": "2026-04-30T18:00:00Z"
              },
              "orderCutoffAt": "2026-04-27T14:00:00Z"
            },
            {
              "shippingMethodId": "TwoDayShipping",
              "name": "Two-Day",
              "description": "Expedited air shipping",
              "carrier": "UPS",
              "price": 12.99,
              "currency": "USD",
              "deliveryWindow": {
                "startAt": "2026-04-28T09:00:00Z",
                "endAt": "2026-04-28T17:00:00Z"
              },
              "orderCutoffAt": "2026-04-26T18:00:00Z"
            }
          ]
        }
      ]
    }
    ```
    
    _Example: GetDeliveryEstimatesPartialResponseExample_ One shipping option is deliverable, another is not. Methods that cannot deliver for a particular reason are kept in the response with \`nonDeliverableReason\` populated.
    
    ```
    {
      "productDeliveryEstimates": [
        {
          "productId": "apple-ipod-shuffle",
          "destination": {
            "postalCode": "10001",
            "countryCode": "US"
          },
          "shippingOptions": [
            {
              "shippingMethodId": "GroundShipping",
              "name": "Ground",
              "description": "Standard ground shipping",
              "carrier": "UPS",
              "price": 5.99,
              "currency": "USD",
              "deliveryWindow": {
                "startAt": "2026-04-30T14:00:00Z",
                "endAt": "2026-04-30T18:00:00Z"
              },
              "orderCutoffAt": "2026-04-27T14:00:00Z"
            },
            {
              "shippingMethodId": "OvernightShipping",
              "name": "Overnight",
              "description": "Priority overnight shipping",
              "carrier": "UPS",
              "nonDeliverableReason": "INSUFFICIENT_INVENTORY"
            }
          ]
        }
      ]
    }
    ```
    
    _Example: GetDeliveryEstimatesEmptyResponseExample_ No estimates available — for example, when the provider returned an empty result.
    
    ```
    {
      "productDeliveryEstimates": []
    }
    ```
    
*   **400** Bad Request
    
    Media type: `application/problem+json`. Schema: `ErrorResponse`.
    
    _Example: GetDeliveryEstimatesBadRequestResponseExample_ A required parameter is missing or has an invalid value.
    
    ```
    {
      "title": "Bad Request",
      "type": "https://api.commercecloud.salesforce.com/documentation/error/v1/errors/validation",
      "detail": "The 'postalCode' parameter is required."
    }
    ```
    
*   **401** Your access token is invalid or expired and can’t be used to identify a user.
    
    Media type: `application/problem+json`. Schema: `ErrorResponse`.
    
    _Example: UnauthorizedExample_
    
    ```
    {
      "type": "https://api.commercecloud.salesforce.com/documentation/error/v1/errors/unauthorized",
      "title": "Unauthorized",
      "detail": "Unauthorized request"
    }
    ```
    
*   **404** Not Found
    
    Media type: `application/problem+json`. Schema: `ErrorResponse`.
    
    _Example: GetDeliveryEstimatesProductNotFoundResponseExample_ The supplied \`productId\` does not resolve to an online, site-assigned product.
    
    ```
    {
      "title": "Product Not Found",
      "type": "https://api.commercecloud.salesforce.com/documentation/error/v1/errors/product-not-found",
      "detail": "No product with ID 'apple-ipod-shuffle' for site 'SiteGenesis' could be found.",
      "productId": "apple-ipod-shuffle",
      "siteId": "SiteGenesis"
    }
    ```
    

## Schemas

### OrganizationId

An identifier for the Salesforce Commerce Cloud organization the request is being made by. It consists of a prefix 'f\_ecom\_' followed by a 4-character [realm identifier](https://developer.salesforce.com/docs/commerce/commerce-api/guide/base-url.html#realm-id) and a 3-character [instance type identifier](https://developer.salesforce.com/docs/commerce/commerce-api/guide/base-url.html#instance-id).

Type: `string`.

Pattern: ^f\_ecom\_\[a-z\]{4}\_(prd|stg|dev|s\[0-9\]{2}|\[0-9\]{3})$. Example: `f_ecom_zzxy_prd`.

### ProductId

The id (SKU) of the product.

Type: `string`.

Minimum length: 1. Maximum length: 100. Example: `apple-ipod-classic`.

### CountryCode

A two letter uppercase country code conforming to the [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) alpha-2 standard.

Type: `string`.

Pattern: ^\[A-Z\]\[A-Z\]$. Example: `US`.

### SiteId

The identifier of the site that a request is being made in the context of. Attributes might have site specific values, and some objects may only be assigned to specific sites

Type: `string`.

Minimum length: 1. Maximum length: 32. Example: `RefArch`.

### DeliveryEstimatesResult

Result document containing per-product delivery estimates.

*   `productDeliveryEstimates` (_array of ProductDeliveryEstimate_, required) The array of per-product delivery estimate entries, one per requested product that has estimates. The array is empty when the platform has no estimates for any of the requested products.

### ErrorResponse

*   `title` (_string_, required) A short, human-readable summary of the problem type. It will not change from occurrence to occurrence of the problem, except for purposes of localization  
    Maximum length: 256. Example: `You do not have enough credit`.
*   `type` (_string_, required) A URI reference \[RFC3986\] that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type (e.g., using HTML \[W3C.REC-html5-20141028\]). When this member is not present, its value is assumed to be "about:blank". It accepts relative URIs; this means that they must be resolved relative to the document's base URI, as per \[RFC3986\], Section 5.  
    Maximum length: 2048. Example: `NotEnoughMoney`.
*   `detail` (_string_, required) A human-readable explanation specific to this occurrence of the problem.  
    Example: `Your current balance is 30, but that costs 50`.
*   `instance` (_string_) A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced. It accepts relative URIs; this means that they must be resolved relative to the document's base URI, as per \[RFC3986\], Section 5.  
    Maximum length: 2048. Example: `/account/12345/msgs/abc`.

### ProductDeliveryEstimate

Delivery estimates for one product at a destination, broken down by applicable shipping method.

*   `productId` (_ProductId_, required)
*   `destination` (_Destination_, required)
*   `shippingOptions` (_array of ShippingOption_, required) The array of shipping method estimates for the product at the destination. Each entry corresponds to one applicable shipping method.

### Destination

The normalized destination used for estimation. Echoes the values supplied on the request.

*   `postalCode` (_string_, required) The destination postal code.  
    Minimum length: 1. Maximum length: 20. Example: `10001`.
*   `countryCode` (_object_, required) The destination country as an ISO 3166-1 alpha-2 code.
    
    Includes all fields of `CountryCode`.
    

### ShippingOption

A delivery estimate for one applicable shipping method. When the provider answered with a delivery window, `deliveryWindow` is populated and `nonDeliverableReason` is omitted. When the provider answered "cannot deliver via this method", `deliveryWindow` is omitted and `nonDeliverableReason` is populated.

*   `shippingMethodId` (_string_, required) The identifier of the shipping method (matches the B2C Commerce `ShippingMethod.ID`).  
    Minimum length: 1. Maximum length: 256. Example: `GroundShipping`.
*   `name` (_string_) The localized name of the shipping method.  
    Minimum length: 1. Maximum length: 256. Example: `Ground`.
*   `description` (_string_) The localized description of the shipping method.  
    Minimum length: 1. Maximum length: 4000. Example: `Standard ground shipping`.
*   `carrier` (_string_) The carrier the provider resolved for this shipping method (for example, `UPS`, `FedEx`, `USPS`). May be omitted when the provider cannot or does not identify a single carrier.  
    Minimum length: 1. Maximum length: 256. Example: `UPS`.
*   `price` (_number (double)_) The estimated shipping cost for this shipping method, in the currency given by `currency`. May be omitted when the provider cannot or does not return a price.  
    Minimum: 0. Example: `5.99`.
*   `currency` (_object_) The ISO 4217 currency code for `price`. Defaults to the site's default currency. Omitted when `price` is omitted.
    
    Includes all fields of `CurrencyCode`.
    
*   `deliveryWindow` (_object_) The estimated delivery window for this shipping method. Omitted when `nonDeliverableReason` is set.
    
    Includes all fields of `DeliveryWindow`.
    
*   `orderCutoffAt` (_string (date-time)_) The latest timestamp by which an order must be placed for the `deliveryWindow` to apply. Clients compare this to the current time to decide whether the estimate is still valid. Omitted when not applicable. Sub-day RFC 3339 precision.  
    Example: `2026-04-27T14:00:00Z`.
*   `nonDeliverableReason` (_string_) A SCREAMING\_SNAKE\_CASE code identifying why the provider could not deliver via this shipping method. This is not localized and not intended to be shown directly to shoppers. This field may be omitted when the provider cannot or does not identify a single reason. Provider implementations may emit additional codes. Omitted when `deliveryWindow` is set.  
    Minimum length: 1. Maximum length: 256. Example: `INSUFFICIENT_INVENTORY`.

### CurrencyCode

A three letter uppercase currency code conforming to the [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) standard, or the string `N/A` indicating that a currency is not applicable.

Type: `string`.

Pattern: ^(\[A-Z\]\[A-Z\]\[A-Z\]|N/A)$. Example: `USD`.

### DeliveryWindow

A time window during which the delivery is expected. Both endpoints are sub-day RFC 3339 timestamps passed through unmodified from the underlying provider.

*   `startAt` (_string (date-time)_, required) The earliest expected delivery timestamp (inclusive).  
    Example: `2026-04-30T14:00:00Z`.
*   `endAt` (_string (date-time)_, required) The latest expected delivery timestamp (inclusive).  
    Example: `2026-04-30T18:00:00Z`.