# Retrieve a queue entry

`GET https://stylor.ai/api/v1/datasets/{datasetId}/items/queue/{itemId}`

- Authentication: private API key, sent as `Authorization: Bearer sgpt-sk-…::…`
- Rate-limit resource: `api.v1.datasets.items.queue.retrieve`
- Demo key: not accepted
- Web page: https://stylor.ai/guides/rest/v1/retrieve-queue-item

Returns one queue entry by `itemId`, in any status including `archived`.
Use it to poll a single product after upload, or to read
`worker.failure` when an entry is `failed`.

This endpoint returns the stored document as-is, so the response also
contains the internal `_id` and `__v` fields. Ignore them; they are not
part of the contract and are absent from the list endpoint.

## Example request

```bash
curl -X GET "https://stylor.ai/api/v1/datasets/YOUR_DATASET_ID/items/queue/YOUR_ITEM_ID" \
  -H "Authorization: Bearer $STYLOR_API_KEY"
```

## Path parameters

- `datasetId` (string (uuid), required): The dataset's id, as returned when it was created.
- `itemId` (string (uuid), required): The queue entry's `itemId`, as returned by the queue listing. The upload endpoint does not return ids.

## Responses

### 200

The queue entry.

Content type `application/json`:

- `item` (object, required): An entry in a dataset's ingest queue. Uploading products creates one entry per product in `pending`; a background worker claims entries, downloads images, extracts metadata and embeddings, and writes a `DatasetItem` with the same `itemId`. The entry is kept after processing with status `complete` (or `failed`); uploading or syncing the same SKU again updates this entry rather than creating another. Status meanings: `pending` waiting for a worker; `processing` claimed; `partial_update` a price/stock refresh that skips AI processing; `complete` a `DatasetItem` was written; `failed` see `worker.failure`; `archived` hidden from listings.
  - `itemId` (string (uuid), required): Queue entry id, assigned at upload. The processed `DatasetItem` reuses it. [example `"8b0a1b62-7c2a-4b7f-9e2c-0f3a9b1f0c11"`]
  - `organizationId` (string (uuid), required): Owning organization. [example `"0a2c1f4e-5b6d-7e8f-9012-3456789abcde"`]
  - `datasetId` (string (uuid), required): Target dataset. [example `"c9b3c6c0-9b0f-4f42-bf3f-2b7a6b1b9d31"`]
  - `status` (string, required): Processing state. [one of `"pending"`, `"processing"`, `"partial_update"`, `"complete"`, `"failed"`, `"archived"`; example `"pending"`]
  - `worker` (QueueWorkerState): Processing bookkeeping. Created with an empty `logs` list at upload; the other sub-fields appear once a worker or sync sets them.
    - `logs` (array<QueueWorkerLog>): Worker log lines, oldest first. Only the 20 most recent are kept. [max items 20]
      - `type` (string): Severity. [one of `"info"`, `"warning"`, `"error"`; example `"info"`]
      - `message` (string): Human-readable message, for example `Claimed by worker <id>`, `Completed by worker <id>`, `Failed: <reason>`, `Stale lock released by worker <id>`, `Updated by sync (<status>)` or `Archived: removed from source`. [example `"Claimed by worker w-7f2a"`]
      - `createdAt` (string (date-time)): When the line was written. [example `"2025-03-04T18:20:03.001Z"`]
    - `lockedBy` (string, nullable): Id of the worker currently processing the entry, or `null`. [example `null`]
    - `lockedAt` (string, nullable): When the current lock was taken, as an ISO 8601 string, or `null`. A lock older than 20 minutes is released and the entry returns to `pending`. [example `null`]
    - `failure` (QueueWorkerFailure, nullable): Set alongside `status: failed`. Reset to `null` when the entry is claimed again or refreshed by a sync.
      - `reason` (string): Human-readable failure reason. [example `"No images could be downloaded"`]
      - `code` (string): `PROCESSING_FAILED` a processing step reported failure; `UNEXPECTED_ERROR` processing threw; `PROCESSING_ERROR` fallback when no code was supplied. [one of `"PROCESSING_FAILED"`, `"UNEXPECTED_ERROR"`, `"PROCESSING_ERROR"`; example `"PROCESSING_FAILED"`]
      - `details` (object, nullable): Additional context. `null` for `PROCESSING_FAILED`; for `UNEXPECTED_ERROR` an object with the error `stack`. [example `null`]
      - `timestamp` (string (date-time)): When the failure was recorded. [example `"2025-03-04T18:21:10.442Z"`]
  - `disableGenerativeAssets` (boolean): Whether AI thumbnails are skipped. Always `true` at present because generative assets are disabled platform-wide. [default `true`; example `true`]
  - `forceFullProcess` (boolean): When `true` the worker runs the full AI pipeline even if the SKU already exists as a processed item. Set internally by store syncs. [default `false`; example `false`]
  - `data` (IngestProduct, required): The raw product shape accepted by the upload endpoint and stored on the queue entry as `data`. It mirrors a Shopify product export. Every field listed is required except `gender`. `description` and `productType` may be empty strings; `name`, `handle` and `sku` must be non-empty (an empty value passes field validation but fails at the database with a `500`). The three date fields must be parseable and are normalised to ISO 8601 UTC on the way in.
    - `name` (string, required): Product title. Must be non-empty. [example `"Classic Crew Tee"`]
    - `handle` (string, required): URL slug. The product URL is built as `<store URL>/products/<handle>`. Must be non-empty. [example `"classic-crew-tee"`]
    - `description` (string, required): Product description; HTML is allowed. May be an empty string. [example `"<p>A heavyweight organic cotton tee with a relaxed fit.</p>"`]
    - `publishedAt` (string, required): Any string `Date` can parse (ISO 8601 recommended). [example `"2024-11-02T09:15:00Z"`]
    - `createdAt` (string, required): Any string `Date` can parse. [example `"2024-11-02T09:15:00Z"`]
    - `updatedAt` (string, required): Any string `Date` can parse. [example `"2025-02-10T12:00:00Z"`]
    - `productType` (string, required): Merchant category. May be an empty string. [example `"T-Shirts"`]
    - `sku` (string, required): Product-level SKU. Must be non-empty, unique within the request, and not already present in the dataset's queue. [example `"A1A2P-BB2J"`]
    - `price` (number, required): Product price. Must be a non-negative number. [minimum 0; example `49`]
    - `tags` (array<string>, required): Free-form tags. Every element must be a non-empty string.
    - `images` (array<IngestProductImage>, required): Images to download. Every element must be an object with `src`.
      - `src` (string (uri), required): Publicly fetchable image URL. Required — an entry without `src` fails the upload with a database validation error. [example `"https://cdn.shopify.com/s/files/1/0001/products/tee-front.jpg"`]
    - `options` (array<IngestProductOption>, required): Product options. Every element must be an object.
      - `name` (string, required): Option name. [example `"Size"`]
      - `values` (array<string>, required): Option values. Empty strings fail the upload at the database.
    - `variants` (array<IngestProductVariant>, required): Purchasable variants. Every element must be an object; a `null` element fails the request with the shared `500`.
      - `sku` (string, required): Variant SKU. Must be a string; an empty string is accepted. [example `"A1A2P-BB2J-M"`]
      - `name` (string, required): Variant title. Becomes the size `label`. Must be non-empty — an empty string fails the upload at the database with a `500`. [example `"Medium"`]
      - `available` (boolean, required): Whether the variant is in stock. [example `true`]
      - `price` (number, required): Variant price. Must be a non-negative number. [minimum 0; example `49`]
      - `createdAt` (string, required): Any string `Date` can parse (ISO 8601 recommended). Stored normalised to ISO 8601 UTC. [example `"2024-11-02T09:15:00Z"`]
      - `updatedAt` (string, required): Any string `Date` can parse. Stored normalised to ISO 8601 UTC. [example `"2025-02-10T12:00:00Z"`]
      - `productId` (string, required): Your identifier for the parent product. Must be non-empty. [example `"8412345678901"`]
    - `gender` (string, nullable): Optional. Who you sell the product to, when you know. It is stored as the item's `metadata.gender` in place of the one the labeller would choose, ahead of any department the title or tags name and of the dataset's `targetGender`. Products that are not worn (home goods, beauty, gift cards) are always `unisex`. Omit it or send `null` to let the labeller decide. Changing it on an existing SKU relabels the product. [one of `"mens"`, `"womens"`, `"unisex"`, `null`; example `"womens"`]
  - `version` (number, required): Ingest pipeline version the entry will be processed with. [example `1`]
  - `createdAt` (string (date-time), required): When the entry was queued. [example `"2025-03-04T18:19:58.120Z"`]
  - `updatedAt` (string (date-time), required): Last status or worker change. [example `"2025-03-04T18:19:58.120Z"`]
  - `_id` (string): Internal database id. Not part of the contract.
  - `__v` (integer): Internal document version. Not part of the contract.

Example:

```json
{
  "item": {
    "_id": "67c74b5e2f1a9c0012d4e8a1",
    "itemId": "8b0a1b62-7c2a-4b7f-9e2c-0f3a9b1f0c11",
    "organizationId": "0a2c1f4e-5b6d-7e8f-9012-3456789abcde",
    "datasetId": "c9b3c6c0-9b0f-4f42-bf3f-2b7a6b1b9d31",
    "status": "failed",
    "worker": {
      "logs": [
        {
          "type": "info",
          "message": "Claimed by worker w-7f2a",
          "createdAt": "2025-03-04T18:20:03.001Z"
        },
        {
          "type": "error",
          "message": "Failed: No images could be downloaded",
          "createdAt": "2025-03-04T18:21:10.442Z"
        }
      ],
      "lockedBy": null,
      "lockedAt": null,
      "failure": {
        "reason": "No images could be downloaded",
        "code": "PROCESSING_FAILED",
        "details": null,
        "timestamp": "2025-03-04T18:21:10.442Z"
      }
    },
    "disableGenerativeAssets": true,
    "forceFullProcess": false,
    "data": {
      "name": "Classic Crew Tee",
      "handle": "classic-crew-tee",
      "description": "",
      "publishedAt": "2024-11-02T09:15:00.000Z",
      "createdAt": "2024-11-02T09:15:00.000Z",
      "updatedAt": "2025-02-10T12:00:00.000Z",
      "productType": "T-Shirts",
      "sku": "A1A2P-BB2J",
      "price": 49,
      "tags": [],
      "variants": [],
      "images": [
        {
          "src": "https://cdn.shopify.com/s/files/1/0001/products/missing.jpg"
        }
      ],
      "options": []
    },
    "version": 1,
    "createdAt": "2025-03-04T18:19:58.120Z",
    "updatedAt": "2025-03-04T18:21:10.442Z",
    "__v": 0
  }
}
```

## Errors

Every error is a JSON object with an `error` string. Match on the status code; the message is written for people.

| Status | Message | When |
| --- | --- | --- |
| 401 | Organization '<organizationId>' not found. | The organization encoded in the API key no longer exists. |
| 404 | Dataset not found for this organization. | No dataset with this `datasetId` belongs to the key's organization. |
| 404 | Queued item '<itemId>' not found in dataset '<datasetId>' for organization '<organizationId>'. | The dataset exists but its queue holds no entry with this `itemId`. |

### Shared authentication, quota and rate-limit errors

| Status | Message | When |
| --- | --- | --- |
| 401 | API key missing. | The `Authorization` header is absent, is not `Bearer <key>`, or the key does not have three dash-separated segments. |
| 401 | Authentication failed: public key is invalid or not recognized. | A public-key endpoint was called with a key that does not exist. |
| 401 | Authentication failed: private key provided instead of a public key. | A public-key endpoint was called with an `sgpt-sk-…` key. |
| 401 | Authentication failed: token is not recognized. | A private-key endpoint was called with a key whose lookup segment does not exist. |
| 401 | Authentication failed: private key is invalid. | A private-key endpoint was called with a key whose secret does not match. |
| 401 | Authentication failed: public key provided instead of a private key. | A private-key endpoint was called with an `sgpt-pk-…` key. |
| 401 | Authentication failed: bearer token format is invalid. | A private key was sent without its `::` lookup segment. |
| 401 | Authentication failed: API key could not be read. Regenerate the key. | The key's embedded organization data could not be decrypted or parsed. |
| 403 | Demo mode is not available for private-key routes. Demos are only supported with public API keys. | The demo key was sent to a private-key endpoint. |
| 403 | Demo mode is not supported on this API route. Check the documentation for available demo endpoints. | The demo key was sent to a public-key endpoint that opts out of demo mode. |
| 403 | No active subscription for this organization. | The organization that owns the key has no active subscription. |
| 403 | No quota found for organization "<organizationId>". | The organization has no quota record for the current billing period. |
| 403 | No entitlement for "<resource>". | The plan's quota template has no entry for this endpoint. |
| 403 | Access denied to "<resource>". | The plan's quota template turns this endpoint off. |
| 429 | Monthly quota exceeded for "<resource>" (<quota>/<quota> used). | The billing-period quota for this endpoint is exhausted. `Retry-After` gives the seconds until the period resets. |
| 429 | RPM limit exceeded for "<resource>" (<used>/<limit> used). | More than the allowed requests per minute were sent. `Retry-After` is 60. |
| 500 | Internal server error. | An unexpected failure on the server. The message is always this string; details are logged, never returned. Quota consumed by the request is refunded, as it is for every 5xx response. |
