> ## Documentation Index
> Fetch the complete documentation index at: https://docs.goshippo.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Shippo is a multi-carrier shipping API. For agent integrations that execute shipping operations (rates, labels, tracking, address validation, customs), connect the hosted Shippo MCP server at https://mcp.shippo.com (per-user OAuth; setup at /guides/mcp-server). To search and read this documentation from an agent, a docs search MCP is available at https://docs.goshippo.com/mcp. Shipping workflow knowledge (agent skills and a knowledge pack) is published at https://github.com/goshippo/ai. For REST integrations start at /guides/api-quickstart; test mode uses shippo_test_ API keys.

# Estimate

## Using the Estimate API

If you are interested in using Shippo's Estimate API, or have any questions about [pricing](https://goshippo.com/pricing/api), please [contact an expert](https://goshippo.com/contact/sales).

One call to `POST https://api.goshippo.com/v2/estimates` returns predicted delivery dates across carriers and service levels, before a label is purchased. Predictions come back sorted fastest first.

Authenticate with `Authorization: ShippoToken <API_TOKEN>`.

## Required parameters

Every request needs all of the following fields. Leave one out and you get a 422 telling you which field is missing.

| Parameter                                        | Type   | Notes                             |
| :----------------------------------------------- | :----- | :-------------------------------- |
| `origin.zip`                                     | string | US ZIP, 5 numeric characters      |
| `destination.zip`                                | string | US ZIP, 5 numeric characters      |
| `parcel.length`, `parcel.width`, `parcel.height` | number | In your chosen `distance_unit`    |
| `parcel.distance_unit`                           | enum   | `in`, `cm`, `mm`, `m`, `ft`, `yd` |
| `parcel.weight`                                  | number | In your chosen `mass_unit`        |
| `parcel.mass_unit`                               | enum   | `g`, `kg`, `lb`, `oz`             |
| `planned_ship_date`                              | string | ISO 8601, timezone-aware          |

Two things trip people up more than anything else:

* **`distance_unit` and `mass_unit` are required, not inferred.** Sending dimensions and weight without their units is the single most common 422.
* **`planned_ship_date` must carry a timezone.** Both `2026-08-27T17:00:00Z` and `2026-08-27T13:00:00-04:00` work. A naive datetime like `2026-08-27T17:00:00` returns a 422, and so does a date on its own.

You also can't ship in the past, though the rule is friendlier than it sounds. We compare the date, not the timestamp, and we do it in whatever timezone you sent. So at 11am you can still pass 9am today. You just can't pass yesterday.

## Optional parameters

| Parameter              | Type               | What it does                                                                                                                            |
| :--------------------- | :----------------- | :-------------------------------------------------------------------------------------------------------------------------------------- |
| `servicelevel_tokens`  | array of strings   | Restricts the response to the service level tokens you list. Inclusion only, so there's no way to exclude a carrier or a service level. |
| `latest_delivery_date` | string, YYYY-MM-DD | Drops any prediction arriving after this date. See the [timezone section](#timezone-of-the-estimates) for additional details.           |
| `confidence_level`     | enum               | `TYPICAL`, `DEFAULT`, or `HIGH`. See below.                                                                                             |

Behavior worth knowing before you build against it:

* Unrecognized tokens in `servicelevel_tokens` are skipped, and each one comes back in the response's `messages` array with the code `servicelevel_unsupported`. If every token you send is unrecognized, you get a 422 instead.
* If `latest_delivery_date` filters out everything, you get a 200 with an empty `predictions` array. That's a success, not an error.
* **We return every supported service level regardless of which carrier accounts you have connected.** We don't have your carrier account context in this call, so filtering to what you actually ship is your side of the job.

## Picking parameters for your use case

| What you're building                                                 | Confidence | Ship date to send                 | Filters to use                                           |
| :------------------------------------------------------------------- | :--------- | :-------------------------------- | :------------------------------------------------------- |
| Delivery promise at checkout or on a product page                    | `DEFAULT`  | Your next carrier handoff cutoff  | None, then filter the response to the services you offer |
| Choosing a service in the warehouse                                  | `TYPICAL`  | Today's handoff time              | `servicelevel_tokens` for your contracted services       |
| Meeting a hard deadline (perishables, regulated goods, dated events) | `HIGH`     | Your next handoff cutoff          | `latest_delivery_date` set to the deadline               |
| Answering "when will it arrive" for a customer                       | `DEFAULT`  | The date the order actually ships | `servicelevel_tokens` for the one service being used     |
| Showing options to sellers on a platform                             | `DEFAULT`  | Seller's handoff cutoff           | Filter the response per seller's connected carriers      |

**We don't model carrier cutoff times, so `planned_ship_date` is where you encode yours.** Pass the moment the package realistically enters the carrier network. If an order lands after your daily handoff, bump the date to the next business day and call again.

We don’t currently support Saturday-delivery upgrades for service levels that do support it.

## Timezone of the estimates

We return `estimated_delivery_date_utc` in UTC. Always. Convert it before you show it to anyone.

This matters more than it sounds. `2026-03-24T03:00:00Z` is March 24 in UTC but March 23 in Los Angeles. If you slice the date off the UTC string and display it, you'll be a day off for a meaningful share of your West Coast buyers.

The same boundary applies to filtering. `latest_delivery_date` compares against the UTC date, so for example, an estimate of 2026-04-12T03:00:00Z has a UTC date of April 12th but is April 11th in America/Los\_Angeles. The filter would exclude it if `latest_delivery_date` is 2026-04-11, even though the package arrives on April 11th locally. Timezone-aware filtering is on the roadmap.

`estimated_transit_days` is the number of calendar days between your planned ship date and the predicted delivery date, returned as a whole number of days (e.g. `2.0`). The dates are counted based on their local calendars to match what the sender and the recipient each see locally, which is why adding `estimated_transit_days` to your `planned_ship_date` will not always produce the date portion of `estimated_delivery_date_utc`. Use `estimated_delivery_date_utc` as the authoritative delivery date, with `estimated_transit_days` as a display-friendly duration.

## Confidence levels

Pass `confidence_level` to control how conservative the estimate is. Omit it, and you get `DEFAULT`. The response echoes back whichever level was applied.

| Value     | What it means                                                                                  | Use it for                                     |
| :-------- | :--------------------------------------------------------------------------------------------- | :--------------------------------------------- |
| `TYPICAL` | The most common outcome on this lane. Around half of deliveries arrive on or before this date. | Internal planning, picking between services    |
| `DEFAULT` | Calibrated for showing to buyers. The majority of deliveries arrive by this date.              | Checkout, product pages, order confirmation    |
| `HIGH`    | A conservative date. Use it when arriving late costs you more than quoting a later date.       | SLA commitments, regulated or perishable goods |

Values are uppercase. Each call returns a single confidence level - the `DEFAULT`, or the one you selected. To receive more than one confidence level, you will need to make multiple calls (each of which is billed separately).

None of these are guarantees. They're predictions trained on real delivery outcomes, and carrier performance varies. Only certain services carry a carrier money-back guarantee, at the carrier's discretion.

## Service levels supported

We support 29 service levels at GA, covering roughly 92 percent of the volume shipped through Shippo. Refer to [Supported service levels](/estimate/supported-service-levels) for valid `servicelevel_tokens` values for each support service level.

* **USPS** Ground Advantage, Priority Mail, Priority Mail Express, Media Mail
* **UPS** Ground, Ground Saver, 2nd Day Air®, 2nd Day Air A.M.®, 3 Day Select®, Next Day Air®, Next Day Air Saver®, Next Day Air® Early, SurePost, SurePost Lightweight
* **FedEx** Ground, Home Delivery, Ground Economy, Smartpost®, 2Day, 2Day A.M., Express Saver®, Standard Overnight®, Priority Overnight®, First Overnight®
* **Regional carriers** OnTrac Ground, LaserShip Ground, AxleHire Next Day, Veho Ground Plus, Veho Premium Economy

Estimates are for US domestic shipments only, and for single-piece shipments only.

## Before going live

The Estimate API is built to sit on your critical path — gating a shipping choice, or checkout itself, on a returned delivery date is a supported way to use it. But like any network dependency, it will occasionally be slow or unavailable. A production integration is one where that moment degrades gracefully instead of stalling a purchase.

That resilience comes down to five controls - all standard in HTTP and resilience libraries, so defaults are a fine starting point:

| Control         | What it does                                                                                                        | Guidance                                                                                                                                                                                                                   |
| :-------------- | :------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Timeouts        | Stops a slow call from hanging your page                                                                            | Set a read timeout of about 1–1.5 seconds - enough to cover a normal response with margin. If a call runs slower than that, fail fast to your fallback rather than widening the timeout to chase the rare slow one.        |
| Circuit breaker | Stops calling us when we're clearly failing, and stops you from wasting effort on a dependency that isn't answering | **Recommended** After a run of failures, serve your fallback for a cool-down, then let one probe through. Count connection errors, timeouts, and 5xx as failures — not 4xx.                                                |
| Bulkhead        | Caps how many Estimate calls run at once, so a slowdown can't exhaust your thread or connection pool                | **Recommended** Set it comfortably above your normal concurrency and leave it. It's a safety valve, not a dial to tune — it only fires when calls pile up.                                                                 |
| Retry           | Recovers a brief one-off blip                                                                                       | At most one retry, and only when a fresh date genuinely beats your fallback. Retry on connection errors, 502/503/504, 408, and 429 (with exponential backoff and jitter). Never retry other 4xx — they're deterministic.   |
| Fallback        | What your customer actually sees when a call is slow or down                                                        | **Recommended** It must be a real value served instantly — never an error or a spinner. Best to simplest: a cached prior estimate → your own static per-service-level table → a post-purchase estimate → hiding the field. |

### Two things that surprise people

* **A 200 can be partial.** Success doesn't guarantee every service level you asked for is present; missing ones are explained in `messages[]` -- `prediction_unavailable` (transient; that service level is temporarily unavailable) or `servicelevel_unsupported` (non-transient; that token isn’t supported). Apply your fallback per service level (full schema in the [API reference](/api-reference/estimates/create-estimates)).
* **Successful calls are billable; failed ones aren't.** Retrying a genuine failure costs nothing. The one way a retry double-bills is if your client times out on a call that actually succeeded — which is why the read timeout should be generous enough not to cut off a normal response, and number of retries should be capped.

### Pre-launch checklist

* Read timeout set; total wait bounded to your customer’s patience
* Circuit breaker and bulkhead configured for every use case
* Retry capped at one, and only where a fresh date beats the fallback
* A real fallback in place, served instantly
* Partial 200 / `messages[]` handled for the service levels you depend on
* Subscribed to the Shippo status page

## What the API doesn't do yet

No batch endpoint, no delivery date ranges, no carrier-level filtering, no multi-piece shipments, and no international lanes. The `object_id` in the response is a correlation ID for support, not something you can fetch later.

Test tokens return placeholder predictions rather than real ones, and test calls aren't billed.


## Related topics

- [Create Estimates](/api-reference/estimates/create-estimates.md)
- [Supported service levels](/estimate/supported-service-levels.md)
- [Shippo API release notes](/api-concepts/api-change-log.md)
