# Export as an image

> POST /boards/{boardId}/export

Source: https://mockflow.com/developers/reference/boards/export-board

**POST** `https://api.mockflow.com/v1/boards/{boardId}/export`  
Scopes: `boards:read`

**curl**

```bash
curl https://api.mockflow.com/v1/boards/brd_3f9e2a/export \
  -X POST \
  -H "Authorization: Bearer $MOCKFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "target": "item",
  "itemId": "itm_p4"
}'
```

**JavaScript**

```javascript
const response = await fetch("https://api.mockflow.com/v1/boards/brd_3f9e2a/export", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MOCKFLOW_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
  "target": "item",
  "itemId": "itm_p4"
})
});

const data = await response.json();
```

**Python**

```python
import os, requests

response = requests.post(
    "https://api.mockflow.com/v1/boards/brd_3f9e2a/export",
    headers={"Authorization": f"Bearer {os.environ['MOCKFLOW_API_KEY']}"},
    json={
  "target": "item",
  "itemId": "itm_p4"
},
)

response.raise_for_status()
data = response.json()
```

**202**

```json
{
  "id": "job_7hd2",
  "kind": "item.create",
  "status": "queued",
  "progress": 0,
  "message": "Interview 5 users",
  "result": {
    "itemIds": [
      "string"
    ],
    "updated": [
      "string"
    ],
    "deleted": [
      "string"
    ],
    "creditsUsed": 0,
    "boardTitle": "Q4 Launch Planning",
    "skill": "string"
  }
}
```

**429**

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests.",
    "docsUrl": "https://mockflow.com/developers/concepts/errors#rate_limited"
  },
  "requestId": "req_45d49816999bac40"
}
```

A PNG of the whole board, one frame with everything inside it, or one item on its own, drawn by the same renderer as the editor's Export. Drawing takes a browser, so this answers 202 with a Job; poll it, and the finished job's result carries `imageUrl`, `width` and `height`.

- `board` is every item except comment pins, cropped to what they cover.
- `frame` is a frame (a section, design frame, diagram frame, mood board and the like) and the items fully inside it. A design frame is cropped to its canvas, under its title bar.
- `item` is one item alone, with nothing behind it.

The background is transparent. The image is published at an unguessable address: anyone with the URL can open it, so treat the URL like the board content it shows. Very large areas are refused before rendering: 20,000 x 20,000 pixels at scale 1, 10,000 x 10,000 at scale 2.

### Authorization

- `Authorization` (string, required): `Bearer <key>`. The key needs `boards:read` scope. Create and manage keys in the [developer console](/developers/console/), or use an [OAuth app](/developers/concepts/oauth-apps) to act for other people; what each scope unlocks is on the [scopes page](/developers/concepts/scopes).

### Path parameters

- `boardId` (string, required)

### Headers

- `Idempotency-Key` (string): A unique key per logical request. Replays within 24 hours return the original response.

### Body

- `callbackUrl` (string): Optional. When the job this request starts finishes or fails, a short body is POSTed here once: `{ eventId, status, boardId, boardUrl, imageUrl }`, where status is `succeeded` or `failed` and imageUrl is a picture of what the job drew, or null. Signed with the workspace's callback secret (GET /webhooks/callback-secret). https to a public host. The full job is on GET /jobs/{jobId}.
- `target` (enum<string>): What to draw. One of `board`, `frame` or `item`. Defaults to `board`.
- `itemId` (string): The frame or item to draw. Required unless `target` is `board`.
- `scale` (enum<integer>): 2 doubles the pixels, for retina screens and print. One of `1` or `2`. Defaults to `1`.

### Response

- `id` (string)
- `kind` (enum<string>): One of `item.create`, `item.update`, `item.delete`, `item.batch`, `ai.generate`, `ai.modify`, `skill.apply` or `board.export`.
- `status` (enum<string>): One of `queued`, `running`, `succeeded` or `failed`.
- `progress` (integer)
- `message` (string): Human readable progress, for example "Placing kanban".
- `result` (object | null): - `itemIds` (string[])
  - `updated` (string[])
  - `deleted` (string[])
  - `creditsUsed` (integer)
  - `boardTitle` (string | null)
  - `skill` (string | null)
  - `convertedFrom` (string)
  - `sourceDeleted` (boolean)
  - `target` (enum<string>): board.export. What was drawn. One of `board`, `frame` or `item`.
  - `format` (enum<string>): board.export. One of `png`.
  - `scale` (enum<integer>): board.export. One of `1` or `2`.
  - `imageUrl` (string): board.export. The PNG. Anyone with this URL can open it.
  - `width` (integer): board.export. The image's width in pixels.
  - `height` (integer): board.export. The image's height in pixels.
- `error` (error): - `code` (enum<string>, required): One of `unauthorized`, `forbidden`, `not_found`, `validation_failed`, `conflict`, `plan_limit`, `rate_limited` or `internal`.
  - `message` (string, required)
  - `details` (object[])
  - `docsUrl` (string)
  - `upgradeUrl` (string)
- `createdAt` (string)
- `finishedAt` (string | null)
- `callbackUrl` (string | null): Where the job's result is POSTed
- `callback` (object | null): The newest delivery to callbackUrl, once the job has finished. Null until then, and when there is no callbackUrl.
    - `url` (string)
  - `deliveryId` (string)
  - `status` (enum<string>): One of `pending`, `retrying`, `succeeded`, `failed` or `cancelled`.
  - `attempts` (integer)
  - `responseStatus` (integer | null)
  - `error` (string | null)
  - `deliveredAt` (string | null)
  - `nextRetryAt` (string | null)

### Errors

- 429 `rate_limited`: Too many requests.
