Shipping methods are the delivery options customers choose at checkout. Each method has a delivery `type`, a price, optional free-shipping threshold and delivery-time estimates, country restrictions, an associated tax rate, and per-currency price overrides for multi-currency stores.

Shipping methods can optionally be linked to a carrier addon (GLS, InPost, or Furgonetka). Linked `pickup_point` or `parcel` rates show the carrier's point picker at checkout. See the [Addons API](/docs/api-reference/addons) for managing carrier connections.

## List Shipping Methods

```
GET /api/v1/shipping
```

### Query Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `limit` | `number` | 10 | Methods per page (1-100) |
| `offset` | `number` | 0 | Methods to skip |
| `query` | `string` | – | Search by method name or description |

### Response

```json
{
  "data": [
    {
      "id": "0191abc0-1234-7def-8000-000000000001",
      "name": "Standard courier",
      "description": "Delivered within 3-5 business days",
      "type": "courier",
      "price": 9.99,
      "freeShippingThreshold": 100,
      "minShippingTime": 3,
      "maxShippingTime": 5,
      "countries": ["US", "CA"],
      "position": 0,
      "addonId": null,
      "addonName": null,
      "addonData": null,
      "taxRateId": "0191abc0-0000-7000-8000-000000000200",
      "currencyPrices": {},
      "createdAt": "2024-05-20T10:30:00.000Z",
      "updatedAt": "2024-05-20T10:30:00.000Z"
    }
  ],
  "meta": {
    "count": 1
  }
}
```

---

## Create Shipping Method

```
POST /api/v1/shipping
```

Creates a checkout delivery option. Prices are in the store's primary currency; use `currencyPrices` to override per currency on multi-currency stores.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | `string` | Yes | Display name shown at checkout, e.g. `Standard courier` |
| `description` | `string` | No | Optional description shown at checkout |
| `type` | `"courier"` \| `"parcel"` \| `"pickup_point"` \| `"in_store"` | Yes | Delivery type |
| `price` | `number` | Yes | Shipping price in the store's primary currency |
| `freeShippingThreshold` | `number` | No | Order subtotal above which this method is free (store currency) |
| `minShippingTime` | `number` | No | Minimum delivery time in days |
| `maxShippingTime` | `number` | No | Maximum delivery time in days |
| `countries` | `string[]` | No | ISO country codes this method ships to (empty = all) |
| `taxRateId` | `string` | No | Tax rate UUID to apply to this shipping method |
| `position` | `number` | No | Sort order at checkout (lower shows first) |
| `currencyPrices` | `object` | No | Per-currency overrides (`{ "EUR": { "price": 9, "freeShippingThreshold": 90 } }`) |
| `addonName` | `"gls"` \| `"inpost"` \| `"furgonetka"` | No | Carrier addon to link – must be connected first (see [Addons API](/docs/api-reference/addons)). Linked `pickup_point`/`parcel` rates show the carrier's point picker at checkout. **Updates are full-replace** – omitting `addonName`/`addonData` on PATCH unlinks the carrier, so resend them when changing other fields. |
| `addonData` | `object` | No | Carrier payload for the rate. Optional for `gls`/`inpost` (derived automatically); required for `furgonetka` (pass `{ id, name, service }` from the Furgonetka services list). |

```bash
curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Standard courier", "type": "courier", "price": 9.99, "freeShippingThreshold": 100, "countries": ["US", "CA"]}' \
  https://your-store.yns.store/api/v1/shipping
```

### Response (201)

```json
{
  "id": "0191abc0-1234-7def-8000-000000000001",
  "name": "Standard courier",
  "description": null,
  "type": "courier",
  "price": 9.99,
  "freeShippingThreshold": 100,
  "minShippingTime": null,
  "maxShippingTime": null,
  "countries": ["US", "CA"],
  "position": 0,
  "addonId": null,
  "addonName": null,
  "addonData": null,
  "taxRateId": null,
  "currencyPrices": {},
  "createdAt": "2024-06-15T10:30:00.000Z",
  "updatedAt": "2024-06-15T10:30:00.000Z"
}
```

---

## Get Shipping Method

```
GET /api/v1/shipping/:id
```

Returns a single shipping method by UUID, including its tax rate and per-currency prices.

### Response

```json
{
  "id": "0191abc0-1234-7def-8000-000000000001",
  "name": "Standard courier",
  "description": "Delivered within 3-5 business days",
  "type": "courier",
  "price": 9.99,
  "freeShippingThreshold": 100,
  "minShippingTime": 3,
  "maxShippingTime": 5,
  "countries": ["US", "CA"],
  "position": 0,
  "addonId": null,
  "addonName": null,
  "addonData": null,
  "taxRateId": "0191abc0-0000-7000-8000-000000000200",
  "currencyPrices": {
    "EUR": {
      "price": 8.99,
      "freeShippingThreshold": 90
    }
  },
  "createdAt": "2024-05-20T10:30:00.000Z",
  "updatedAt": "2024-05-20T10:30:00.000Z"
}
```

---

## Update Shipping Method

```
PATCH /api/v1/shipping/:id
```

Replaces the shipping method's fields. Uses the same body as **Create Shipping Method**.

### Request Body

Same fields as [Create Shipping Method](#create-shipping-method).

```bash
curl -X PATCH \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Express courier", "type": "courier", "price": 14.99, "minShippingTime": 1, "maxShippingTime": 2}' \
  https://your-store.yns.store/api/v1/shipping/0191abc0-1234-7def-8000-000000000001
```

### Response (200)

```json
{
  "id": "0191abc0-1234-7def-8000-000000000001",
  "name": "Express courier",
  "description": null,
  "type": "courier",
  "price": 14.99,
  "freeShippingThreshold": null,
  "minShippingTime": 1,
  "maxShippingTime": 2,
  "countries": [],
  "position": 0,
  "addonId": null,
  "addonName": null,
  "addonData": null,
  "taxRateId": null,
  "currencyPrices": {},
  "createdAt": "2024-05-20T10:30:00.000Z",
  "updatedAt": "2024-06-15T11:00:00.000Z"
}
```

---

## Delete Shipping Method

```
DELETE /api/v1/shipping/:id
```

Hard-deletes the shipping method by UUID.

```bash
curl -X DELETE \
  -H "Authorization: Bearer your_api_key" \
  https://your-store.yns.store/api/v1/shipping/0191abc0-1234-7def-8000-000000000001
```

### Response

```json
{
  "ok": true,
  "deleted": 1
}
```