---
title: "Bulk products toggle inventory policy offers"
description: "Flip the Shopify inventory policy on variants attached to a preorder offer (CONTINUE or DENY). Pass the explicit shopify_variant_ids for a partial change; omitting shopify_variant_ids applies the policy to EVERY attached"
url: https://docs.stoqapp.com/v2-reference/preorders-offers/bulk-products-toggle-inventory-policy-offers/
api: "API v2 reference"
method: POST
path: "/preorders/offers/{id}/products/bulk_toggle_inventory_policy"
---

# Bulk products toggle inventory policy offers

`POST https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/bulk_toggle_inventory_policy`

Flip the Shopify inventory policy on variants attached to a preorder offer (CONTINUE or DENY). Pass the explicit shopify_variant_ids for a partial change; omitting shopify_variant_ids applies the policy to EVERY attached variant, so only omit it when the merchant asked for all of them.

**Note:** Returns 202 with a job; Shopify is updated in batches, so poll job.status_url until it is completed. shopify_variant_ids are Shopify variant gids; ones not on this offer are skipped and returned in skipped_shopify_variant_ids, and the call fails with 422 if none are. With CONTINUE, variants at their quantity limit are left out, as the dashboard's 'Skip variants that have reached their quantity limit' (checked by default) does; skip_quantity_limited: false includes them.

## Path parameters

- `id` (string, required)

## Headers

- `Idempotency-Key` (string): A fresh unique key for every write (a new UUID, say); reuse it only to retry that write. Keys are remembered for 1 hour: the same key and the same request within that hour returns the first result, with `Idempotent-Replayed: true`, without running again; the same key with a different method, path or body is refused (422 `idempotency_key_reused`); a retry while the first is still running gets 409 `idempotency_key_in_progress`. Keys are per store. Server errors and rate limits are not kept, so their retry runs.

## Request body

- `policy` (string, required): e.g. `CONTINUE` One of: `CONTINUE`, `DENY`.
- `shopify_variant_ids` (array of strings)
- `skip_quantity_limited` (integer): e.g. `5`

Rate limit: this call costs 2 points ([rate limits](https://docs.stoqapp.com/docs/rate-limits/)).

## Example request

```sh
curl -X POST "https://app.stoqapp.com/api/v2/external/preorders/offers/73a74948-2b57-4cc3-971f-2b441828c977/products/bulk_toggle_inventory_policy" \
  -H "X-Auth-Token: $STOQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "policy": "CONTINUE",
    "shopify_variant_ids": [
      "45000000001"
    ],
    "skip_quantity_limited": 5
  }'
```

## 200

Success: the updated resource.

## 202

Accepted: async/bulk work was queued. Poll the returned job.

```json
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
```

## 401

Missing or invalid `X-Auth-Token`.

```json
{
  "errors": [
    "Invalid API key"
  ],
  "code": "auth_invalid",
  "details": [
    {
      "code": "auth_invalid",
      "message": "Invalid API key",
      "path": null,
      "value": null,
      "expected": null
    }
  ]
}
```

## 404

The resource does not exist for this shop, or the action path is not registered.

```json
{
  "errors": [
    "Offer not found"
  ],
  "code": "not_found",
  "details": [
    {
      "code": "not_found",
      "message": "Offer not found",
      "path": null,
      "value": null,
      "expected": null
    }
  ]
}
```

## 409

An earlier request with the same Idempotency-Key is still running. Wait, then resend the same request with the same key.

```json
{
  "errors": [
    "A request with this Idempotency-Key is still running"
  ],
  "code": "idempotency_key_in_progress",
  "details": [
    {
      "code": "idempotency_key_in_progress",
      "message": "A request with this Idempotency-Key is still running",
      "path": null,
      "value": null,
      "expected": null
    }
  ]
}
```

## 422

The request failed validation.

```json
{
  "errors": [
    "name is required"
  ],
  "code": "validation_failed",
  "details": [
    {
      "code": "validation_failed",
      "message": "name is required",
      "path": null,
      "value": null,
      "expected": null
    }
  ]
}
```

## 429

Rate limited: cost-weighted per token (read 1, write 2; 360 points / 60s). Check `Retry-After`.

```json
{
  "errors": [
    "Rate limit exceeded"
  ],
  "code": "rate_limited",
  "details": [
    {
      "code": "rate_limited",
      "message": "Rate limit exceeded",
      "path": null,
      "value": null,
      "expected": null
    }
  ]
}
```

