# Rendering

Canonical URL: https://api-docs.test-printeers.com/guides/rendering

Learn how to create product mockup renders using scenes, perspectives, and compositions.

## Overview

Rendering generates realistic product mockups by placing your design on a product in a 3D scene, viewed from a specific camera angle. The full flow looks like this:

```
   Browse catalog        Discover scenes
   GET /products         GET /scenes
        │                     │
        ▼                     ▼
   Product_xxx            Scene_xxx
        │                     │
        └─────────┬───────────┘
                  │
                  ▼
        List perspectives
        GET /perspectives
                  │
                  ▼
         Perspective_xxx
                  │
                  ▼
         Look up composition
     GET /lookup-composition
                  │
                  ▼
         Composition_xxx + Image_xxx
              POST /renders
                  │
                  ▼
             Render_xxx
                  │
                  ▼
            Poll status
         GET /renders/xxx
                  │
                  ▼
             completed
                  │
        ┌─────────┴─────────┐
        ▼                   ▼
  Download media      Download thumbnail
  GET /renders/xxx/   GET /renders/xxx/
      media               thumbnail
```

## Concepts

Rendering has four building blocks:

- **Scene**: A 3D environment (studio backdrop, desk setup, flat lay) in which products are placed. Each scene supports specific productgroups.
- **Perspective**: A camera angle with output settings (resolution, format). Scene perspectives can be used for all products in a scene. Product perspectives are tied to specific products, these usually highlight product features such as the camera island or charging port.
- **Composition**: A valid combination of a scene, a product, and a perspective. Not all combinations exist. Use the lookup endpoint to check.
- **Render**: The final output: your design placed on the product in the scene, from the chosen camera angle.

## Step 1: Discover Scenes and Perspectives

List available scenes with `GET /scenes`. Use the optional `productgroupReference` filter to find scenes that support a specific productgroup.

```bash
curl "https://api.printeers.com/v2/scenes?productgroupReference=Productgroup_7yrcm5hd2w8pz4x6k3qf9b1tnv" \
  -H "X-Printeers-Secret-Key: $KEY"
```

```json
{
  "scenes": [
    {
      "reference": "Scene_8hm3pz5wkr1yv7xn4btq9cdfsj",
      "name": "Studio White Backdrop"
    }
  ]
}
```

Use `GET /scenes/{sceneReference}` to see the scene's compatible productgroups and perspectives:

```json
{
  "scene": {
    "reference": "Scene_8hm3pz5wkr1yv7xn4btq9cdfsj",
    "name": "Studio White Backdrop",
    "description": "A simple photo studio with white backdrop",
    "private": false,
    "allowsProductPerspectives": false,
    "compatibleProductgroups": [
      { "reference": "Productgroup_7yrcm5hd2w8pz4x6k3qf9b1tnv" }
    ],
    "perspectives": [
      { "reference": "Perspective_6rv2mc8yqw3nt5xk9hpz1bdfgs" },
      { "reference": "Perspective_3qn8yw1kfh6mp5xr7vzb9ctdsj" }
    ]
  }
}
```

When `allowsProductPerspectives` is true, product-specific perspectives can also be used with this scene in addition to the scene's own perspectives. Not all scenes are suitable for rendering the product highlight perspectives.

List perspectives with `GET /perspectives`, optionally filtered by `sceneReference` and/or `productReference`. Use `GET /perspectives/{perspectiveReference}` to see output details:

```json
{
  "perspective": {
    "reference": "Perspective_6rv2mc8yqw3nt5xk9hpz1bdfgs",
    "name": "Upper Right",
    "output": {
      "widthPx": 2560,
      "heightPx": 2560,
      "format": "png"
    },
    "scenes": [
      { "reference": "Scene_8hm3pz5wkr1yv7xn4btq9cdfsj" }
    ],
    "products": null
  }
}
```

For scene perspectives, `scenes` lists the linked scenes and `products` is null. For product perspectives, `products` lists the linked products and `scenes` is null.

## Step 2: Look Up a Composition

Use `GET /lookup-composition` to check whether a scene + product + perspective combination is available:

```bash
curl "https://api.printeers.com/v2/lookup-composition?sceneReference=Scene_8hm3pz5wkr1yv7xn4btq9cdfsj&productReference=Product_4j8k2m5n7p9q1r3s6t8v0w2x4y&perspectiveReference=Perspective_6rv2mc8yqw3nt5xk9hpz1bdfgs" \
  -H "X-Printeers-Secret-Key: $KEY"
```

When the combination is available, the endpoint returns `200 OK`:

```json
{
  "composition": {
    "reference": "Composition_8hm3pz5wkr1yv7xn4btq9cdfsj",
    "tokenCost": 10
  }
}
```

`tokenCost` is the number of rendertokens a render of this composition consumes; see [Rendertokens](#rendertokens) below.

When the combination does not exist, the endpoint returns `404 Not Found`. When the combination exists but is no longer available, it returns `410 Gone`.

**Note**: It may make sense to store or even hard-code references to the scenes, perspectives and/or compositions you require for your use-case. Just be aware that references are different between our test and prod environment and that referenced objects may be deprecated and become unavailable.

## Step 3: Upload an Image

Upload the design you want rendered on the product. This is the same image upload used for creating orders. See the [Creating Orders](https://api-docs.test-printeers.com/guides/creating-orders.md) guide for full details.

```bash
curl -X POST https://api.printeers.com/v2/images \
  -H "X-Printeers-Secret-Key: $KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @design.png
```

```json
{
  "image": {
    "reference": "Image_pdcptbw3k48sv03wy338bb8jzm"
  }
}
```

Accepted formats are JPEG and PNG. Images larger than 7000x7000 pixels are automatically downsized. Uploading the same image twice returns the same reference.

## Step 4: Create a Render

Create a render by providing a composition reference and an image reference:

```bash
curl -X POST https://api.printeers.com/v2/renders \
  -H "X-Printeers-Secret-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "render": {
      "compositionReference": "Composition_8hm3pz5wkr1yv7xn4btq9cdfsj",
      "imageReference": "Image_pdcptbw3k48sv03wy338bb8jzm"
    }
  }'
```

```json
{
  "render": {
    "reference": "Render_8eksvwek9pc58r1qmqqf3492mg"
  }
}
```

Creating a render with the same composition and image returns the existing render reference.

Every call consumes the composition's `tokenCost` rendertokens from your organization's weekly limit. When the limit is reached, the endpoint returns `429 Too Many Requests` with error code `rendertoken_limit_exceeded`; see [Rendertokens](#rendertokens) below.

## Step 5: Poll for Completion

Renders are processed asynchronously. Poll `GET /renders/{renderReference}` to check the status. Use a 60-second polling interval.

```bash
curl "https://api.printeers.com/v2/renders/Render_8eksvwek9pc58r1qmqqf3492mg" \
  -H "X-Printeers-Secret-Key: $KEY"
```

```json
{
  "render": {
    "reference": "Render_8eksvwek9pc58r1qmqqf3492mg",
    "compositionReference": "Composition_8hm3pz5wkr1yv7xn4btq9cdfsj",
    "imageReference": "Image_pdcptbw3k48sv03wy338bb8jzm",
    "status": "completed",
    "thumbhash": "1QcSHQRnh493V4dIh4eXh4aTh0eHJ4dnhw==",
    "media": {
      "mimeType": "image/png",
      "extension": "png",
      "size": 524288
    },
    "thumbnail": {
      "mimeType": "image/png",
      "extension": "png",
      "size": 32768
    },
    "created": "2026-02-24T12:34:56Z",
    "completed": "2026-02-24T12:35:10Z"
  }
}
```

| Status | Meaning |
|---|---|
| `pending` | Render is queued or being processed. |
| `completed` | Render is ready for download. |
| `failed` | Render failed during processing. |

The `thumbhash` field contains a base64-encoded [thumbhash](https://evanw.github.io/thumbhash/) for generating a placeholder preview while the full image loads. It is only available when status is `completed`.

## Step 6: Download the Result

Download the full render or its thumbnail:

```bash
# Full render
curl "https://api.printeers.com/v2/renders/Render_8eksvwek9pc58r1qmqqf3492mg/media" \
  -H "X-Printeers-Secret-Key: $KEY" \
  --output render.png

# Thumbnail
curl "https://api.printeers.com/v2/renders/Render_8eksvwek9pc58r1qmqqf3492mg/thumbnail" \
  -H "X-Printeers-Secret-Key: $KEY" \
  --output thumbnail.png
```

When the render is complete, these endpoints return `200 OK` with the binary file. When the render is not yet complete, they return `202 Accepted` with a `Retry-After` header indicating how many seconds to wait before retrying.

A completed render's files never change, so the `200 OK` responses carry `Cache-Control: private, max-age=31536000, immutable`. An HTTP client or proxy that honors it keeps the file cached instead of downloading it again.

Render downloads count against the `downloads` rate-limit bucket; see the [Rate Limiting](https://api-docs.test-printeers.com/guides/rate-limiting.md) guide.

## Rendertokens

Render creation is metered in **rendertokens**. Each composition has a `tokenCost` (returned by `GET /lookup-composition` and `GET /compositions/{compositionReference}`), and every `POST /renders` call deducts that cost from your organization's weekly rendertoken limit. The limit resets every Monday at 00:00 Europe/Amsterdam, aligned with the billing week.

Check your current usage with `GET /rendertokens`:

```bash
curl "https://api.printeers.com/v2/rendertokens" \
  -H "X-Printeers-Secret-Key: $KEY"
```

```json
{
  "rendertokens": {
    "used": 120,
    "limit": 1000,
    "remaining": 880,
    "resets": "2026-07-13T00:00:00+02:00"
  }
}
```

When the remaining rendertokens do not cover the composition's `tokenCost`, `POST /renders` returns `429 Too Many Requests` with error code `rendertoken_limit_exceeded` and a `Retry-After` header set to the time until the weekly reset. Retrying earlier will not succeed. A rendertoken subscription with a higher weekly limit can be activated in the Printeers Dashboard under Settings, Subscriptions.

## Typical Integration

A typical rendering integration follows these steps:

1. **Browse the catalog**: call `GET /products` to find products and their productgroup references. See the [Products](https://api-docs.test-printeers.com/guides/products.md) guide.
2. **Discover scenes**: call `GET /scenes` filtered by productgroup to find available scenes.
3. **Pick a perspective**: use `GET /scenes/{sceneReference}` to see the scene's perspectives, or `GET /perspectives` to browse all perspectives.
4. **Look up the composition**: call `GET /lookup-composition` with the scene, product, and perspective. Returns 404 if the combination doesn't exist, or 410 if it's no longer available.
5. **Upload an image**: send the design to `POST /images`.
6. **Create the render**: call `POST /renders` with the composition and image references.
7. **Wait for completion**: poll `GET /renders/{renderReference}` every 60 seconds until `status` is `completed`.
8. **Download the result**: fetch the full render from `/media` and optionally the thumbnail from `/thumbnail`.

## Next Steps

- [Renders API Reference](https://api-docs.test-printeers.com/reference/v2#tag/renders): full endpoint documentation for all rendering endpoints.
- [Products](https://api-docs.test-printeers.com/guides/products.md): learn how products and productgroups are organized.
- [Creating Orders](https://api-docs.test-printeers.com/guides/creating-orders.md): place orders with your product images.
