---
title: "Schedule an offer"
description: "Schedule a preorder offer: start only (off until then), end only (on until then) or both (on between them)."
url: https://docs.stoqapp.com/v2-reference/preorders-offers/schedule-an-offer/
api: "API v2 reference"
method: POST
path: "/preorders/offers/{id}/schedule"
---

# Schedule an offer

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

Schedule a preorder offer: start only (off until then), end only (on until then) or both (on between them).

**Note:** Send start, end or both; absent or null leaves that side open. Like the editor, start only or a window turns the offer off until the start, and end only turns it on until the end. Changing the kind of schedule turns the countdown off, reported in also_changed. When the countdown is on or the merchant also wants one, say before proposing that scheduling turns it off, and schedule first, then turn the countdown on. Use unschedule to remove the schedule.

## 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

- `start` (string): e.g. `2026-07-01T09:00`
- `end` (string): e.g. `2026-07-31T23:59`

## Returns

- `id` (string): e.g. `73a74948-2b57-4cc3-971f-2b441828c977`
- `name` (string): e.g. `Summer Sneaker Drop`
- `internal_name` (string): e.g. `summer-2026`
- `availability` (object)
  - `schedule` (string): e.g. `date_range`
  - `starts_at` (string): e.g. `2026-07-01T09:00:00-04:00`
  - `ends_at` (string): e.g. `2026-07-31T23:59:00-04:00`
  - `current_status` (string): e.g. `scheduled`

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/schedule" \
  -H "X-Auth-Token: $STOQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "start": "2026-07-01T09:00",
    "end": "2026-07-31T23:59"
  }'
```

## 200

Success: example response shown.

```json
{
  "id": "73a74948-2b57-4cc3-971f-2b441828c977",
  "name": "Summer Sneaker Drop",
  "internal_name": "summer-2026",
  "availability": {
    "schedule": "date_range",
    "starts_at": "2026-07-01T09:00:00-04:00",
    "ends_at": "2026-07-31T23:59:00-04:00",
    "current_status": "scheduled"
  }
}
```

## 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

Invalid lifecycle transition: read the message; don't retry blindly. Also returned while an earlier request with the same Idempotency-Key is still running.

```json
{
  "errors": [
    "Offer is already disabled"
  ],
  "code": "conflict",
  "details": [
    {
      "code": "conflict",
      "message": "Offer is already disabled",
      "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
    }
  ]
}
```

