---
title: "How writes work (Operations)"
canonical_url: https://support.digitalphotogallery.com/articles/article/2811a89b-e9f5-413a-b05c-7bb20b699313
short_url: https://dpg.support/aygk
category: "API"
locale: en
updated_at: 2026-07-03T17:22:33Z
source: Digital Photo Gallery Support
---

# How writes work (Operations)

When you read from the API you get your answer straight away. Writing works a little differently, and it's worth understanding before you start making changes, because every write in the API behaves the same way.

### Why a write gives you an Operation

Some image work takes real time: regenerating versions, building an archive, moving thousands of photos between sets. That work runs through the image processor, so a write doesn't sit and wait for it. Instead it:

1. takes your request and replies with **`202 Accepted`** and an **Operation**, then
2. does the work in the background, moving the Operation to `succeeded` or `failed`.

You poll the Operation until it's done.

```
PATCH /v1/images/{public_uuid}
Authorization: Bearer YOUR_TOKEN
Idempotency-Key: 8f14e45f-ceea-467a-9e0b-1a2b3c4d5e6f
Content-Type: application/json

{ "title": "Main Stage, Friday headline" }
```

```json
{
  "uuid": "op-7c9e…",
  "status": "succeeded",
  "type": "update",
  "image_public_uuids": ["be66ea4e-…"],
  "result": { "message": "Updated successfully." }
}
```

Then keep polling:

```
GET /v1/operations/op-7c9e…
```

until `status` reads `succeeded` or `failed`.

> 💡 **Tip:** Most operations finish almost instantly and come back already `succeeded` in that first `202`. It's still worth polling, so your code copes gracefully with the ones that take a moment longer.

### Idempotency

Every write needs an **`Idempotency-Key`** header. It can be any unique value for the action you're performing, and a UUID does the job nicely.

- Send the **same key with the same body** again and you'll get the original Operation straight back, with the work done only once. So if a request times out, you can safely retry it.
- Send the **same key with a different body** and you'll get `409 idempotency_key_conflict`.

That's what makes writing safe to automate: a dropped connection never turns into a duplicate edit.

### Polling without the waste

When you read an Operation, send back the `ETag` you were given as `If-None-Match`. While nothing has changed you'll get a tiny `304 Not Modified` back, so polling all the way to the finish costs next to nothing.

### In short

Write, get an Operation (`202`), then poll until it's `succeeded` or `failed`. Always send an `Idempotency-Key`. Every write in the API follows this same pattern.
