The Braandly public API is a REST API for reading and writing your workspace data and browsing the public design catalog. This guide covers how to authenticate, what the API exposes, and the shapes of requests and responses. For the full, always-current list of endpoints, use the developer portal linked at the end.
Base URL
https://api.braandly.com/api/v1/public
Every response includes an API-Version header (currently v1). The unversioned https://api.braandly.com/api/public path is a live alias of the same API.
Authenticate
Send your API key in the ApiKey header on every authenticated request.
ApiKey: bk_your_api_key_here
You create and manage keys in the app. See Create and manage Braandly API keys. Public catalog reads (brands, palettes, fonts, gradients) work without a key.
For an app that acts on another user's behalf, Braandly also supports OAuth 2.1, where the user signs in and authorizes your app instead of handing over a key. The same scopes and roles apply. This is the path the MCP server uses for connector-directory clients. See Guide to Model Context Protocol (MCP) in Braandly.
Scopes and roles
Each key carries scopes that decide what it can read and write, like read:tasks or write:brands. Two rules apply on top of scopes:
- The key owner must be a member of the workspace the request touches.
- A guest is read-only. Creating or changing data needs a workspace role of member or higher, plus the matching
write:scope.
A request that fails either rule returns 403.
What the API exposes
| Resource | Read | Write | Notes |
|---|---|---|---|
| Workspaces | Yes | Yes | Workspaces you belong to |
| Members | Yes | No | List a workspace's members |
| Projects | Yes | Yes | Scoped to a workspace, including sections and project members |
| Tasks | Yes | Yes | Per workspace or per project, including tags and subtasks |
| Comments | Yes | Yes | On tasks, projects, brands, and other resources |
| Docs | Yes | Yes | Workspace docs and personal docs |
| Brand guidelines | Yes | Yes | Per workspace, including status changes |
| Brand identity | Yes | Yes | A brand's identity by slug |
| Workspace brands | Yes | Yes | Create, update, archive, set visibility |
| Brinks | Yes | Yes | Your link-in-bio pages, including content blocks |
| Catalog: palettes, fonts, gradients | Yes | Like / save | Public to read; saving to a workspace needs a key |
| Catalog: brands | Yes | No | Public brand directory |
| User assets | Yes | No | Assets you have saved across workspaces |
Requests and responses
Response envelope
Every response uses the same shape.
{
"success": true,
"message": "Tasks retrieved",
"data": {}
}
On an error, success is false, message describes the problem, and data is null.
Pagination
List endpoints return a paginated data object.
{
"success": true,
"message": "Items retrieved",
"data": {
"current_page": 1,
"per_page": 20,
"total_result": 125,
"total_pages": 7,
"has_next_page": true,
"next_page": { "page": 2, "per_page": 20 },
"previous_page": null,
"data": []
}
}
List responses are slim. To keep them light, each item leaves out large nested fields (for example a doc's content, a guideline's blocks, a project's sections, or a task's subtasks). Fetch a single resource to get the full body, or add ?expand=full to the list request.
Status codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Created |
204 | Deleted, no content |
400 | Bad request, such as a validation error |
401 | Missing, expired, or invalid key |
403 | Valid key, but not allowed (scope, role, or not a member) |
404 | Not found |
429 | Rate limit exceeded |
500 | Server error |
Rate limits
Authenticated requests are limited per key in a rolling 15-minute window, and the allowance scales with your plan. See the limits table in Create and manage Braandly API keys. Public catalog reads, which need no key, are limited per IP instead. Going over either limit returns 429.
Quickstart
Read the public palette catalog with no key:
curl "https://api.braandly.com/api/v1/public/palettes?per_page=5"
List the workspaces your key can reach:
curl "https://api.braandly.com/api/v1/public/workspaces" \
-H "ApiKey: bk_your_api_key_here"
The same call in JavaScript:
const res = await fetch(
"https://api.braandly.com/api/v1/public/workspaces",
{ headers: { ApiKey: "bk_your_api_key_here" } }
);
const body = await res.json();
console.log(body.data);
Generate a typed client
The API publishes an OpenAPI spec, so you can generate types or a full SDK instead of writing requests by hand.
npx openapi-typescript https://api.braandly.com/api/v1/public/openapi.yaml -o braandly-api.d.ts
To scaffold a full client library in your language, point an OpenAPI generator at the same spec:
npx @openapitools/openapi-generator-cli generate \
-i https://api.braandly.com/api/v1/public/openapi.yaml \
-g typescript-fetch -o ./braandly-sdk
The full endpoint reference, with every path, parameter, and example, lives at braandly.com/developers. It is generated from the OpenAPI spec, so it is always current. Use it as the source of truth when this guide and the spec differ.
Get help
For API questions, contact api-support@braandly.com.