# B. Rate-Shop Integrators

If you already ship through a multi-carrier rate-shop or TMS platform — Shipium, 2Ship, ClickPost, e2open, Machool, ZectorPro, Descartes, EasyPost, OneShip, Techdinamics, and similar — Envoi is added as **one more carrier inside that platform**, not as a new bespoke integration. The platform calls the same generic Envoi public API that direct-API retailers use; there is no Envoi-side adapter per integrator. Typical lift is **1–2 weeks**, and in most cases the integrator platform, not your team, does the technical work.

## How it works

The critical architectural fact: **Envoi keeps no integrator-specific adapter code.** Every supported platform integrates from *its* side against the generic public API, using a retailer-issued API key in the `Access-Token` header:

| Rate-shop concept | Envoi API call |
|---|---|
| Rate shop / carrier selection | [`POST /public/service-areas/:country/validate`](../api/service-areas/validate.md) with `fulfillmentLocationName` and `sendRate: true` — returns serviceability, rate, taxes, and estimated delivery date |
| Label purchase / shipment creation | [`POST /public/orders`](../api/orders/create.md) — the label (PDF URL or ZPL string) is returned **in the response**; there is no separate label call |
| Tracking | [Webhooks](../webhooks/overview.md) pushed to the platform's endpoint, **or** the platform polls [`GET /public/orders/<trackingCode>`](../api/orders/get-update-cancel.md) for the `packageJourney` |
| Cancel / void | [`DELETE /public/orders/<id or trackingCode>`](../api/orders/get-update-cancel.md) |

```text
+-----------+        +---------------------------+        +---------------------+
| Retailer  |        |  Rate-shop / TMS platform |        |      Envoi API      |
| OMS / WMS | -----> |  (Shipium, 2Ship,         | -----> |  api.yourenvoi.com  |
|           | order  |   ClickPost, ...)         |  POST  |                     |
+-----------+        |                           | /public/orders              |
                     |  1. validate (rate shop)  | <----- |  order + label      |
                     |  2. create order (label)  |        |                     |
                     |  3. webhooks or polling   | <----- |  tracking events    |
                     +---------------------------+        +---------------------+
```

Because the surface is the generic API, everything in the [Direct API pathway](direct-api.md) applies — this page covers only what differs.

## Integrator-side setup checklist

What you (or Envoi) hand to the platform team so they can configure Envoi as a carrier:

- **API key** — issued per retailer, sent in the `Access-Token` header. Staging and production keys are separate; see [Authentication](../getting-started/authentication.md).
- **Base URLs** — staging `https://api.staging.yourenvoi.com`, production `https://api.yourenvoi.com`.
- **Fulfillment location names** — the exact `childUserName` / `fulfillmentLocationName` values for each shipping origin (e.g. `MapleMain-GTA-1`). The rate-shop call requires a known fulfillment location name; order creation takes `fulfillmentLocationId` (the numeric id), or the name as the legacy `childUserName`. Retrieve the live set via [`GET /public/service-areas/:id/fulfillment-locations`](../api/service-areas/lookup.md).
- **Service codes** — `ENVOI_SAME_DAY` and `ENVOI_NEXT_DAY`. These appear as `serviceCode` on tracking and webhook events; map them to the platform's service-level taxonomy so the right promise shows downstream.
- **Label format** — PDF vs ZPL, agreed per retailer and configured by Envoi.
- **Tracking strategy** — webhook endpoint + HMAC secret if the platform receives pushes, or confirmation that it will poll `GET /public/orders/<trackingCode>`.
- **Field-mapping notes** — units (kg/lb, cm/in) agreed per implementation; `packages[]` array for multi-package shipments (see [Multi-Package Orders](../api/multi-package.md)).

## Onboarding differences vs. direct API

- **The platform usually does the build.** Most of these platforms have shipped Envoi before; your work is often limited to enabling the carrier, entering credentials, and mapping services. This is why the timeline is 1–2 weeks instead of 2–4.
- **Envoi's work is configuration, not code**: your Envoi contact creates fulfillment locations, sets cutoffs and pickup times, chooses the label format, and (if pushing) registers the platform's webhook endpoint and HMAC secret.
- **Testing runs through the platform's staging tools** against Envoi staging. Use the [simulate endpoint](../api/tracking/simulate.md) to generate journeys, and mock webhooks to validate the platform's event mapping.
- **Billing sometimes runs through the platform** (e.g. OneShip) — confirm the commercial path during kickoff, since it changes who reconciles invoices.

## Known-working platforms

All of these are live or have completed integrations against the generic public API:

| Platform | Notes |
|---|---|
| Shipium | Validate + create-order + label flow |
| 2Ship | Some integrations also call the validate endpoint directly |
| ClickPost | Reference implementation for the `packages[]` MPS object |
| e2open | Uses validate + order creation |
| Machool | Handles tracking via webhooks |
| ZectorPro | Custom consumer of the generic API — the "variant" lives on the platform side |
| Descartes | Order creation + validate |
| EasyPost | Validate + order creation with tracking back |
| OneShip | Poll-based tracking via `GET /public/orders/<trackingCode>`; billing can run through the platform |
| Techdinamics | Order creation + validate |

Using a platform not on this list? It almost certainly still works — the requirement is simply that the platform can call a REST API with a key header. Point its carrier team at these docs and the [Postman collection](../tools/postman.md).

## Integration steps

1. Kickoff: identify the platform, the fulfillment locations, and who owns the platform-side configuration (retailer vs. platform vendor).
2. Envoi issues a **staging** API key and creates staging fulfillment locations; you hand the setup checklist above to the platform.
3. Platform configures Envoi as a carrier: validate call for rate shop, create-order for label purchase, tracking via webhooks or polling.
4. Test on staging: rate-shop responses (including after-cutoff behavior), order creation, label rendering in the platform's print flow, cancellation, and tracking-event mapping using [simulate](../api/tracking/simulate.md).
5. Envoi mirrors the configuration in production and issues a production key.
6. Go live at low volume with both teams watching the first day's pickups.

## Go-live checklist

1. Production API key entered in the platform's production carrier config (not the staging key).
2. Every shipping origin mapped to its exact production fulfillment location name.
3. Service codes `ENVOI_SAME_DAY` / `ENVOI_NEXT_DAY` mapped to the platform's service levels and downstream customer messaging.
4. Label prints verified from the platform's production print flow (barcode scan test at the warehouse).
5. Tracking verified end to end: webhook subscription active (HMAC verified) or polling schedule confirmed.
6. Tracking-number mapping confirmed — which code the platform stores and which one customer notifications link to.
7. Cutoff times reviewed against warehouse pick/pack SLAs so rate-shop wins are actually fulfillable.

## Gotchas

- **Tracking-code mapping is the #1 field bug.** The create response contains both `envoiTrackingCode` (GUID — drives `https://app.yourenvoi.com/tracking/<envoiTrackingCode>`) and `trackingCode` (retailer-prefixed, e.g. `ENV-3SR8289Z4Y84T984`; Envoi generates it if the platform does not supply one). Platforms sometimes store one and link the other — verify which field populates the platform's "tracking number" and "tracking URL" before UAT signoff.
- **`childUserName` naming must match exactly.** It is a string key, typically `<retailer>-<service-area>-<store#>` (some platforms use `<brand>-<store-number>` for ship-from-store). A typo returns a serviceability failure, not a helpful error. Treat the list as config, not free text.
- **Cutoffs affect rate responses.** The validate endpoint's estimated delivery date reflects the fulfillment location's cutoff — a rate quoted at 16:45 against a 16:30 cutoff is a *next-day* promise. Make sure the platform surfaces `estimatedDeliveryDate` rather than assuming same-day.
- **No idempotency key.** If the platform retries a timed-out create, duplicates are possible. Prefer platforms' "check before retry" behavior, keyed on your order `number`.
- **Polling platforms lag pushes.** If the platform polls (e.g. OneShip), out-for-delivery and delivered events reach customers on the polling interval. If that matters, add a retailer-side [webhook subscription](../webhooks/overview.md) in parallel.
