# Platform API (/docs/developers/platform-api)

Read your own Bloss data as a creator or coach, or your brand's data on the Scale plan, with the read-only Platform API.

The Platform API lets your own scripts and apps read Bloss data. It's read-only, so nothing can be changed, posted or paid through it. It has two parts:

- **Creator API**: everything a creator or a coach can read about their own work: your account, your creator profile and stats, the brands you create for, your videos, views, earnings and payouts, bounties, and your coaching workspace. It's free. You don't need a paid plan.
- **Brand API**: what a brand admin sees about a brand: its settings and team, creators, videos, analytics and campaign reach, and for full admins its pay data. It needs the brand to be on the **Scale** plan. See [Brand API](#brand-api).

## Quickstart [#quickstart]

<Steps>
<Step>

### Create a token [#create-a-token]

Go to <UiPath>Account › API tokens</UiPath>, click **Create token**, and tick the permissions you need. Copy the token: it starts with `blsp_` and is shown only once. See [API tokens](/docs/developers/api-tokens).

</Step>
<Step>

### Call the API [#call-the-api]

Start with `GET /me`. It returns who you are and every brand you belong to, with the ids the other endpoints take.

```bash
curl https://www.bloss.app/api/v1/me \
  -H "Authorization: Bearer $BLOSS_API_TOKEN"
```

```json
{
  "id": "…",
  "name": "Sam Rivera",
  "email": "sam@example.com",
  "creator": { "id": "…", "slug": "sam-rivera", "listingStatus": "public" },
  "coach": null,
  "brands": [
    {
      "id": "…",
      "name": "Glow Skincare",
      "slug": "glow",
      "adminTier": null,
      "creatorStatus": "active"
    }
  ]
}
```

`GET /me` needs the **Your account: name, email, roles and memberships** permission. For a brand you administer, `adminTier` is `"full"` or `"limited"`.

</Step>
<Step>

### Find the next endpoint [#find-the-next-endpoint]

Every endpoint, with its parameters and response fields, is in the [Platform API reference](/docs/developers/platform-api-reference). The same description is available as an OpenAPI 3.1 document at `https://www.bloss.app/api/v1/openapi.json`, which you can load into Postman, Insomnia or a code generator.

</Step>
</Steps>

## Basics [#basics]

| Item | Value |
| --- | --- |
| Base URL | `https://www.bloss.app/api/v1` |
| Authentication | `Authorization: Bearer blsp_…` (a personal token) on every request. `X-API-Key: blsp_…` works too. For the Brand API, a brand key (`blsk_…`) works in the same headers. |
| Methods | `GET` only. Any other method returns `405`. |
| Format | JSON. Responses aren't cached (`Cache-Control: no-store`). |
| Request id | Every response carries an `X-Request-Id` header. Quote it if you contact support. |

A token reads only what its permissions allow, and only data you can see in the app yourself. A brand you don't belong to, or a resource that isn't yours, answers `404`, exactly as if it didn't exist.

## Money data is opt-in [#money-data-is-opt-in]

Earnings, payouts and your payout setup sit behind a separate permission, **Your earnings, payouts and payout-account status**, marked **Money data** on the token page. A token without it can't read any amount you earned or were paid, and asking returns `403 insufficient_scope`.

Even with that permission, payout details are masked: you see where a brand pays you and whether your account there is set up, never a full email address or account number.

The Brand API works the same way: a brand's pay rules, payouts, spend, funds and subscription each need a permission marked **Money data**. See [Who can read what](#who-can-read-what).

## Brand API [#brand-api]

The Brand API reads a brand the way its admins see it in Bloss. Use it to pull campaign numbers into a client report, keep a dashboard in sync, or let an AI agent answer questions about your program.

It's included in the **Scale** plan. See [Plans and features](/docs/agencies/plans-and-features). The Creator API doesn't depend on any plan.

### What you can read [#what-you-can-read]

| Area | What you can read | Permissions |
| --- | --- | --- |
| Brand | Settings as <UiPath>Settings</UiPath> shows them (time zone, posting cadence, trial, features), the team and open admin invitations, invite links, recruitment applications, support tickets, and the brand's API keys and webhooks (never the key or the full webhook URL). | **Brand settings, members and invitations**, **Recruitment submissions**, **Support tickets**, **API keys (metadata only) and webhooks** |
| Creators | The roster, each creator's profile, open account alerts, views per day, account analytics, posting compliance and violations, your reviews, trial progress, creator groups, bounties and their claims, and Streak Survivor games. | **The brand's creators and their profiles**, **Bounties, claims and games** |
| Videos and analytics | Videos as the <Term id="video-vault">Video Vault</Term> lists them, <Term id="set">sets</Term> with their videos, tags with their stats, videos tracked by URL, <Term id="cycle">payout cycles</Term>, campaign reach (total, by day and by tag), and the videos behind one day of the analytics chart. | **The brand's videos, sets and tags**, **The brand's analytics and exports** |
| Money | Pay rules and the payout provider, payout cycles with their totals, each creator's payouts in a cycle, a creator's pay deal and payout history, the Base pay queue, a cycle's Bonus pay board, referral payouts, the funds balance, campaign spend and budget, and the brand's subscription. | **Payout settings, cycles and payouts**, **Funds balance and ledger**, **Subscription state** (all **Money data**) |

The API calls a set a "pair" in a few places, for example in field descriptions. It's the same thing. Every endpoint in each area is in the [Platform API reference](/docs/developers/platform-api-reference).

### Who can read what [#who-can-read-what]

| Who | Brand, creators, videos and analytics | Money | Subscription |
| --- | :---: | :---: | :---: |
| Full admin | ✓ | ✓ | |
| Limited admin | ✓ | | |
| Agency owner | ✓ | ✓ | ✓ |
| Brand key | ✓ | ✓ | |

- **Money data needs a full admin.** A limited admin who asks for pay data gets `403 forbidden`, even if the token has the money permissions. Agency owners and agency admins are full admins of every brand in the agency. See [Full vs limited admins](/docs/brands/full-vs-limited-admins).
- **The subscription is the agency owner's.** As in the app, where billing is owner-only, everyone else gets `403 forbidden`, brand keys included.
- **The brand must be on Scale.** Otherwise every Brand API endpoint answers `403 plan_required`, with `details.requiredPlan` set to `"scale"`. The agency owner changes the brand's plan in [agency billing](/docs/agencies/billing).
- **Access follows the app.** Each request checks your access to the brand again, so a token stops reading a brand the moment you leave it or lose admin access.

Pay rules aren't part of the brand's settings in the API: base pay, bonus tiers and the payout model are on the money side, behind **Payout settings, cycles and payouts**.

### Personal tokens and brand keys [#personal-tokens-and-brand-keys]

You can read the Brand API with either kind of credential.

| | Personal token | Brand key |
| --- | --- | --- |
| Starts with | `blsp_` | `blsk_` |
| Belongs to | You | The brand |
| Reads | Every brand you administer (or only the ones you picked with **Only these brands**), plus your own data on the Creator API | Its own brand, on the Brand API only |
| Acts as | You, with your own admin access, full or limited | A full admin of its brand |
| Stops working when | You revoke it, it expires, or you lose admin access | It's revoked or it expires |
| Create it in | <UiPath>Account › API tokens</UiPath>, under **Brand (Scale plan)** | <UiPath>Settings › Integrations › API Keys</UiPath> (full admins) |

Use a **personal token** for your own scripts and AI agents, or when you work across several brands. Use a **brand key** for an integration that should keep running when people join or leave the team, such as a client dashboard. See [Brand keys](/docs/developers/api-tokens#brand-keys).

A brand key asked about another brand answers `404`. It can't call the Creator API or `GET /me`: those answer `403 forbidden`. Older keys marked **Campaign API (v0) only** don't work on the Brand API at all (`401`); create a new key for it.

Every Brand API path takes the brand's id. Find it under <UiPath>Settings › Integrations › API Keys</UiPath>, next to **Brand ID**, with a copy button. A personal token can also read it from `GET /me`.

### Examples [#examples]

List the brand's payout cycles. Cycle days are `YYYY-MM-DD` in the brand's time zone, and `current` marks the cycle today falls in.

```bash
curl https://www.bloss.app/api/v1/brands/$BRAND_ID/cycles \
  -H "Authorization: Bearer $BLOSS_API_TOKEN"
```

```json
{
  "data": [
    {
      "cycleId": "cyc_oct",
      "startDate": "2026-10-01",
      "endDate": "2026-10-31",
      "status": "pending",
      "current": true
    },
    {
      "cycleId": "cyc_sep",
      "startDate": "2026-09-01",
      "endDate": "2026-09-30",
      "status": "paid",
      "current": false
    }
  ]
}
```

A campaign is the cycles you pass in `cycleIds`. Get its reach, the videos and views, with a breakdown per cycle:

```bash
curl "https://www.bloss.app/api/v1/brands/$BRAND_ID/campaign/summary?cycleIds=cyc_sep,cyc_oct" \
  -H "Authorization: Bearer $BLOSS_API_TOKEN"
```

```json
{
  "metrics": { "totalVideos": 412, "totalViews": 3180450 },
  "cycles": [
    {
      "cycleId": "cyc_sep",
      "startDate": "2026-09-01",
      "endDate": "2026-09-30",
      "status": "paid",
      "videos": 236,
      "views": 2011300
    },
    {
      "cycleId": "cyc_oct",
      "startDate": "2026-10-01",
      "endDate": "2026-10-31",
      "status": "pending",
      "videos": 176,
      "views": 1169150
    }
  ]
}
```

Get what the same campaign cost, against a prepaid budget of 5,000 US dollars, with spend and CPM per tag. This needs a full admin and the **Payout settings, cycles and payouts** permission:

```bash
curl "https://www.bloss.app/api/v1/brands/$BRAND_ID/campaign/spend?cycleIds=cyc_sep,cyc_oct&prepayment=5000&breakdown=tag" \
  -H "Authorization: Bearer $BLOSS_API_TOKEN"
```

Spend is <Term id="base-pay">base pay</Term> plus the <Term id="cpm">CPM</Term> <Term id="bonus">bonus</Term>, in US dollars. With `prepayment`, the response adds what remains, the share of the budget used, and `atThreshold` once spend reaches `thresholdPct` of it (70% by default). `breakdown=day` gives spend per day instead.

### Compared with the Campaign API (v0) [#compared-with-the-campaign-api-v0]

The [Campaign API](/docs/developers/api-reference) reads the same campaign data, and the Brand API's campaign endpoints count the same videos and views for the same cycles. Your existing Campaign API integrations keep working. If you move one to the Brand API, these are the differences:

| | Campaign API (v0) | Brand API (v1) |
| --- | --- | --- |
| Base URL | `https://www.bloss.app/api/v0` | `https://www.bloss.app/api/v1/brands/{brandId}` |
| Credential | A brand key | A brand key or a personal token |
| Reach and spend | Together: summary, daily and tag figures include spend | Split: `/campaign/summary`, `/campaign/daily` and `/campaign/tags` have reach only; spend and budget are on `/campaign/spend`, with `breakdown=tag` or `breakdown=day` |
| Who sees spend | Anyone holding the key | Full admins, with **Payout settings, cycles and payouts** |
| Cycle dates | `startDate` and `endDate` as UTC timestamps | `startDate` and `endDate` as `YYYY-MM-DD` days in the brand's time zone |
| Sets | `GET /campaign/pairs` | `GET /sets` |
| Creator groups | `GET /groups` | `GET /creator-groups` |
| Beyond campaigns | — | Creators, videos, tags, payouts, settings and more |

Filters work as before: `cycleIds` makes up the campaign, and `tagIds` and `groupIds` narrow it.

## Responses [#responses]

A successful response is the resource itself, as JSON. There's no wrapper around single resources.

Lists that can grow long are paginated and look like this:

```json
{
  "data": [{ "id": "…" }, { "id": "…" }],
  "nextCursor": "WzE3NjA…"
}
```

### Pagination [#pagination]

| Query parameter | Meaning |
| --- | --- |
| `limit` | Page size, 1–100. Default 50. |
| `cursor` | The `nextCursor` from the previous page. Leave it out for the first page. |

`nextCursor` is `null` on the last page. Cursors are opaque: pass them back unchanged. Pages don't shift when new rows appear while you're paging. A cursor that's been edited, or that came from a different endpoint, returns `400 validation_failed`.

### Dates and times [#dates-and-times]

- **Calendar days** are `YYYY-MM-DD` strings. For a brand's data, a day is a day in the brand's time zone, and responses that group by day include the `timeZone` they used. Your stats across all brands use UTC days.
- **Instants** (when a video was posted, when a payout was made) are ISO 8601 timestamps in UTC, for example `2026-10-22T14:05:00.000Z`.
- Date ranges take `from` and `to`, both inclusive. Unless an endpoint says otherwise, `to` defaults to today and `from` to 30 days before it.

## Errors [#errors]

Every error has the same shape:

```json
{
  "error": {
    "code": "insufficient_scope",
    "message": "This token needs the creator:earnings permission.",
    "details": { "requiredScope": "creator:earnings" },
    "requestId": "6f1c…"
  }
}
```

Branch on `code`, which never changes. `message` is for people and may be reworded. `details` is there only when it helps, for example the parameters that failed validation.

| Status | `code` | Meaning | What to do |
| --- | --- | --- | --- |
| `400` | `validation_failed` | A parameter is missing or invalid. `details` lists each problem. | Fix the request. |
| `401` | `unauthorized` | The token is missing, invalid, expired or revoked. | Check the header, or create a new token. |
| `403` | `insufficient_scope` | The token lacks the permission this endpoint needs. `details.requiredScope` names it. | Create a token with that permission. |
| `403` | `forbidden` | You can't read this: cross-brand stats with a token limited to some brands, pay data as a limited admin, the subscription as anyone but the agency owner, or the Creator API with a brand key. | Read the message. |
| `403` | `plan_required` | The brand isn't on the Scale plan, which the Brand API needs. | The agency owner can change the brand's plan. |
| `403` | `api_suspended` | API access is suspended for your account or for this brand. | Contact support. |
| `404` | `not_found` | The endpoint or resource doesn't exist, or isn't yours. | Check the ids. Look them up with `GET /me`. |
| `405` | `method_not_allowed` | The API is read-only. Only `GET` works. | Use `GET`. |
| `429` | `rate_limited` | Too many requests. | Wait for `Retry-After` seconds, then retry. |
| `500` | `internal_error` | Something went wrong on the Bloss side. | Retry with backoff. Quote `requestId` if it persists. |
| `503` | `api_disabled` | The API is temporarily unavailable. | Retry later. |

## Rate limits [#rate-limits]

By default the Creator API allows 60 requests a minute and the Brand API 300.

- **Personal tokens** are counted **per user, across all your tokens**, so creating more tokens doesn't give you more requests. The Creator API and the Brand API each have their own count.
- **Brand keys** are counted per key.

Every response that counts toward the limit carries:

| Header | Meaning |
| --- | --- |
| `X-RateLimit-Limit` | Requests allowed in the current window. |
| `X-RateLimit-Remaining` | Requests left in it. |
| `X-RateLimit-Reset` | When the window resets, in Unix seconds. |

Over the limit, you get `429 rate_limited` with a `Retry-After` header in seconds. Wait that long before you retry, and spread out or batch your calls.

## Keep tokens safe [#keep-tokens-safe]

A token reads your earnings, videos and brands as you, and a brand key reads its brand as a full admin. Keep both out of front-end code, mobile apps, screenshots and public repositories. If one leaks, [revoke it](/docs/developers/api-tokens#revoke-a-token) right away.

## Related [#related]

- [API tokens](/docs/developers/api-tokens): create, limit and revoke tokens and brand keys.
- [AI agents (MCP)](/docs/developers/mcp): let Claude, Cursor and other agents read your data.
- [Use your brand's data with AI agents](/docs/brands/settings/api-and-ai-agents): the Brand API for brand admins.
- [Platform API reference](/docs/developers/platform-api-reference): every endpoint.
- [Campaign API reference](/docs/developers/api-reference): the earlier, campaign-only API.
