Product kits
One verified reference sheet that every generation can use.
A product in roasOS is more than a folder of photos. When you make a product, roasOS reads the photos and builds the reference sheet: one image that shows the product from every angle, with a large close-up of the label. The sheet is the kit. It is the reason a bottle keeps its exact label and its exact shape across an image, a scene and a video.
What a product carries
| Part | What it is |
|---|---|
| Facts | the structured description: the category, the form factor, the colours, the materials, the label text, the size class and how a person holds it |
| Reference sheet | ONE generated image: up to nine labeled views of the product on a grid, at 4K |
| Raw photos | the photos that you uploaded; they stay available |
roasOS builds the sheet from the photos and the facts. It then reads the sheet back, and it checks that every label line is legible. A sheet that fails the check does not publish; roasOS retries once with the failure named.
The views on the sheet follow the product's category. A supplement sheet leads with the label close-up and shows the loose gummies. An apparel sheet leads with the front of the garment and shows the fabric and the print. A device sheet leads with the three-quarter view and shows the ports.
A product takes 5 raw photos at most.
App products
A mobile app is a product too, and it has no object to photograph. Make it with kind: "app". Its images are real screenshots taken on the phone, up to 8. Do not use App Store marketing images: those carry device frames, captions and crops, and an ad built on them shows a picture of a picture. roasOS builds no sheet and no kit for an app: a screenshot has no angles, and its pixels are the proof.
When an ad shows the app, it shows one of these screenshots on a phone in the scene. The screenshot goes into the render as a reference image, and the render prompt tells the model to show it exactly as given. The brief picks the screenshot that proves each variant's hook, so upload the screens that carry your claims.
Upload the screenshots with POST /v1/uploads and send their URLs in images, or send public https URLs of the screenshots in import_urls.
Add app_store_url for information. roasOS reads the public listing and fills the seller, the category, the price, the rating, the description and the icon. It never takes screenshots from the listing. Any product, of either kind, can carry product_url: its own public page, stored for information and never fetched.
curl -X POST https://api.roasos.com/v1/products \
-H "Authorization: Bearer roasos_sk_..." \
-H "Content-Type: application/json" \
-d '{ "name": "Capper", "kind": "app", "images": ["https://cdn.roasos.com/uploads/<ws>/images/<id>.png"], "app_store_url": "https://apps.apple.com/us/app/capper-ai-sports-betting/id6758966274" }'POST /v1/products/{id}/kit on an app product answers 409 product_kind_no_kit.
The legacy angle set
Before the sheet, a kit was a set of separate angle images. That set still exists for callers that ask for it explicitly.
| Set | Angles |
|---|---|
Full, with "full": true | front, three_quarter, detail, in_hand, side_left, side_right, top, surface |
Named, with angles | any of the nine names, in a list of 1 to 9 |
The ninth name is back. roasOS makes a back view from a raw back photo only, and it invents none.
Status
GET /v1/products/{id} gives the kit and its status.
| Status | Meaning |
|---|---|
none | there is no kit; only the raw photos are available |
queued | the kit job is waiting |
processing | the kit job is running |
ready | every angle is complete |
partial | some angles are complete |
failed | the kit job failed; the raw photos are still available |
You do not have to wait. A generation works while the status is queued or processing. roasOS then uses the raw photos.
How a generation uses the sheet
Send product_id on a model endpoint, and roasOS passes the reference sheet. One reference carries every angle, so the model fuses one identity instead of an average of many photos, and the label arrives large enough to copy.
If you pass product images yourself, pass reference_sheet from GET /v1/products/{id} as the one product reference. Until a sheet exists, roasOS falls back to the raw photos.
You never select shots yourself. Send product_id and let roasOS resolve it. Refer to Reference media and uploads.
Build a kit over the API
The API reference publishes every product operation.
| Operation | Path | Credits |
|---|---|---|
| Make a product | POST /v1/products | 0 |
| List the products | GET /v1/products | 0 |
| Read one product and its kit | GET /v1/products/{id} | 0 |
| Change a product | PATCH /v1/products/{id} | 0 |
| Delete a product | DELETE /v1/products/{id} | 0 |
| Build or rebuild the kit | POST /v1/products/{id}/kit | paid |
POST /v1/products takes a name and 1 to 5 photos (1 to 8 screenshots for kind: "app"). Put workspace-owned cdn.roasos.com URLs in images. Put public https URLs in import_urls, and roasOS fetches each one for you. For an app, refer to App products.
POST /v1/products/{id}/kit needs the scope api:write and an Idempotency-Key header. The body is optional, and it selects the artifact:
- An empty body requests the reference sheet. The answer is
202with{"status": "queued", "kind": "reference_sheet"}. roasOS generates the sheet within minutes, verifies the label, and publishes it asreference_sheeton the product. The generation is billed to the workspace like one image. {"full": true}or anangleslist runs the legacy angle job — paid, asynchronous, with the reservation shape below:
{
"data": {
"id": "6f1d…",
"kind": "product_kit",
"status": "queued",
"credits_reserved": 36,
"included": true,
"kit_version": 1
}
}roasOS also builds the sheet by itself when you make a product with photos, so most callers never post to /kit at all. Poll GET /v1/products/{id} until reference_sheet is set.
credits_reserved is the worst case, and roasOS refunds what the kit does not use. It holds four parts:
- one cut-out for each photo;
- one upscale for each photo;
- one render for each generated angle;
- one retry for each generated angle.
The retries are the fidelity check. It may make each angle a second time. A back view costs no angle render, because roasOS takes it from a raw photo.
included tells you what the job costs in the end. roasOS includes the first build of each product. roasOS also includes the first 5 kits of a workspace. It still reserves credits for an included job, because the dispatch needs a reservation. It then settles that job to 0, and it refunds the whole reservation.
A rebuild while a kit job runs answers 409 kit_job_running. A product with no photos answers 409 product_kit_requires_photos.
Then poll GET /v1/products/{id} until the kit status is ready. The kit job publishes onto the product; it does not publish a job result of its own.
Quote the kit first
You can quote a kit build before you pay for it. Send "quote_only": true with the body. The answer is 200 with a quote. The quote charges nothing, and it is valid for 10 minutes:
{
"data": {
"kind": "quote",
"quote_id": "0b7e…",
"reserved_credits": 36,
"expires_at": "2026-10-18T12:10:00Z",
"pricing_version": "customer-pricing@…",
"authorization": { "status": "auto_approved" },
"confirmation": {
"generation_type": "product_kit",
"product_id": "6f1d…",
"kit_version": 2,
"angles": ["front", "three_quarter", "detail", "in_hand"],
"included": true
}
}
}Then send the same body with "quote_id" in place of quote_only, and the same Idempotency-Key. The confirm charges exactly reserved_credits and answers the 202 job above. These rules apply:
- With
quote_onlyorquote_idand neitherfullnorangles, the call builds the four core angles. It does not request the reference sheet. - roasOS refuses a confirm with a different body, a different price or a different kit version. Quote again.
- A confirm that you send again returns the first answer. roasOS does not charge it twice.
- When a kit job already runs for the product, the confirm answers
409 kit_job_runningand charges nothing. - A quote that expired answers
410. Quote again. quote_onlytogether withquote_idanswers400.
A body with no quote field still builds the kit in one call, as before.
An agent makes and reads a product with roasos_create_product, roasos_list_products and roasos_get_product. It builds a kit with roasos_build_product_kit, which is quote-first. The change and the delete have no tool, so an agent calls those over REST.
Files
Each kit file is an immutable object under https://cdn.roasos.com/workspaces/<workspace>/products/<product>/v<n>/. A rebuild makes a new version, so an older URL keeps its bytes.
Next
- Where the photos come from: Reference media and uploads.
- What a kit makes possible: Statics.
- One product, one set of ads: Make static ads.