Collections
Some things Esy makes are made of other things: a clip art pack is a set of pieces with a cover, a story book is a run of pages. A collection is that whole, owned by Esy. Its members keep their ids through every re-roll, every piece of work lands on a member by id, and the cover, publishing and cost are read from the whole — never from whichever order happened to run last.
This page describes the model being built now, packs first. The packs API reference ships on this site with the endpoints. Until then packs are still placed as Generation Orders, as in Publish packs with a worker team, and existing integrations keep working unchanged while clients move over.
Collection, order, or artifact?
These three are easy to confuse, and the difference decides how you read everything else.
| What it is | Lives | Example | |
|---|---|---|---|
| Artifact | One made thing | Forever | A bear sticker |
| Order | One batch of work Esy executes | Until it settles | “Draw these 12 prompts” |
| Collection | One named thing made of many artifacts, redone piece by piece over many orders | Forever | The “Beach Bears” pack |
If it has its own title or cover, its members can be redone one at a time, and it outlives the order that started it, it is a collection. An order is never a collection: a pack with one re-roll already spans two orders.
What a collection holds
collection pack-7f3a91c2 · "Beach Bears" · kind pack · format clipart
├─ spec brief, style kit (slug + the version used), render settings
├─ cover artifact
├─ delivery unpublished | published | partial | failed
├─ etag "42" — changes whenever the collection or a member changes
└─ items
├─ pitem-91c2 "Bear with a water gun" accepted → current + print
│ └─ attempts order-…/run-… failed $0.11
│ order-…/run-… completed $0.11
├─ pitem-4b07 "Bear on a surfboard" review → current artifact
└─ pitem-c3e1 "Bear on a surfboard" B&W companionOf pitem-4b07| Part | What it is for |
|---|---|
kind | What sort of collection: pack today, story-book next. Each kind has its own route and its own words. |
spec | The kind’s settings, checked against the kind’s schema. Library references are stored with the version they resolved to, so editing a style kit later never changes how an existing pack was made. |
items | The members. Each has an id that never changes — renaming, re-rolling or reordering keeps it. |
attempts | Every time Esy tried to make a member: the order and run, the outcome, and what it cost. |
etag | A version tag. Edits send it back; if someone changed the collection in between, the edit is refused with 409 and the current collection, instead of silently overwriting their change. |
clientRef | Your own id for it, unique per workspace. Creating with the same clientRef twice returns the one collection. |
annotations | Small key-values of yours that Esy stores and returns but never interprets. |
Lifecycle
collection planning → ready → working → review → complete
+ attention (something failed or a budget stopped)
+ failed (planning failed) · archived
item pending → working → review → accepted
+ failed · removed (restorable) · locked (planned, not unlocked)Publishing is tracked apart from status, in delivery, so a complete collection can be published, taken down, and published again without its status moving.
Working on a collection
You read and edit a collection like any resource. Anything that does work or spends money is a named action on it, written {collection}:verb, so a rename and a render never look alike in your logs or your bill.
| Action | What happens |
|---|---|
:render | Esy makes every pending member, or only the ones you list (a re-roll). It places the orders itself and tags each job with its member. |
items/…:accept · :reject | Keep a member’s result, or send it back to pending. |
:makeCover · :makeSheet | Build the cover or a contact sheet from accepted members. |
:exportPrint | Make print-size renditions of accepted members. |
:publish · :unpublish | Deliver the whole collection to its outlet, or take it down. |
:archive | Hide it from lists. Nothing is deleted. |
Every action takes a requestId: send the same one again after a timeout and you get the first result back, not a second render and a second bill. Every action that starts work returns what it started — the orders, the members covered, the attempt ids and the budget cap — so you can charge, and refund a failed attempt, exactly once.
Knowing when something changed
Esy calls you rather than making you poll. Events are thin: they say which collection changed and its new version, and you read the collection for the rest. A late event for a version you have already seen is safe to ignore.
{
"type": "pack.updated",
"resource": { "type": "pack", "id": "pack-7f3a91c2", "version": 43 },
"clientRef": "cp_2f1a…",
"occurredAt": "2026-09-17T14:03:11Z"
}Deliveries are signed exactly like every other Esy webhook — see Webhooks — and may arrive more than once, so dedupe on webhook-id. To catch anything a long outage missed, list with updatedAfter every few minutes rather than every few seconds.
What stays with your app
Esy owns the collection; your app asks for work and shows what Esy returns. What stays yours is what is genuinely your business: your customers, prices, credits and checkout. For free previews the line is the same — you decide how many a customer gets, and Esy counts previews against the customer reference you send, so a new pack or a retry cannot reset the count.
Kinds
| Kind | Members | Status |
|---|---|---|
pack | Pieces — clip art, coloring pages or illustrations — plus a cover | First, in rollout |
story-book | Pages, drawing on a pack for its characters | Next |
- A collection is one named thing made of many artifacts; an order is one batch of work toward it.
- Members keep their ids through every re-roll, and results land on them by id.
- Work is a named action with a requestId; edits carry the etag.
- Esy tells you something changed; you read the collection to see what.