> ## Documentation Index
> Fetch the complete documentation index at: https://www.trybloom.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Automation

> Wire Bloom into Zapier, n8n, Make, Gumloop, or any other workflow tool.

Integrate Bloom into your automation stack so your workflows can generate on-brand images on demand and drop them into the rest of your tools. Whether you're building in Zapier, n8n, Make, Gumloop, or anything else with an HTTP request step, the integration follows the same pattern below.

## What you need before you start

* A **Bloom API key**. [Create one](https://www.trybloom.ai/settings#api-keys) and keep it nearby — you'll paste it into your tool's credential vault. App integrations can use Bloom OAuth instead.
* A **brand session ID**. Every image you generate is scoped to a brand:
  * If you already have brands, hit `GET /brands` and copy any `id`.
  * If you don't, create one in the [Bloom app](https://www.trybloom.ai) by onboarding from a URL, or via `POST /brands` from your workflow.
* An **HTTP tool** in your workflow — every automation platform has one (sometimes called "HTTP request", "API call", or similar). That's the only primitive you need.

## The three-call pattern

```mermaid theme={null}
flowchart LR
  A["POST /images/generations<br/>(returns 202 + id)"] --> B["GET /images/{id}<br/>(block until ready)"] --> C["Use image.imageUrl<br/>(downstream action)"]
```

1. **Start a generation.** Returns `202 Accepted` immediately with an image ID — the actual generation runs in the background.
2. **Get the image.** Either pass `?wait=true` and let Bloom hold the connection open until it's ready, or poll on a short interval if your tool can't keep a connection alive.
3. **Use the URL.** The completed image's CDN URL is in the response — pipe it into Slack, a Google Sheet, Drive, Webflow, whatever.

## Authentication

For most automation tools, send your API key as the `x-api-key` header:

```http theme={null}
x-api-key: bloom_sk_...
```

Store the key once in your tool's credential vault and reference it as a variable in each step — don't paste it directly into the workflow JSON. (Zapier calls this an "auth connection", n8n calls them "credentials", Make calls them "connections", Gumloop calls them "secrets" — same primitive.)

The API also accepts `Authorization: Bearer bloom_sk_...` for API keys and `Authorization: Bearer <bloom_oauth_access_token>` for app integrations using Bloom OAuth access tokens.

## Step 1 — Start a generation

`POST https://www.trybloom.ai/api/v1/images/generations`

```json theme={null}
{
  "brandSessionId": "f7e319aa-2a7f-4f2a-853a-eb5a5798659e",
  "prompt": "Hero image for a spring product launch.",
  "aspectRatio": "16:9",
  "imageSize": "2K",
  "model": "pro"
}
```

**Required:** `brandSessionId`, `prompt`. Everything else is optional.

**Common optional fields:**

| Field               | Values                                                                  | Notes                                                                    |
| ------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `aspectRatio`       | `1:1`, `16:9`, `9:16`, `4:5`, `3:2`, `2:3`, `3:4`, `4:3`, `5:4`, `21:9` | Defaults to a Bloom-chosen ratio if omitted.                             |
| `imageSize`         | `2K`, `4K`                                                              | `2K` = 1 credit (default). `4K` = 2 credits (Plus/Pro plans).            |
| `model`             | `fast`, `standard`, `pro`                                               | `pro` is the default. `fast` is cheaper and quicker.                     |
| `variantCount`      | `1`–`5`                                                                 | One image by default. Each variant costs the same as one generation.     |
| `referenceImageIds` | array of image IDs                                                      | Use uploaded or previously generated images as style/content references. |

**Response (`202 Accepted`):**

```json theme={null}
{
  "data": {
    "imageIds": ["a1b2c3d4-..."],
    "creditsUsed": 1
  }
}
```

Store `data.imageIds[0]` — that's what the next step needs.

## Step 2 — Get the image

You have two ways to retrieve the finished image. Pick based on your tool's request timeout.

### Option A — `wait=true` (recommended)

`GET https://www.trybloom.ai/api/v1/images/{id}?wait=true`

Holds the connection open until the generation reaches a terminal state. One call, no polling loop, no scheduling. Returns the same shape whether the image was already done or just finished.

```bash theme={null}
curl "https://www.trybloom.ai/api/v1/images/a1b2c3d4-...?wait=true" \
  -H "x-api-key: $BLOOM_API_KEY"
```

Use this whenever the tool can keep an HTTP request alive long enough. Most generations complete in well under a minute.

### Option B — Polling

`GET https://www.trybloom.ai/api/v1/images/{id}`

If your tool has a hard per-step timeout (Zapier in particular), fire the GET on a loop with a short delay until `status` is terminal.

```
loop:
  GET /images/{id}
  if status == "completed" → break
  if status == "failed"    → break with error
  wait 3 seconds
end
```

Most workflow tools have a built-in "wait + retry" or "delay then continue" primitive — n8n's Wait node, Make's Sleep module, Gumloop's loop primitive. Zapier requires a multi-step zap with a Delay step.

## Step 3 — Use the URL

A completed image response includes the CDN URL inside the `data` envelope:

```json theme={null}
{
  "data": {
    "id": "a1b2c3d4-...",
    "status": "completed",
    "imageUrl": "https://storage.trybloom.ai/...",
    "aspectRatio": "16:9",
    "imageSize": "2K"
  }
}
```

Pull `data.imageUrl` and pipe it into whatever downstream step the workflow needs — upload to Drive, post to Slack, write into a Sheet cell, attach to an email.

## Batching

If you fire many generations at once (e.g. one per row in a spreadsheet), you don't have to poll each ID individually. The list endpoint accepts `ids=id1,id2,...&wait=true` and holds open until **every** referenced image reaches a terminal state. One call collects the whole batch.

```bash theme={null}
curl "https://www.trybloom.ai/api/v1/images?ids=id1,id2,id3&wait=true" \
  -H "x-api-key: $BLOOM_API_KEY"
```

## Errors

Failed responses use a consistent envelope:

```json theme={null}
{
  "error": {
    "code": "BRAND_NOT_FOUND",
    "status": 422,
    "message": "Brand session not found"
  }
}
```

Branch on `code`, not on `message`. Common codes you'll see while integrating:

| Code                         | Meaning                                                                                                                                           |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `UNAUTHORIZED` (401)         | Missing or invalid API key or OAuth access token.                                                                                                 |
| `BRAND_NOT_FOUND` (422)      | The `brandSessionId` doesn't exist or belongs to a different account.                                                                             |
| `INSUFFICIENT_CREDITS` (402) | Your workspace ran out of credits — top up at [trybloom.ai/#pricing](https://www.trybloom.ai/#pricing).                                           |
| `PAYMENT_REQUIRED` (402)     | Subscription paused (failed or pending payment). Blocks generation even with a positive credit balance — follow the `data.action_url` to resolve. |
| `TOO_MANY_REQUESTS` (429)    | Too many requests too fast — back off and retry.                                                                                                  |
