# Shipping

Shipping zones and prices.

This page covers [the shipping rate card object](https://public-api.dapi.digital/docs/reference/shipping.md#shipping_rate_card_object) and [the shipping quote object](https://public-api.dapi.digital/docs/reference/shipping.md#shipping_quote_object).

## Endpoints

-   [GET `/v2/shipping/rates`](https://public-api.dapi.digital/docs/reference/shipping.md#get_shipping_rates)
-   [GET `/v2/shipping/quote`](https://public-api.dapi.digital/docs/reference/shipping.md#get_shipping_quote)

## The shipping rate card object

What buyers pay for shipping. An order ships for the `base_price` of the tier of its heaviest single item (never the summed weight), plus `per_additional_item` for every other item. Items under `extra_small_max_weight_grams` ride along without the additional charge, unless they come with extra parts. Example: three small items and one medium item to EU Core cost the medium base price plus three additional items. When a zone has no price of its own for a tier, checkout charges that tier at the zone medium price (per additional item charge included), or, when the zone prices no medium tier either, a flat default for the whole parcel with no per additional item charge. The prices here already show that fallback, so they are always what checkout charges.

### Attributes

-   `object` (string): Names the type of this object. Always `shipping_rate_card`.
-   `currency` (string): Currency of every price on the card.
-   `tiers` (array of object): Tier limits, lightest first.
    -   `tier` (ShippingTier): Weight class of an item, by the greater of its actual and volumetric weight: `small` up to 600 g, `medium` up to 2 kg, `large` above.
    -   `max_weight_grams` (integer or null): Heaviest chargeable weight in the tier. Null for the top tier.
-   `extra_small_max_weight_grams` (integer): Items under this weight do not add the per-additional-item charge. Extra small is a flag on an item, not a tier you can quote: such an item is priced as `small` when it is the heaviest in the parcel, and is left out of `additional_items` otherwise.
-   `zones` (array of ShippingZone): Every active zone, or only the matching one with `country`.
    -   `code` (string): Stable identifier of the zone, for example `eu-core`. Zones are platform configuration, so they have a readable code instead of an opaque id.
    -   `object` (string): Names the type of this object. Always `shipping_zone`.
    -   `name` (string): Display name.
    -   `countries` (array of string): Countries this zone ships to. Empty for the rest-of-world zone, which covers every country not listed elsewhere except Russia, Belarus, Iran and Syria, where 3DAPI does not deliver.
    -   `rest_of_world` (boolean): True for the catch-all zone.
    -   `base_price` (object): What an order costs to ship to this zone, by the tier of its heaviest item. A tier the zone does not price shows the fallback checkout charges: the medium price, else the flat default (which then ignores `per_additional_item`).
        -   `small` (object): An amount of money. Amounts are integers in the smallest currency unit, so they never need decimal parsing.
            -   `amount` (integer): Amount in the smallest currency unit (cents for usd). 5000 means $50.00. Never a decimal.
            -   `currency` (string): Three-letter ISO 4217 currency code, lowercase. Every amount is `usd` today.
        -   `medium` (object): An amount of money. Amounts are integers in the smallest currency unit, so they never need decimal parsing.
            -   `amount` (integer): Amount in the smallest currency unit (cents for usd). 5000 means $50.00. Never a decimal.
            -   `currency` (string): Three-letter ISO 4217 currency code, lowercase. Every amount is `usd` today.
        -   `large` (object): An amount of money. Amounts are integers in the smallest currency unit, so they never need decimal parsing.
            -   `amount` (integer): Amount in the smallest currency unit (cents for usd). 5000 means $50.00. Never a decimal.
            -   `currency` (string): Three-letter ISO 4217 currency code, lowercase. Every amount is `usd` today.
    -   `per_additional_item` (object): Added for every item after the heaviest one.
        -   `amount` (integer): Amount in the smallest currency unit (cents for usd). 5000 means $50.00. Never a decimal.
        -   `currency` (string): Three-letter ISO 4217 currency code, lowercase. Every amount is `usd` today.

**The shipping rate card object**

```json
{
  "object": "shipping_rate_card",
  "currency": "usd",
  "tiers": [
    {
      "tier": "small",
      "max_weight_grams": 600
    },
    {
      "tier": "medium",
      "max_weight_grams": 2000
    },
    {
      "tier": "large",
      "max_weight_grams": null
    }
  ],
  "extra_small_max_weight_grams": 100,
  "zones": [
    {
      "code": "eu-core",
      "object": "shipping_zone",
      "name": "EU Core",
      "countries": [
        "DE",
        "NL",
        "BE",
        "PL",
        "RO"
      ],
      "rest_of_world": false,
      "base_price": {
        "small": {
          "amount": 599,
          "currency": "usd"
        },
        "medium": {
          "amount": 799,
          "currency": "usd"
        },
        "large": {
          "amount": 1299,
          "currency": "usd"
        }
      },
      "per_additional_item": {
        "amount": 100,
        "currency": "usd"
      }
    },
    {
      "code": "rest-of-world",
      "object": "shipping_zone",
      "name": "Rest of World",
      "countries": [],
      "rest_of_world": true,
      "base_price": {
        "small": {
          "amount": 1599,
          "currency": "usd"
        },
        "medium": {
          "amount": 1999,
          "currency": "usd"
        },
        "large": {
          "amount": 2999,
          "currency": "usd"
        }
      },
      "per_additional_item": {
        "amount": 100,
        "currency": "usd"
      }
    }
  ]
}
```

## Get the shipping rate card

GET `/v2/shipping/rates`

Public: no API key needed.

- **Credentials**: None: the endpoint is public.

- **For**: Designers and Integrators

- **Operation id**: `get_shipping_rates`

Returns every shipping zone with its prices per tier. Public: no credentials needed. An order ships for the `base_price` of the tier of its heaviest single item (never the summed weight), plus `per_additional_item` for every other item. Items under `extra_small_max_weight_grams` ride along without the additional charge, unless they come with extra parts. Example: three small items and one medium item to EU Core cost the medium base price plus three additional items. When a zone has no price of its own for a tier, checkout charges that tier at the zone medium price (per additional item charge included), or, when the zone prices no medium tier either, a flat default for the whole parcel with no per additional item charge. The prices here already show that fallback, so they are always what checkout charges. For a single price, use the shipping quote instead.

### Query parameters

-   `country` (string): Only return the zone that ships to this country. Russia, Belarus, Iran and Syria return no zones: 3DAPI does not deliver there.

### Returns 200 OK

The rate card. Returns [the shipping rate card object](https://public-api.dapi.digital/docs/reference/shipping.md#shipping_rate_card_object).

### Responses

-   `200`: The rate card.
-   `400`: The request is invalid. `details.errors` lists each problem (`validation_failed`), or an `expand[]` path is unknown (`invalid_expand`).
-   `429`: Too many requests (`rate_limited`): the limit is 120 per minute per IP address. Wait for the number of seconds in the `Retry-After` header, then retry; `details` has `limit`, `window_seconds`, `reset_at` and `retry_after_seconds`.

Errors use [the error object](https://public-api.dapi.digital/docs/guides/errors.md#error-object).

**Request**

```bash
curl "https://public-api.dapi.digital/v2/shipping/rates"
```

## The shipping quote object

The shipping price for one parcel to one country.

### Attributes

-   `object` (string): Names the type of this object. Always `shipping_quote`.
-   `zone` (object): The zone that serves the country.
    -   `code` (string): Stable identifier of the zone, for example `eu-core`. Zones are platform configuration, so they have a readable code instead of an opaque id.
    -   `name` (string): Display name of the zone.
-   `country_code` (string): ISO 3166-1 alpha-2 country code, uppercase. A code that is not a real country is refused with `validation_failed`.
-   `tier` (ShippingTier): Same shape as `ShippingTier` above.
-   `base_price` (object): Base price of the tier in this zone. When the zone does not price the tier, the fallback checkout charges: the zone medium price, else the flat default.
    -   `amount` (integer): Amount in the smallest currency unit (cents for usd). 5000 means $50.00. Never a decimal.
    -   `currency` (string): Three-letter ISO 4217 currency code, lowercase. Every amount is `usd` today.
-   `additional_items` (integer): Items charged on top of the heaviest one.
    
    Range at least 0.
    
-   `per_additional_item` (object): Charge for each additional item in this zone.
    -   `amount` (integer): Amount in the smallest currency unit (cents for usd). 5000 means $50.00. Never a decimal.
    -   `currency` (string): Three-letter ISO 4217 currency code, lowercase. Every amount is `usd` today.
-   `total` (object): What the shipping costs: `base_price` plus `per_additional_item` times `additional_items`.
    -   `amount` (integer): Amount in the smallest currency unit (cents for usd). 5000 means $50.00. Never a decimal.
    -   `currency` (string): Three-letter ISO 4217 currency code, lowercase. Every amount is `usd` today.

**The shipping quote object**

```json
{
  "object": "shipping_quote",
  "zone": {
    "code": "eu-core",
    "name": "EU Core"
  },
  "country_code": "DE",
  "tier": "medium",
  "base_price": {
    "amount": 799,
    "currency": "usd"
  },
  "additional_items": 3,
  "per_additional_item": {
    "amount": 100,
    "currency": "usd"
  },
  "total": {
    "amount": 1099,
    "currency": "usd"
  }
}
```

## Get a shipping price

GET `/v2/shipping/quote`

Public: no API key needed.

- **Credentials**: None: the endpoint is public.

- **For**: Designers and Integrators

- **Operation id**: `get_shipping_quote`

Returns what one parcel costs to ship to a country, given the tier of its heaviest item and how many other items travel with it. Public: no credentials needed. Computed exactly as checkout does, including its fallback for a tier the zone does not price (the zone medium price, else a flat default for the whole parcel with `per_additional_item` 0). Every country is served except Russia, Belarus, Iran and Syria, which 3DAPI does not deliver to (422 `shipping_destination_not_served`); the rest-of-world zone covers countries no other zone lists. A code that is not a country is a 400.

### Query parameters

-   `country` (string, required): Destination country.
-   `tier` (string, required): Tier of the heaviest item in the parcel. There is no `extra_small` tier: an extra-small item is quoted as `small`.
    
    Possible values: `small`, `medium`, `large`.
    
-   `additional_items` (integer or null): How many other items ship in the same parcel, extra-small items excluded. 0 for a single item.
    
    Range 0 to 1000. Defaults to 0.
    

### Returns 200 OK

The price. Returns [the shipping quote object](https://public-api.dapi.digital/docs/reference/shipping.md#shipping_quote_object).

### Responses

-   `200`: The price.
-   `400`: The request is invalid. `details.errors` lists each problem (`validation_failed`), or an `expand[]` path is unknown (`invalid_expand`).
-   `404`: No active zone serves the country (`shipping_zone_not_found`). Only possible if 3DAPI has switched off the rest-of-world zone.
-   `422`: 3DAPI does not deliver to the country (`shipping_destination_not_served`): Russia, Belarus, Iran and Syria.
-   `429`: Too many requests (`rate_limited`): the limit is 120 per minute per IP address. Wait for the number of seconds in the `Retry-After` header, then retry; `details` has `limit`, `window_seconds`, `reset_at` and `retry_after_seconds`.

Errors use [the error object](https://public-api.dapi.digital/docs/guides/errors.md#error-object).

**Request**

```bash
curl "https://public-api.dapi.digital/v2/shipping/quote?country=DE&tier=small"
```

---

3DAPI API Docs. This page on the web: https://public-api.dapi.digital/docs/reference/shipping. Index of every page: https://public-api.dapi.digital/docs/llms.txt.
