Paths are relative to https://tarkle.com/api/v1. Every call sends your API key as Authorization: Bearer <your-tarkle-key>. A call that works inside a workspace also sends X-Workspace-Key: <workspace-key>, the 8-character key of that workspace, which GET /workspaces lists. Only GET /workspaces and POST /brand-lookup work without it. To create a key, see Authentication. The exact request and response schemas are in openapi.json.
curl -H "Authorization: Bearer $TARKLE_KEY" -H "X-Workspace-Key: $WORKSPACE_KEY" "https://tarkle.com/api/v1/brands?limit=10"What the key can do here
A key acts as the person who created it, with that person’s access in each workspace it reaches. Brand calls need that person to be an owner or admin of the workspace. Otherwise the answer is 403 forbidden. A key limited to chosen workspaces answers 403 no_access for any other workspace.
Keys have no scope picker: a key holds every scope except the one for purchases. The Needs column names the scope each call checks, so you can match it to an error. Brand calls allow 120 requests a minute for each key.
Calls
| Call | Needs | What it does |
|---|---|---|
GET /brands |
brands:read |
The workspace’s brands, newest first. limit (1 to 100, default 25) and cursor. |
GET /brands/{brand} |
brands:read |
One brand in full. |
POST /brands |
brands:create |
Create a brand. It is always a private draft. See Create, archive and restore brands. |
PATCH /brands/{brand} |
brands:write |
Change the fields you send. The slug, passwords and domains cannot be changed here. See Update a brand. |
DELETE /brands/{brand} |
brands:create |
Archive the brand. Needs confirm_delete: true. |
GET /archived-brands |
brands:create |
The archived brands, newest first. They never expire. |
POST /archived-brands/{brand}/restore |
brands:create |
See Create, archive and restore brands. |
GET, PUT, DELETE /brands/{brand}/domain |
brands:domains |
See Brand domains. |
GET /brands/{brand}/assets |
brands:read |
Logos, icon, banner and collection files with download links. |
GET /brands/{brand}/markdown |
brands:read |
The brand as brand.md (text/markdown). |
GET /brands/{brand}/analytics |
brands:read |
Views, downloads and requests. period is 30d (default), 90d or all. |
POST /brands/{brand}/files |
brands:files |
Start an upload of one brand file. See Upload brand files. |
POST /brands/{brand}/files/import |
brands:files |
Fetch a picture from a public web address and attach it, in one call. |
POST /brands/{brand}/files/{file}/complete |
brands:files |
Check the uploaded file and attach it. |
DELETE /brands/{brand}/files |
brands:files |
Take one file off the brand, named by slot in the query. |
GET /brands/{brand}/requests |
brands:requests |
Download and view requests. status, limit, cursor. |
POST /brands/{brand}/requests/{request} |
brands:requests |
Approve or reject one request. See Access requests. |
POST /brand-lookup |
brands:read |
Suggestions for a brand from a website address. Saves nothing and needs no workspace. |
Create a brand
POST /brands needs name, summary and industry. access, is_draft and confirm_public are refused on create, because a new brand is always a private draft.
Send password to protect the brand from the start. It must be at least 8 characters and at most 72 bytes. Only a hash of it is stored. The password is for the API only: the MCP server does not set one when it creates a brand. The slug defaults to the name. At the plan’s brand page limit the call answers 403 forbidden, and a slug the workspace already uses answers 409 name_taken.
Archive and restore
DELETE /brands/{brand} archives the brand. The API never deletes a brand for good. The brand’s page goes offline and answers 404, the app stops listing it, and its slug and its place under the plan’s brand page limit are freed. Its domains are detached and are not restored. Its files and settings are kept, and nothing removes them, so the brand can always be restored. The call answers with archived: true and the archived brand’s id, slug, name, archived_at and domains.
POST /archived-brands/{brand}/restore puts one back with its id, where {brand} is that id (a uuid, or the call answers 400). The plan’s brand page limit applies as it does on create, so the call answers 403 forbidden at the limit. If the old slug is taken now, send another slug in the body, otherwise the answer is 409 name_taken. Domains are not restored; connect them again with Brand domains. The call returns the restored brand in full.
The list response
GET /brands returns data (an array) and next_cursor. Each item has id, slug, name, summary, access, is_draft, download_approval, indexable, created_at and urls (the public page address and the api address). See Paging and limits.
Fields of a brand
GET /brands/{brand} returns these fields.
| Field | Contents |
|---|---|
id, slug, name |
The identifiers and the name. |
summary, story |
Short description and longer story. |
industry, size, company_type, year_founded |
Company facts. |
website |
The brand’s website address. |
social |
twitter, facebook, instagram, linkedin, youtube and github links. |
colors |
primary and secondary (or null) and additional (a list of name and value). |
fonts |
headline and body, each with name, custom and source (google, adobe or custom), and css for an Adobe font. |
print_values |
The CMYK and Pantone values of each color. |
auto_logo_variants |
Whether black and white logo downloads are made automatically. |
access |
public, password or restricted. |
is_draft, download_approval |
Whether the brand is a draft, and whether downloads need approval. |
indexable |
True when the page is public and not a draft. |
tracking |
ga4, gtm, search_console and adobe_kit IDs. |
seo |
title and description, each null when not set. |
team |
A title and a list of members with id, name, title and has_photo. |
press |
Links with id, title, url, description, image and source. |
guidelines |
Sections with id, title, text and images (each with id, kind and caption). |
urls |
page, markdown, mark_usage and api addresses. |
created_at |
When the brand was created. |
Files
A brand’s files can be read in two ways: from the Assets call of this API, or from the file links in the brand’s own markdown. Both cover the icon, the logos and the collection files.
Upload and remove files
Start an upload with POST /brands/{brand}/files, send the file to the address it returns, then call POST /brands/{brand}/files/{file}/complete. For a picture that is already on the web, POST /brands/{brand}/files/import does both steps in one call. See Upload brand files and Update a brand.
The slot is one of icon, main_logo, banner, social_image, favicon, logo, asset, team_photo or guideline_image. Logos and collection files need id (from GET /brands/{brand}/assets), team photos need member_id or member_name, and guideline images need section_id and id. The stored file is deleted too unless something of the brand still uses it.
Through the API: GET /brands/{brand}/assets
GET /brands/{brand}/assets returns brand (id, slug), then images and collections.
imageslists the icon, main logo and banner that are set, each with aroleoficon,main_logoorbanner.collectionslists each collection withid,name,descriptionandfiles.
Download links expire. The response carries links_expire: true, so list again when you need a fresh link.
Through the file links in brand.md
Each file in a public brand’s markdown page links to /api/brand-asset?brand=<id>&file=<key> on the host the page is served from.
/api/brand-asset answers only when all of these are true:
- the brand is public, is not a draft and does not need download approval;
- the file is one of that brand’s own icon, logos, collection files, guideline images or older images (when none of its collections has files).
It does not serve the banner, the social image, the favicon, the font files, the team photos or any other file of the brand. When all checks pass, the link redirects with 302 to a signed link. That signed link is valid for 7 days. A visitor address can make 300 of these requests an hour for each brand, and above that limit the answer is 429, with a Retry-After header of 3600 seconds.
GET /brands/{brand}/markdown returns the same brand.md text without the file links. Use GET /brands/{brand}/assets when you need the files themselves.
Analytics
The series is built from the 2,000 most recent rows of each number, so for a very busy brand it can add up to less than its total. downloaded_files holds top_assets, formats and unrecorded for the downloads in the period. It is null when that data is not available.