# Public API

> Call FlashBoards from your own server with an API key to read your account, estimate costs and generate images and video.

Source: https://flashboards.yaroflasher.com/docs/integrations/api

Last verified: 2026-10-25 (checked against FlashBoards app build 1710ec2f754c)

The Public API v1 is a single JSON endpoint for your FlashBoards account, boards, model discovery and generation, called from your own server.

> **Note: Who can use it.** Any active FlashBoards account can create API keys in **Settings → Developer**. Operations can change, so treat discovery (below) as the source of truth. The API is server-only: it sends no CORS headers, and a key in browser code is a leaked key.

## Endpoint

| Setting | Value                                                                                    |
| ------- | ---------------------------------------------------------------------------------------- |
| Method  | `GET` and `POST`                                                                         |
| URL     | `https://flashboards.yaroflasher.com/api/v1/operations`                                  |
| Auth    | `Authorization: Bearer fb_sk_…` (API keys only; sign-in tokens and cookies are rejected) |

## Get a key

### Step 1: Open Developer settings

Open **Settings** (the person icon at the bottom right of the board) and select **Developer**.

### Step 2: Create a key

Under **API keys**, type a name in the **Key name** field (up to 60 characters, `default` if left empty) and click **New key**. A notice says "Copy your new key now. You won't be able to see it again." Click **Copy**, store the key somewhere safe, then click **Done**. Keys start with `fb_sk_`.

Each row shows the key name, a **full access** badge, its prefix (`fb_sk_` plus a few characters), creation date and last use (or **never used**). **Refresh** reloads the list.

* **Limit.** At most 25 active keys. Creating another fails with "You can have at most 25 active API keys. Revoke one first."
* **Expiry.** Keys don't expire. Revoke a key when you no longer need it.
* **Rate limits.** Creating and revoking keys and connected apps share a limit of 20 changes per minute.

### Revoke a key

Click the **Revoke API key** icon on a row, then **Revoke** in the **Revoke API key?** dialog. Revoking prevents new authenticated requests with that key and can't be undone. It does not cancel work already started. Reference preview links the key already shared stay viewable for up to 24 hours. Create a new key for any server that still needs access.

![Settings, Developer tab: Connect via MCP with the server URL, API keys with New key, and Connected apps](https://media.yaroflasher.com/docs/media/settings-developer.w1400.38ce464b.webp)

You don't need provider keys to generate; a FlashBoards key is enough.

## Call an operation

POST the operation name and its input. Operations without arguments need only the name.

```bash
curl -X POST https://flashboards.yaroflasher.com/api/v1/operations \
  -H "Authorization: Bearer ${FLASHBOARDS_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"operation":"get_account"}'
```

## Discover operations

`GET` the same URL (authenticated) for the current operations, each with a title, description, input JSON Schema and its `annotations` (for example `readOnlyHint` and `destructiveHint`).

The schemas are advisory: cross-field rules and count limits are enforced at parse time, so a schema-valid request can still be rejected. Many inputs are strict and reject unknown fields with `400 INVALID_INPUT`, so send only the fields the schema lists.

## Available operations

| Group                                                                                                               | Operations                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Account                                                                                                             | `get_account`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Shared boards (no tab needed)                                                                                       | `list_shared_boards`, `get_shared_board_snapshot` (read-only); `publish_board`, `unpublish_board`, `update_board_access` (owner only, with a confirm token; publishing also needs an open tab, and publishing, invites and widening to authenticated-link access need your approval there)                                                                                                                                                                                                                                                                       |
| Models and cost                                                                                                     | `list_generation_models`, `estimate_generation_cost`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| Generation                                                                                                          | `generate_image`, `generate_video`, `generate_audio` (speech and sound effects), `get_generation`, `list_recoverable_generations`                                                                                                                                                                                                                                                                                                                                                                                                                                |
| Audio, music and video models                                                                                       | `estimate_skill_model` quotes and `run_skill_model` starts music, stem separation, audio clean-up and analysis, voice design and video continuation models; poll with `get_generation`                                                                                                                                                                                                                                                                                                                                                                           |
| Voices                                                                                                              | `list_audio_voices`, `search_audio_voices`, `preview_audio_voice`, `save_audio_voice` (saves a voice-design preview), `create_audio_voice` (needs the speaker's consent), `delete_audio_voice` (deletes one of your own cloned or designed voices), `generate_voice_audio`, `change_voice_audio`, `estimate_audio_voice_cost`, `get_audio_voice_task`. Default and shared library voice IDs work directly with `generate_voice_audio` or `change_voice_audio`, without saving. Up to three slots for your own cloned or designed voices; library voices use none |
| Audio and video finishing (free; audio for any signed-in account, video needs an active plan or a positive balance) | `mix_audio_tracks`, `concat_audio_tracks`, `cut_audio_span`, `fit_audio_duration`, `add_audio_reverb`, `extract_video_audio`, `get_audio_finishing_task`; `trim_video`, `concat_videos`, `replace_video_audio`, `conform_video`, `detect_video_cuts`, `get_video_finishing_task`; `compare_video_detail`, `get_video_detail_comparison`                                                                                                                                                                                                                          |
| Headless image finishing                                                                                            | `arrange_images`, `crop_image`, `pad_image`; `extract_video_frame` takes a video instead. No open board needed. Free compute for any signed-in account, subject to rate limits.                                                                                                                                                                                                                                                                                                                                                                                  |
| Planning                                                                                                            | `plan_audio_timeline` (free, reads a word-timed transcript), `measure_music_beats`, `plan_music_montage` (free)                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Image and video enhancement                                                                                         | `list_media_enhancement_models`, `estimate_media_enhancement_cost`, `enhance_media`, `get_media_enhancement`                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Remote Board notes — internal pilot                                                                                 | `get_remote_board_notes` reads bounded notes; `create_remote_board_note` places one complete note. Eligible admin/tester owners of published, active realtime V2 boards only. See [availability and retry rules](https://flashboards.yaroflasher.com/docs/integrations/mcp.md#remote-board-notes-internal-pilot); this does not enable ordinary shared-board editing                                                                                                                                                                                                                                        |
| Video enhancement                                                                                                   | `estimate_video_enhancement` quotes and `enhance_video` starts a paid upscale of one MP4 or MOV source video: an AI chat attachment (up to 8 MiB), a media upload receipt (up to 100 MiB), or one of your own finished videos in `source` (up to 100 MiB), such as a trimmed or joined cut; poll with `get_generation`                                                                                                                                                                                                                                           |
| Media description and transcripts                                                                                   | `describe_media` and `transcribe_media` start a paid request; `get_media_description` and `get_media_transcript` read the result; `validate_chat_media` checks a file without uploading it or starting a paid action                                                                                                                                                                                                                                                                                                                                             |
| Shared-board media operations (limited rollout)                                                                     | `create_media_operation`, `get_media_operation`, `cancel_media_operation`, `retry_media_operation`                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| References                                                                                                          | `search_references`, `search_references_by_image`, `get_reference_preview`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Film frames (where enabled)                                                                                         | `search_movie_frames` finds real-film frames by text, a similar result or film/shot-term browsing; `get_movie_frame_preview` reads a returned `previewHandle`. Server availability and access checks apply                                                                                                                                                                                                                                                                                                                                                       |
| vidIQ research and packaging                                                                                        | `list_vidiq_research_tools` lists tools, inputs and prices for free; `vidiq_research` researches public videos and channels; `vidiq_packaging` generates or scores titles and scores a published video's thumbnail. Calls charge your balance when answered, except free `trend_categories` and cached research. Needs an active subscription or a positive balance without a payment issue; see [Research with vidIQ](https://flashboards.yaroflasher.com/docs/integrations/mcp.md#research-with-vidiq)                                                                                                    |
| Platform rules and draft checks                                                                                     | `get_platform_rules` reads dated platform rules and checks supplied clip facts; `get_draft_verdict` returns a rubric or a verdict from supplied scores. Free, read-only; a verdict is not a forecast of views                                                                                                                                                                                                                                                                                                                                                    |
| Music references (where available)                                                                                  | `search_music_artist`, `list_music_genre_artists`, `search_music_recordings`, `describe_music_style`, `describe_music_vibes` read MusicBrainz snapshot metadata and style descriptions, not generated audio. Results include a data licence                                                                                                                                                                                                                                                                                                                      |
| Video references                                                                                                    | `list_video_reference_categories`, `search_video_references`, `get_video_reference` (a playback link valid for 24 hours; anyone with it can play the clip)                                                                                                                                                                                                                                                                                                                                                                                                       |
| Guided workflows                                                                                                    | `list_skills`, `get_skill` (free, read-only)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Boards (need an open tab)                                                                                           | `prepare_board_generation`, `get_prepared_board_generation`, `generate_on_board`, `list_board_sessions`, `get_board_snapshot`, `export_board_image`, `add_media_to_board`, `execute_board_action`, `delete_board_items`, `undo_board_edit`                                                                                                                                                                                                                                                                                                                       |
| Reusable local tools (limited rollout)                                                                              | Through `execute_board_action` with `action: "extensionsRequest"`; discover contracts first. Live extension discovery needs a pilot account and eligible local-board tab; installation and invocation also need human plugin consent. See [Customization SDK](https://flashboards.yaroflasher.com/docs/integrations/sdk.md)                                                                                                                                                                                                                                                                                 |
| Board action schemas (no tab needed)                                                                                | `describe_board_action` returns the argument schema of one `execute_board_action` action (read-only)                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| Media tools                                                                                                         | `list_media_tools` lists the transforms (no tab needed); `start_media_tool`, `get_media_tool_run` and `cancel_media_tool_run` run them on board items (need an open tab)                                                                                                                                                                                                                                                                                                                                                                                         |

The MCP start menu (`flashboards`), chat upload tools (`create_upload_link`, `get_upload`, `import_chat_file`, `show_media_upload_picker`), chat viewers (`show_reference_gallery`, `display_generated_image`, `display_generation`) and social approval-card callback (`social_publish_card`) are MCP-only and aren't offered here. Discovery can include further operations for the account's available features; inspect it rather than treating this table as a fixed allowlist.

Board operations and media tool runs need an open, signed-in FlashBoards tab. Without one they return an error, and `list_board_sessions` returns an empty list.

## Run media tools

Media tools transform items in your open tab. Read `get_board_snapshot` for item IDs, then call `start_media_tool` with a tool ID from `list_media_tools`, `itemIds`, its `params`, the snapshot’s board ID as `expectedBoardId`, and a `requestId` (1–120 letters, digits, underscores or hyphens).

Retry only the identical request in the originating tab. Its ID returns the existing run while that record is retained: up to 30 minutes after completion, or less if newer runs fill the 50-run registry. Different input under a retained ID is refused. After reload, expiry, eviction or an uncertain result, inspect the board before starting again; reusing a forgotten ID can start another run.

* The call waits up to 10 seconds by default (`waitSeconds`). If the run is still going, poll `get_media_tool_run` with its `runId` until it succeeds, fails or is cancelled. Success lists the new item ids.
* Results are added to the board next to the sources. A cancelled run adds nothing.
* `engine: "auto"` (the default) and `"local"` run in the browser without uploading. Server-only tools require explicit `engine: "server"`: scene detection, collage, audio join, mix, reverb and soundtrack replacement. Read `list_media_tools` for the engines each tool accepts; server execution uploads the source media.
* Local-runner outputs are limited to 1 GB each and 2 GB per run; server tools have their own limits.
* A run lives in that tab. If the tab closes or reloads, the outcome is unknown: re-read the board before starting another run.

## Read the response

Every accepted call answers `200` with `{ ok, operation, result }`. `ok` is a transport-level flag, and business failures stay `200`, so `ok: true` doesn't always mean the work succeeded. For `generate_on_board`, always read `result.status`.

Transport problems use other status codes, with the body `{ "ok": false, "error": { "code": "...", "message": "..." } }`:

| Status | `error.code`             | Meaning                                                                                                                                                                                                   |
| ------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`  | `UNAUTHORIZED`           | Missing or invalid API key                                                                                                                                                                                |
| `415`  | `UNSUPPORTED_MEDIA_TYPE` | Content type isn't `application/json`                                                                                                                                                                     |
| `400`  | `INVALID_BODY`           | Body isn't valid JSON or is over the size limit                                                                                                                                                           |
| `400`  | `INVALID_REQUEST`        | Body isn't `{ "operation": "...", "input": {...} }`                                                                                                                                                       |
| `400`  | `UNKNOWN_OPERATION`      | No operation with that name; call `GET` for the list                                                                                                                                                      |
| `400`  | `INVALID_INPUT`          | Input doesn't match the operation's schema. The message describes the first validation issue, including its field path when available; `error.fields` lists up to 50 issues with a path, code and message |
| `429`  | `RATE_LIMITED`           | Too many requests. `error.retryAfter` and the `Retry-After` header give the wait in seconds                                                                                                               |
| `503`  | `SERVICE_UNAVAILABLE`    | Briefly unavailable; honor `Retry-After`                                                                                                                                                                  |
| `500`  | `INTERNAL`               | Unexpected failure                                                                                                                                                                                        |

* Methods other than `GET` and `POST` return `405`.
* The rate limit is 120 requests per minute per account, shared with MCP. Request bodies can be up to 11 MiB.

## Edit boards and share

The board and sharing operations follow the same rules as in MCP; see [Edit a board](https://flashboards.yaroflasher.com/docs/integrations/mcp.md#edit-a-board) and [Share and publish](https://flashboards.yaroflasher.com/docs/integrations/mcp.md#share-and-publish).

* **Edits.** Read `get_board_snapshot` first. `execute_board_action` takes an `action`, its `args` and `expectedBoardId` (the snapshot's `activeBoardId`), plus `sessionId` from `list_board_sessions` when more than one tab is live. `describe_board_action` returns the argument schema for one action and needs no tab.

```json
{"operation":"execute_board_action","input":{"action":"addTextNote","args":{"text":"Shot 1"},"expectedBoardId":"BOARD_ID","sessionId":"SESSION_ID"}}
```

* **Delete and undo.** Pass the snapshot's board id and `revision`:

```json
{"operation":"delete_board_items","input":{"expectedBoardId":"BOARD_ID","expectedRevision":"REVISION","itemIds":["ITEM_ID"]}}
```

Up to 50 ids per call, all or nothing. `undo_board_edit` reverts only edits made with the same API key.

* **Confirm tokens.** Sharing changes first return `status: "needs_confirmation"`, a preview and a single-use `confirmToken`, valid for 5 minutes. Repeat the same input with that token. Publishing, invitations and widening access to **Authenticated link** then require **Approve** in your open tab (`status: "awaiting_approval"`, with `approvalId`). Making access **Invite only**, revoking access and unpublishing can complete after the token confirmation without an open tab.
* **Errors.** A refused board or sharing call answers `200` with `ok: false` and a `result` that has `error`, `code` and `retryable`, plus `fields` (up to 50 entries, each with a path, code and message), `details` or `docsUrl` where useful. See [Errors](https://flashboards.yaroflasher.com/docs/integrations/mcp.md#errors). `TAB_OUTDATED` means the open tab is older than the operation: reload it and try again.

## Spend money safely

> **Warning: Retries can double-charge.** `generate_image` and `generate_video` require `generationAttemptId` (8 to 120 characters). Reuse it only for the exact same request; a new value starts a second paid attempt. Inspect an uncertain outcome before retrying.

* `enhance_video` also requires `generationAttemptId`. Reuse it only for the exact same source and settings.
* If a start returns `SUBMISSION_INDETERMINATE` (with `ok: false`), or `generate_on_board` returns `indeterminate_after_claim` (with `ok: true`), the attempt may already be charged. Do not retry.
* API keys have no spending ceiling: a leaked key can spend your balance until you revoke it. Revoke keys you no longer use.
* Some models and tools accept an optional per-request maximum, `maxCostUsd` (for example GPT Image 2.5, Nano Banana 2 Lite, H3 Max video, `generate_audio` and `enhance_media`). Requests estimated above it are rejected. Check each discovery schema.
* Audio, voice, finishing and enhancement operations also take a `requestId` or `generationAttemptId`. Reuse it only to retry the exact same request. Voice and finishing operations refuse a reused ID with different input.
* Call `estimate_generation_cost` to see the price first.
* A failed generation returns `code: "GENERATION_FAILED"`, `retryable: false`, `attemptClosed: true`, a `failureKind` (`content_policy`, `invalid_input`, `timeout`, `provider_error` or `unknown`) and a next step in `error`. Repeating that attempt only repeats the failure: fix the input and start a new attempt with a new `generationAttemptId`. `charged: false` appears only when FlashBoards confirmed the attempt wasn't charged.

## Use a local reference image

`generate_image` accepts one approved local image in `referenceImages` as a base64 data URL, with no board, open tab or upload step. The data URL can be up to 10 MiB and the request up to 11 MiB; base64 adds about a third, so keep originals well under that. Some models only accept image URLs, so check the model's discovery schema.

```json
{
  "operation": "generate_image",
  "input": {
    "prompt": "Describe the requested edit",
    "model": "nano-banana-2",
    "resolution": "1k",
    "generationAttemptId": "attempt-local-reference-1",
    "referenceImages": [
      { "filename": "reference.png", "dataUrl": "data:image/png;base64,..." }
    ]
  }
}
```

Send image bytes only after the user approved that attachment, and never a file path. `imageUrls` still works for URL-based references. For `generate_video`, compatible Seedance models accept one `referenceImages` attachment, or one `referencePreviewHandle` from a reference search, alongside supported `imageUrls`. Local video files can't be sent as references through the API. The voice operations take WAV bytes in `audioBase64`.

## Reuse your own results

Instead of a public URL, many inputs accept one of your completed results. FlashBoards checks that it's yours and reads it on the server.

* `generate_image`: `referenceGenerationIds` (your earlier image results) and `referencePreviewHandles` (from `search_references`) for image edit models that take references, up to 16 references in total for GPT Image 2.5.
* `generate_video`: an earlier image as the first frame (`firstFrameUrl`) or last frame (`endFrameUrl`, needs a first frame) of H3 Max and H3 Max Turbo, earlier images or reference previews as H3 Max references, earlier videos as H3 Max Reference to Video references (`referenceVideoGenerationIds`: a video `generationId` or the task ID of `conform_video`), earlier audio as an H3 Max Turbo soundtrack, and earlier images (`referenceGenerationIds`) and audio (`referenceAudioUrls`) as Seedance references.
* `run_skill_model`: an earlier audio result as the source of audio models, and an earlier video for video continuation.
* Finishing and voice operations: earlier generations, voice tasks and finishing results as sources, by ID. They never accept URLs. Video finishing results also return a video `generationId`, which works with `get_generation`, `describe_media`, `transcribe_media`, `add_media_to_board` and as a video source.
* `describe_media` and `transcribe_media`: `generationId`, `videoFinishingTaskId` or `mediaSource` read your own results on the server.

## Describe and transcribe media

Both operations bill your balance like a generation and work in two steps: start the request, then read the result. Each start takes a `requestId` you choose; reuse it only for the same request. A failed result is not proof that nothing was charged: an acknowledged response can be billed even when processing yields an empty or unusable result. Inspect the task's billing state and your history before starting again. Formats differ: for `describe_media` it is 1 to 128 characters from `A-Z a-z 0-9 . _ : -` and must start with a letter or digit; for `transcribe_media` it is 1 to 120 characters from `A-Z a-z 0-9 _ -` (no `.` or `:`).

| Operation          | Main input                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Read the result with    |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| `describe_media`   | `requestId` and exactly one source: `mediaDataUrl` (one image or video as a base64 data URL of type `image/jpeg`, `image/png`, `image/webp`, `video/mp4`, `video/quicktime` or `video/webm`; the media itself can be up to 8 MiB decoded, which is about 10.7 MiB as a data URL), `generationId` (one of your image or video results, with `outputIndex` for multi-output results), `videoFinishingTaskId`, or a `previewHandle` from `search_references` or `search_movie_frames`. Optional `prompt` (up to 1,000 characters): the task for a video, or a question to answer about an image | `get_media_description` |
| `transcribe_media` | `requestId` and either `mediaSource` (one of your own audio or video results, cut on the server to an optional `range` of up to 3 minutes) or `source` (`{ "id": "...", "kind": "audio" }` or `"kind": "video_audio"`, where `id` is 1 to 128 characters from `A-Z a-z 0-9 _ -`) with `audioBase64` (WAV bytes, up to 7 MiB and up to 180 seconds). Optional `range`, `model`, a two-letter `language` hint and up to 20 `phrases`                                                                                                                                                           | `get_media_transcript`  |

Describe also accepts optional `model`, `mode` and `sourceRange` (see the discovery schema for values). These three are video-only: an image request with any of them returns `INVALID_MEDIA_OPTIONS`. On your own result (`generationId`), `sourceRange` is cut out on the server. With `audioBase64`, transcription takes audio bytes, not a URL or file path, as uncompressed PCM or floating-point WAV, and a `range` doesn't cut the recording: slice the audio yourself so its length matches the range to within 0.05 seconds. With `mediaSource`, the server does the cutting.

For the in-app version, see [Describe and transcribe](https://flashboards.yaroflasher.com/docs/media/describe-and-transcribe.md).

## Recover a generation

`list_recoverable_generations` returns your recent recoverable generations from the last 48 hours with a fresh `generationId` for each. Pass one to `get_generation` for status. Listing never starts, refreshes or charges a generation.

## Search reference images

```json
{"operation":"search_references","input":{"query":"brutalist concrete museum at dusk","limit":12}}
```

`query` is 1 to 1,024 characters and `limit` is 1 to 100 (default 20). To search by image, `search_references_by_image` takes `imageBase64` (a JPEG, PNG or WebP, up to 327,680 decoded bytes) and a `limit` of 1 to 50 (default 20). Pass a result's `previewHandle` to `get_reference_preview` to download a preview. Handles are short-lived and tied to the creating key. A `previewUrl` is a temporary share link: anyone with it can open the preview for about 24 hours, without your key and even after you revoke it. Don't publish or store it.

## Export a board image

`export_board_image` renders a selection or the whole board to PNG from a live tab. Read `get_board_snapshot`, then pass `expectedBoardId` and `sessionId`.

```json
{"operation":"export_board_image","input":{"expectedBoardId":"BOARD_ID","sessionId":"SESSION_ID","scope":"board","scale":2,"background":"#ffffff"}}
```

Limits: 256 items, 8192 pixels per edge, 16 megapixels and 8 MiB PNG. Decode `result.base64` to save the file.

## Related

- [MCP server](https://flashboards.yaroflasher.com/docs/integrations/mcp.md)
- [Billing](https://flashboards.yaroflasher.com/docs/generation/billing.md)
- [Describe and transcribe](https://flashboards.yaroflasher.com/docs/media/describe-and-transcribe.md)
- [Settings](https://flashboards.yaroflasher.com/docs/account/settings.md)
