---
title: "Errors, rate limits & conventions"
canonical_url: https://support.digitalphotogallery.com/articles/article/e78e2cca-e45b-4a85-b4c9-ffd0b5ce3e76
short_url: https://dpg.support/aaam
category: "API"
locale: en
updated_at: 2026-07-03T17:22:44Z
source: Digital Photo Gallery Support
---

# Errors, rate limits & conventions

A handful of things behave the same way on every endpoint. Once you know them, the rest of the API holds no surprises.

### The error format

Whenever something goes wrong, the response has the same shape:

```json
{
  "error": {
    "code": "validation",
    "message": "…a readable explanation…",
    "detail": "title must be at most 191 characters",
    "field": "title",
    "request_id": "…"
  }
}
```

`code` is a stable machine name you can switch on, `detail` and `field` tell you exactly what to put right, and `request_id` is the reference to give us if you ever need to ask. You'll see codes like `unauthorized`, `forbidden`, `api_not_enabled`, `validation`, `image_not_found`, `idempotency_key_conflict`, `rate_limited` and `payload_too_large`.

> 💡 **Tip:** Because a `400 validation` tells you the field and the rule it broke, a program can read that, correct itself and try again, with nobody watching.

### Paging

Lists take `?limit` (50 by default, up to 200) and `?offset`, and every list sets two response headers so you always know where you stand:

- `X-Has-More` is `true` or `false`.
- `X-Next-Offset` is the `?offset` to use for the next page.

Keep going while `X-Has-More` is `true`.

### Rate limits

Signing in and MFA are rate limited. If you go over, you get `429 rate_limited` back with a `Retry-After` header telling you how many seconds to wait. Wait that long before trying again.

### Cheap polling

Every GET returns an `ETag`. Send it back as `If-None-Match`, and if nothing has changed you get an empty `304 Not Modified`, which is easy on both ends, especially over a slow or metered connection.

### Doing a lot at once

`POST /v1/operations/batch` runs up to 50 writes in a single request, so you can add keywords, set ratings and move images between sets all together. It hands back one summary plus a child Operation for each item, and the whole batch is checked before any of it runs, so it's all-or-nothing.

### Idempotency, once more

Every write takes an `Idempotency-Key`. The same key with the same body gives you back the original result, safely; the same key with a different body gives you a `409`. There's more in [Operations](https://support.digitalphotogallery.com/articles/article/2811a89b-e9f5-413a-b05c-7bb20b699313).
