> For the complete documentation index, see [llms.txt](https://docs.parcellab.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.parcellab.com/docs/convert/promise.md).

# Promise

Provide a pre-checkout delivery date to drive conversion rates and reduce customer service calls through clear delivery expectations.

## Overview

Promise lets you display accurate delivery date predictions on product pages, at checkout, and in post-purchase communications to improve conversion and customer satisfaction.

You can use parcelLab’s API and self-service Promise configuration in the App to display accurate pre-checkout delivery predictions based on your carriers and warehouses. These predictions are powered by our machine learning algorithm that accounts for distribution setup, holidays, operating hours, weather, and other operational constraints.

## Data Requirements

To use <code class="expression">space.vars.Product\_Promise</code>, the following keys need to be sent to parcelLab in tracking records for communications. This ensures the data is available to reference in your <code class="expression">space.vars.Product\_Promise</code> configuration.

<details>

<summary>Keys for v4 API (new integrations)</summary>

| Key                     | Type   | Description                                    |
| ----------------------- | ------ | ---------------------------------------------- |
| courier\_service\_level | String | Product or service level from carrier.         |
| warehouse               | String | Warehouse from which the delivery was shipped. |

</details>

<details>

<summary>Keys for v2 API (existing integrations only)</summary>

| Key                 | Type   | Description                                    |
| ------------------- | ------ | ---------------------------------------------- |
| courierServiceLevel | String | Product or service level from carrier.         |
| warehouse           | String | Warehouse from which the delivery was shipped. |

</details>

To use the checkout promise in communications, save it with the order in your system, then send it through your parcelLab order or tracking integration. The prediction request and widget do not perform this write for you.

<details>

<summary>Keys for v4 API (new integrations)</summary>

| Field                                                        | Type   | Value to send                                                                                       |
| ------------------------------------------------------------ | ------ | --------------------------------------------------------------------------------------------------- |
| `announced_delivery_date`                                    | Date   | The single ISO date shown at checkout, such as the selected method's latest date for "delivery by". |
| `announced_delivery_date_min`, `announced_delivery_date_max` | Dates  | The start and end of the range shown at checkout, if you displayed a range.                         |
| `additional_fields`                                          | Object | Custom fields. For example, `{"requestID": "gxFAiZfP"}` stores the prediction request ID.           |

In the v4 Order API, send `announced_delivery_date` and `additional_fields` inside `mutations[].tracking`. Send the range fields `announced_delivery_date_min` and `announced_delivery_date_max` at the top level of the order payload. See the [v4 Order API](/docs/developers/orders/create-orders-trackings.md) for the complete payload.

</details>

<details>

<summary>Keys for v2 API (existing integrations only)</summary>

| Tracking field            | Type   | Value to send                                                                             |
| ------------------------- | ------ | ----------------------------------------------------------------------------------------- |
| `announced_delivery_date` | Date   | The single ISO date shown at checkout.                                                    |
| `customFields`            | Object | Custom fields. For example, `{"requestID": "gxFAiZfP"}` stores the prediction request ID. |

Coordinate the custom field name with parcelLab. `requestID` is the custom key used in these examples; the API response field is `requestId` in v2 and `request_id` in v4.

</details>

For further details on how to send parcelLab the promise date for use in communications, refer to the section [Using Promise Dates in Communications from parcelLab](#using-promise-dates-in-communications-from-parcellab).

For a list of input fields required to configure <code class="expression">space.vars.Product\_Promise</code> in the <code class="expression">space.vars.Product\_App</code> (that is: Service Levels, Warehouses and Delivery Methods), refer to the Promise Configuration Template.

{% file src="/files/cdDgfj279POuCOIIInGb" %}

## Displaying <code class="expression">space.vars.Product\_Promise</code> on Your Website

The following sections describe the recommended process for integrating parcelLab <code class="expression">space.vars.Product\_Promise</code> into your online shop and using the generated promise date in your post-purchase communications.

### Call the Promise API

After publishing your <code class="expression">space.vars.Product\_Promise</code> configuration in the <code class="expression">space.vars.Product\_App</code>, you can retrieve promise dates by calling the <code class="expression">space.vars.Product\_Promise</code> API.

For details on using the <code class="expression">space.vars.Product\_Promise</code> API, please refer to our API documentation:

* [v4 API (new integrations)](/docs/developers/promise/api.md)
* [v2 API](/docs/developers/v2/promise/promise-dates.md)
* [Promise UI Plugin](https://app.gitbook.com/s/ew6OnyRUe6InzC96WnMr/promise/ui-plugin)

### From Product Page to Order

Use an estimate while the shopper browses. At checkout, use the confirmed address and the shipping method that the shopper selects. Save the date you show when the shopper places the order so that later communications use the same promise.

```mermaid
sequenceDiagram
    participant Shop as Your shop
    participant PL as parcelLab APIs
    participant Order as Your order system
    Shop->>PL: Promise request: country/ZIP or IP + fallback
    PL-->>Shop: Location, predictions, request ID
    Note over Shop: Show browsing estimate and allow correction
    Shop->>PL: Promise request: confirmed address and shipping method
    PL-->>Shop: Updated predictions and request ID
    Note over Shop: Display a date or range from one matching method
    Shop->>Order: Order placed: save displayed promise and request ID
    Order->>PL: Order/tracking write: saved announced date and request ID
    Note over PL: Use saved promise in communications and Insights
```

A response location is an estimate used to select delivery methods. It does not confirm the shopper's shipping address. A country fallback applies when the IP cannot resolve or has no matching methods. It does not guarantee a date. If no prediction is available, keep the destination editable and omit the delivery date.

### Preview the Widget

Open the [Promise UI playground](https://cdn.parcellab.com/playground/promise-ui/index.html) to compare layouts and generate an embed for your website. The playground configures the reference widget; it does not publish your account's warehouses or delivery methods. Use the App's **Publish Setup** flow for those changes.

1. Enter your Promise-enabled account ID and select a data preset. **PDP · IP (Germany fallback)** and **PDP · IP (US fallback)** estimate a location before the shopper supplies an address. Country-only and ZIP + country presets let you test known destinations.
2. Under **Data**, select **ZIP + country**, **Country only**, or **IP Fetch + fallback country**. Enter a three-letter country code. For IP Fetch, leave **IP address** empty to use your public IP, or enter an IPv4 or IPv6 address to test that address. The configured country is the fallback for IP requests.
3. Set the warehouse, carrier, and service-level filters to match the methods your shop offers. Review the **Sample request**. In public-IP mode, its IP is an example; a specified IP appears as entered.
4. Choose a presentation preset or adjust layout, date wording, cutoff, carrier display, and location controls. **Inline (PDP, cart)** uses a compact text layout. **Card** gives the estimate more space; **Badge** gives a short date summary. Hiding location controls does not change the destination used for the prediction.
5. Use **Show API response** to inspect the request and raw result for the Data controls. This panel makes a separate request. It does not read a destination that you manually changed inside the widget preview. To compare that location, enter its country and ZIP in **Data**.
6. Select **HTML** or **JavaScript** and copy the generated embed. Use the production widget script at `https://cdn.parcellab.com/js/promise-ui/v1/promise.iife.js` for your storefront. The [widget integration examples](https://app.gitbook.com/s/ew6OnyRUe6InzC96WnMr/promise/ui-plugin#recommended-usage) explain the fields and required connections.

The browser URL stores the demo controls, preset selections, embed tab, and API panel state. Copy it to share a setup. A manually specified IP or ZIP is included in that URL; the automatically fetched IP and location are not. Shopper corrections inside the preview stay in browser storage and are not part of the shared URL. Selecting a data preset or changing request fields clears those saved choices so you can test the selected inputs again.

Previewing an embed does not install it on your shop or save a promise to an order. Your integration must connect the checkout address, shipping method, and order data. The reference widget uses the v2 Promise endpoint; a custom frontend can use the v4 API.

### Best Practices for Displaying Promise

| Input                             | When to use it                                                            | Shopper experience                                                                 |
| --------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| Confirmed country and postal code | The address is known, especially at checkout.                             | Use this destination ahead of saved choices or an IP estimate.                     |
| Saved manual destination          | The shopper entered a country or postal code on an earlier page or visit. | Reuse the choice, but let the shopper change it. A new country clears the old ZIP. |
| IP address with country fallback  | No address or saved choice is available.                                  | Label the location as approximate and let the shopper correct it.                  |
| Country only                      | Only the market is known, or a country-level fallback is used.            | Show the country and an **Add ZIP** action if location controls are visible.       |

| Placement           | Recommended display                                                                                 | Why                                                                                   |
| ------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Product detail page | Earliest estimated date and order cutoff; hide carrier and location controls for a compact display. | Gives the shopper an initial estimate before an address is known.                     |
| Checkout            | Editable country and ZIP, "delivery by" date, and carrier; hide the cutoff.                         | Lets the shopper confirm the destination and see the estimate for the offered method. |

For "delivery by", display the selected method's latest date. For a range, use that method's earliest and latest dates. Changing the wording does not select a different method. At checkout, match the selected shipping option instead of choosing the first API result or the fastest method that the shopper did not select.

<figure><img src="https://1156682959-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LPf1Lv1YUuLYva6LrXQ%2Fuploads%2Fgit-blob-c1006431af88c69f478f298faf34016a217c55c0%2Fpromise-ui-pdp-minimal.png?alt=media" alt="Product page delivery estimate with earliest date and order cutoff; carrier and location controls are hidden."><figcaption><p>Compact product page estimate. Dates and cutoff depend on the response.</p></figcaption></figure>

<figure><img src="https://1156682959-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LPf1Lv1YUuLYva6LrXQ%2Fuploads%2Fgit-blob-a9eb971d758f134b29306b26d6e3dcf04d0ce9ba%2Fpromise-ui-checkout-location.png?alt=media" alt="Checkout delivery-by estimate with UPS and editable ZIP and country, marked as an approximate location."><figcaption><p>Checkout estimate with an editable destination. Supply the checkout address when it is known.</p></figcaption></figure>

### What Is Saved

| Data                                   | Where to keep it                | Lifetime and use                                                                                                                                                                  |
| -------------------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Automatic IP location                  | Temporary page state            | Use it to label an estimate. Do not copy it into the confirmed shipping address. The response does not identify whether IP lookup or country fallback supplied the location.      |
| Shopper's manual country and ZIP       | Browser storage for convenience | The reference widget saves picker changes for 30 days after the last change on the same browser and site. Visits do not extend expiry. A ZIP supplied by the page takes priority. |
| Promise shown when the order is placed | Your order system               | Save the ISO date or range, selected delivery method, confirmed destination, and prediction request ID. Send the saved values to parcelLab with the order or tracking.            |

The widget does not save IP addresses or automatic locations in browser storage. Its saved manual destination is shared by widgets on the same site, not separated by account. It cannot transfer that choice to a different site or device. If storage is unavailable, the current widget still works but cannot reuse the choice on a later visit. Host calls to `update()` do not save a manual choice; a custom API integration must implement its own destination storage.

Request a new prediction when the destination or shipping method changes and before the order is placed. The reference widget does not poll automatically or run a cutoff countdown. A saved destination is reusable input, not a saved delivery date.

### Using Promise Dates in Communications from parcelLab

Use the same promise in checkout, your order system, and post-purchase communications. The steps below also apply when the reference widget calls v2 and your order integration uses v4.

1. Request a prediction for the confirmed delivery address and the shipping option offered at checkout.
2. Check the HTTP status, `success`, and the matching entry in `prediction[]`. Choose one method and read all displayed dates from that entry. A non-null `location` alone does not mean a prediction is available.
3. When the shopper places the order, save the displayed ISO date or range, the selected method, the confirmed destination, and the response's request ID with the order. Keep the request ID from the response that supplied the displayed date.
4. Send the saved values through your authenticated order or tracking integration. Keep the original checkout promise if you calculate a new estimate later. Configure your communications to use the announced date fields and your agreed custom request-ID field.

#### Fields to Read and Write

In this table, `selected` means the one entry from `prediction[]` that matches the shipping option. These are field paths, not literal request values.

| Value                               | Read from v4 prediction                                        | Read from v2 prediction                                      | Save or send                                                                                                                     |
| ----------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| Approximate destination             | `location.country`, `location.zip`                             | `location.country`, `location.zip`                           | Temporary UI state. A ZIP of `null` or `"0"` means no postal code. Use the confirmed address for the order.                      |
| "Delivery by" date                  | `selected.prediction.latest_date`                              | `selected.prediction.latest`                                 | Save this ISO date; send it as `announced_delivery_date`.                                                                        |
| Date range                          | `selected.prediction.earliest_date` and `latest_date`          | `selected.prediction.earliest` and `latest`                  | Save both ISO dates. In v4, send them as top-level order fields `announced_delivery_date_min` and `announced_delivery_date_max`. |
| Single earliest or most likely date | `selected.prediction.earliest_date` or `most_likely_date`      | `selected.prediction.earliest` or `mostLikely`               | Save the date actually displayed; send it as `announced_delivery_date`.                                                          |
| Prediction request ID               | Top-level `request_id`                                         | Top-level `requestId`                                        | Save with the order. Send in v4 `tracking.additional_fields.requestID` or v2 `customFields.requestID`, if configured.            |
| Selected method                     | `selected.id`, `warehouse`, `courier`, `courier_service_level` | `selected.id`, `warehouse`, `courier`, `courierServiceLevel` | Keep the selected option with the order. Use the matching configured warehouse, carrier, and service value for the tracking.     |

Save machine-readable dates such as `2026-10-16`. Localized text such as "Friday, October 16" is for display. A cutoff is the time remaining to order for that estimate; it is not the announced delivery date.

For example, if checkout displayed "Delivery by October 16, 2026" from a response with request ID `gxFAiZfP`, add these fields to the tracking object in your v4 `add_tracking` mutation:

```json
{
  "announced_delivery_date": "2026-10-16",
  "additional_fields": {
    "requestID": "gxFAiZfP"
  }
}
```

This is a fragment of `mutations[].tracking`, not a complete Order API request. Include your normal order and tracking identifiers. Use `customFields` instead of `additional_fields` for a v2 tracking. The custom key `requestID` is independent of whether you read `request_id` from v4 or `requestId` from v2.

If checkout displayed a range, add these fields to the top level of the v4 order payload, alongside `account` and `order_number`:

```json
{
  "announced_delivery_date_min": "2026-10-14",
  "announced_delivery_date_max": "2026-10-16"
}
```

The reference widget does not write these fields to your order system or create a parcelLab tracking. Its public API does not expose the selected prediction or the response request ID. For order persistence, use a custom API integration or extend the reference implementation to retain the response and selected method that produced the displayed promise. Do not read a new prediction later and treat it as the original checkout promise.

{% hint style="info" %}
For a separate estimate based on a known dispatch time, use `now_override` and `dispatch_now=true` in v4, or `_now` and `dispatchNow=true` in v2. Keep the saved checkout promise for comparison.
{% endhint %}

The reporting on <code class="expression">space.vars.Product\_Promise</code> fulfillment can be viewed in the Insights section of the <code class="expression">space.vars.Product\_Promise</code> module in the <code class="expression">space.vars.Product\_App</code>.

<figure><img src="https://1156682959-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LPf1Lv1YUuLYva6LrXQ%2Fuploads%2FSP3xk4tzLUzVhvcwmd1I%2FPromiseInsights.png?alt=media&amp;token=3310317f-5ec0-43e2-83f0-d0e5abd8923d" alt="Promise Analytics report within the Promise module"><figcaption></figcaption></figure>

For further information on Promise fulfillment and performance, see our Promise analytics documentation.

{% content-ref url="/pages/XRwZrgSwrD84r5rXwUpo" %}
[Promise Insights](/docs/convert/promise-insights.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.parcellab.com/docs/convert/promise.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
