---
title: "Queue the design work on a view"
method: POST
path: "/concepts/{concept}/angles/{conceptAngle}/renders"
tags: ["Renders"]
---

# Queue the design work on a view

`POST /concepts/{concept}/angles/{conceptAngle}/renders`

## Request

- Base URL: `https://api.getfacade.ai/api/v1`
- URL: `https://api.getfacade.ai/api/v1/concepts/{concept}/angles/{conceptAngle}/renders`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.getfacade.ai/oauth/authorize`, token URL `https://api.getfacade.ai/oauth/token`, scopes: `agent`)

Designs the exterior on this view and shows it on the photo: materials applicable in the
building's country, products actually sold there, and the build-up behind the surface.
Returns the render immediately with a non-terminal status: its `id` is the job
id. The finished `file_url` is a permanent public link (no signature, no expiry) that
can be handed to a person as it stands, and that keeps working for anyone it reaches.

Colour and brand are two different fields. `colors` carries the palette: `palette:1`,
`#RRGGBB`, and the order carries the 60/30/10 role, the first entry being the dominant
wall colour. `brand_selections` carries real manufacturer products at whatever precision
is known — `siding:brand:12`, `siding:line:40@double-4-dutchlap`,
`siding:product:88@double-4-dutchlap`, `paint:brand:3`, `paint:product:412` — where the
optional `@profile` suffix pins the siding geometry. Ten entries each.

`seed` is optional; omit it unless reproducing an earlier render, the server generates
and returns one.

`render_effort` asks for a tier: `BRAINSTORM` is the quickest, `STANDARD` the middle,
`HIGH` the slowest and most detailed. Some buildings resolve the tier on their own and
the request never reaches the render, so the response echoes what was asked for rather
than what ran.

**Refining an existing design.** With `mode: refine` the render iterates on
`parent_render_id` instead of the view photo: the instruction in
`prompts.prompt_concept` is applied to that finished picture and everything it does not
mention is kept. The parent must be **completed**, must belong to the same building, and
must sit in the same view stack as the render being created (a main render refines a main
render; a secondary view refines within its own stack) — otherwise this answers 422.

Refining a main view does **not** overwrite the picture: the server forks a new design,
so the design the result lands in is the one reported by
`relationships.concept_angle.meta.concept_id` of the response, not the one in the path.

## Path parameters

- `concept` string, required
- `conceptAngle` string, required

## Headers

- `Idempotency-Key` string, required

## Request body

- object
  - `data` object, required
    - `type` 'render', required
    - `attributes` object, required
      - `version` unknown, required
      - `seed` integer
      - `style_ids` integer[]
      - `colors` string[]: Palette entries: `palette:{id}` or `#RRGGBB`. Ordered 60/30/10.
      - `brand_selections` string[]: Manufacturer products: `{category}:{level}:{id}[@profile]`.
      - `render_effort` 'BRAINSTORM' | 'STANDARD' | 'HIGH': How hard the engine works on this picture. Ignored where the building resolves the tier itself; `HIGH` answers 422 without the entitlement.
      - `prompts` object
        - `prompt_concept` string
        - `prompt_angle` string
      - `mode` 'explore' | 'refine': `explore` (default) renders from the view photo; `refine` iterates on `parent_render_id`.
      - `parent_render_id` string: Required when `mode` is `refine`. Must be a completed render in the same building and view stack.
      - `controls` object[]: Sketches that steer the render. Uploading one is not part of this API yet.
        - `id` string, uuid, required

## Response `201`

Queued

- object
  - `data` Render: JSON:API resource. `id` is a top-level field, never inside `attributes`.
    - `type` string, required
    - `id` string, required
    - `attributes` object
      - `status` string
      - `started_at` string, date-time, nullable
      - `typical_duration` integer, nullable: Seconds this render usually takes end to end. Use it to pace polling.
      - `file_url` string, nullable: Permanent public link to the finished image. No signature, no expiry.
      - `error_message` string, nullable: Why the render failed, in the account's language. Present only on a failed render.
      - `error_code` string, nullable: Stable machine code for the failure (provider_error, timeout, style_transfer_error, ...).
      - `mode` 'explore' | 'refine'
      - `is_refine` boolean
      - `settings` object
        - `seed` integer
    - `relationships` object
      - `concept_angle` object
        - `data` ToOne
          - `data` object
            - `type` string, required
            - `id` string, required
        - `meta` object: The design this render landed in — a refine of a main view forks a new one.
          - `concept_id` string
          - `project_id` string
      - `parent_render` object: The render this one iterates on, null outside refine mode.
        - `data` object, nullable

## Other responses

- `402`: Admission refused before any work was queued. `AGENT_KEY_CAP_REACHED` — this key has spent its cap, issue a new one or raise it. `AGENT_CREDITS_EXHAUSTED` — the account has no `api`-scope credits left. Neither is retryable: back off and report the `detail` text as it stands.
- `409`: `IDEMPOTENCY_IN_PROGRESS` — the first call carrying this `Idempotency-Key` has not answered yet. Retryable, and the only refusal here that is: wait and send the same call again, or read the job list. Do not re-send it under a new key — that is the second charge this header exists to prevent.
- `422`: The request was understood and refused. The message is the API's own text; show it unchanged. `IDEMPOTENCY_KEY_REQUIRED` — a paid call from an agent key with no `Idempotency-Key` header; nothing was queued, send it again with one. `IDEMPOTENCY_KEY_REUSED` — that header value already names a different request; a new order needs a new value.
- `429`: Rate limited on this key's own bucket, separate from the human sessions of the same account. Refusal is deliberately cheap: back off, do not retry in a tight loop.

---

[API](https://skmtc.dev/getfacade/apis/getfacade-agent-api.md) · [All operations](https://skmtc.dev/getfacade/apis/getfacade-agent-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getfacade/apis/getfacade-agent-api/revisions/2b52eda7362c?raw)
