# SketchUp and Rhino plugins

> The shape of a modelling-tool plugin: export the view, render it, bring the image back.

Source: https://developers.mnml.ai/docs/plugin-pattern

A plugin does three things, in this order. The same pattern fits SketchUp, Rhino, Revit and Blender.

### Step 1: Export the viewport

Save the view as a PNG or JPEG at the size you want back.

### Step 2: Render it

Call [POST /v2/renders](https://developers.mnml.ai/docs/renders) with the image in the same call: the file as the `image` part of a multipart form, or base64 in JSON. Add an `Idempotency-Key` made when the user pressed the button, so a retry after a dropped connection never charges twice.

### Step 3: Bring the image back

Poll [GET /v2/jobs/{id}](https://developers.mnml.ai/docs/jobs) every few seconds, then download `outputs[0].url` before its `expires_at` and place it in the model or a gallery.

## Where the key lives

Each user pastes their own key from the [console](https://developers.mnml.ai/console/keys) into the plugin’s settings, and the plugin keeps it in the operating system’s keychain. Never ship a key inside the plugin: anyone could read it and spend on your account. A key used from a desktop plugin needs no allowed origins.

## Showing progress and cost

- Show the price before the user renders: [GET /v2/engines](https://developers.mnml.ai/docs/engines) lists each engine’s price.
- `charged_usd` on the answer is what the render cost, in dollars; [GET /v2/account](https://developers.mnml.ai/docs/account) is the balance left.
- A `402 INSUFFICIENT_CREDITS` should open the user’s top-up page, not a generic error.
- Respect `Retry-After` on a `429`, and see [Rate limits](https://developers.mnml.ai/docs/rate-limits) for the numbers.
