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

# Migrate to the Brands API

> Move creation, polling, export, and deletion from the Brand Skills beta to the generally available Brands API.

Move new creation requests to `POST /brands` using your existing API key
and base URL, `https://www.rainbrand.com/api/v1`. Both APIs remain available
during migration. Continue managing existing beta jobs through `/brand-skills`
until they have finished and you have stored or deleted their results.

Keep using `x-api-key`, or `Authorization: Bearer` instead—not both. Your billing
and commercial terms are unchanged by this migration.

## What changes

| Step | Brand Skills beta | Brands API |
| - | - | - |
| Create | `POST /brand-skills` | `POST /brands` |
| Save creation ID | Brand Skill ID and Brand ID | `data.id`, the Brand ID |
| Poll | `GET /brand-skills/{id}` | `GET /brands/{id}?wait=true` |
| In progress | `pending` or `processing` | `analyzing` |
| Successful | `completed` | `ready` |
| Failed | `failed` | `failed` |
| Download | ZIP included in completed response | Request and poll a separate export |
| Delete | `DELETE /brand-skills/{brand-skill-id}` | `DELETE /brands/{brand-id}` |

## Update creation and polling

Send your ordered `sources` and optional `instructions`. If you create brands
for multiple customers under one account, use `allowDuplicate: true` to skip
source-based duplicate detection when one customer's sources should not block
another customer's creation. This option does not create separate teams or
access boundaries.

Omit `workspaceId` if your old value is an arbitrary label rather than a real
Rainbrand team ID. Remove `brandName`; Rainbrand derives the name from the sources.
PDFs are supported on `/brands`.

Use a fresh `Idempotency-Key` for each new creation. Beta keys and IDs do not
transfer to the new flow.

```bash theme={null}
curl --request POST "https://www.rainbrand.com/api/v1/brands" \
  --header "x-api-key: $RAINBRAND_API_KEY" \
  --header "Idempotency-Key: $IDEMPOTENCY_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "sources": [
      { "kind": "website", "url": "https://acme.com" }
    ],
    "allowDuplicate": true
  }'
```

The response contains one ID to save:

```json theme={null}
{
  "data": {
    "id": "<brand-id>",
    "status": "analyzing"
  }
}
```

Call `GET /brands/{id}?wait=true` with that Brand ID. Repeat while the status is
`analyzing`; stop at `ready` or `failed`. A wait timeout does not stop creation.
See [Create a brand](https://docs.rainbrand.com/guides/create-brand) for source
examples and the [create](https://docs.rainbrand.com/api-reference/brands/create-a-brand)
and [get](https://docs.rainbrand.com/api-reference/brands/get-a-brand) references
for exact schemas. The example above skips duplicate detection; omit
`allowDuplicate` if you want the normal duplicate check.

## Export the ZIP separately

Once the brand is `ready`:

1. Call `POST /brands/{id}/exports` and save `data.skillId`.
2. Poll `GET /brands/{id}/exports/{skillId}` until `ready` or `failed`.
3. Download `data.download.url` from the ready export and store the complete
   folder with its relative paths intact.

The Brand ID identifies the brand; `skillId` identifies the exported version.
See [Export a Brand Skill](https://docs.rainbrand.com/guides/export-brand-skill)
for executable requests and download handling.

## Replace creation retry handling

Brand creation has no `failure.retryable` field. Use this mapping:

| Result | Action |
| - | - |
| HTTP `429` | Wait for `Retry-After` before retrying. |
| Uncertain POST result after a network error or HTTP `5xx` | Retry with the same idempotency key and body. |
| Brand ID already received | Poll that ID instead of creating again. |
| Terminal `failed` status | Read the failure code below; use a new key for the next attempt. |

Correct the source or input first for `INVALID_URL`, `UNSUPPORTED_SOURCE`,
`WEBSITE_SOURCE_REJECTED`, `PDF_SOURCE_REJECTED`, `SOURCE_REJECTED`,
`INSTAGRAM_PROFILE_NOT_FOUND`, or `INSTAGRAM_PRIVATE_PROFILE`.

Retry unchanged later for `SCRAPE_FAILED`, `INSTAGRAM_FETCH_FAILED`,
`PDF_PROCESSING_FAILED`, `BRAND_GUIDE_BUILD_FAILED`, or `INTERNAL_ERROR`.

Export failures retain their own `failure.retryable`: when true, repeat the
export POST. Do not recreate a ready brand because its export failed.

## Update deletion

Delete new brands with `DELETE /brands/{id}`, using the Brand ID saved at
creation. The deleted brand becomes unavailable. Continue deleting existing
beta jobs through `/brand-skills` with their beta IDs. See the
[delete reference](https://docs.rainbrand.com/api-reference/brands/delete-a-brand).

## Cutover checklist

1. Update request fields, saved IDs, polling, retry handling, export, and deletion.
2. Test a website and a PDF through `/brands`: create, poll, export, download,
   and validate the extracted Skill and assets.
3. Delete the test brands and confirm they are unavailable.
4. Switch new creates to `/brands`, using `allowDuplicate: true` where needed.
5. Keep polling and deleting existing beta IDs on `/brand-skills` until they
   have drained. Coordinate beta retirement with Rainbrand after cutover.

If you need separate Rainbrand teams for your customers, coordinate that
mapping with Rainbrand. It is separate from updating the API calls above.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.