Chartlink Brands API

The Brands API from Chartlink — 10 operation(s) for brands.

Operations 14

GET /api/brands/schema Brand settings JSON Schema — the machine-readable truth for every setting #
GET /api/brands List brands: the workspace's own, then those shared with it (access: owner |… #
POST /api/brands Create a brand #
GET /api/brands/{idOrSlug} Get a brand by id or slug #
PATCH /api/brands/{idOrSlug} Update a brand (tokens and templates deep-merge; replace: true replaces them) #
DELETE /api/brands/{idOrSlug} Soft-delete a brand (assets fall back to the default brand) #
GET /api/brands/{idOrSlug}/guide Every brand setting by path — kind, range, default, what it also sets — and… #
POST /api/brands/{idOrSlug}/vet Check brand changes by path as the studio does — nothing is saved; PATCH the… #
POST /api/brands/{idOrSlug}/preview Draw one of the brand's example charts as a PNG — from the stored brand, or… #
POST /api/brands/{idOrSlug}/setup Set a brand up in one go from screenshots, words, a logo or a website: a strong… #
GET /api/brands/{idOrSlug}/shares Who this brand is shared with, and pending invitations (the owning workspace) #
POST /api/brands/{idOrSlug}/shares Share this brand with someone by email (owners of the brand's workspace). #
DELETE /api/brands/{idOrSlug}/shares/{shareId} End a share: the owner takes it back, or the receiving workspace lets it go #
DELETE /api/brands/{idOrSlug}/invites/{inviteId} Withdraw a pending brand invitation #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/chartlink-app:chartlink-app-brands-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

chartlink-app-brands-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: chartlink Brands API
  version: 0.1.0
  description: 'chartlink — a platform for charts and maps, made in your brand, with live-updating embed links. NOT CONNECTED YET? In an AI app that takes MCP connectors (Claude and others): your human adds https://chartlink.app/mcp as a

    connector, signs in and picks a workspace — no key, nothing pasted into the chat. In Claude Code or a script:

    an API key from their studio (Workspace → API keys for Claude Code and scripts), sent as Authorization: Bearer. Either way you work in their workspace — their brands and charts. Every chart carries urls.studio, where they

    fine-tune it. A share URL is one published chart. Credits are GET

    /api/billing-info and a checkout link from POST /api/checkout-link, which you hand to your human. WHAT AN ASSET IS

    CHART TYPES: line, bar, area, scatter, dumbbell, slope, heatmap, choropleth, symbol-map, pie, treemap, waterfall, candlestick

    (GET /api/asset-types describes each; GET /api/asset-types/{type}/schema is the contract — read it before the first create.)

    An asset = type + data + config (+ brand). data holds typed columns and row-arrays; config holds

    everything about presentation (title and the other text elements, encoding, chart options). They are updated independently:

    PUT /assets/{id}/data replaces the numbers; PATCH /assets/{id} deep-merges config. Never resend

    what you are not changing. There is no table type (removed): a ranking is a sorted "bar" chart with

    value labels, a row-by-row comparison a "dumbbell" (one point per row = a dot plot) with row labels. KICKER AND TITLE MARKER: kicker {text, font, align, box} is a short line above the title (a section or topic

    that ties charts together; default a small bold line in the emphasis colour). title.marker {position: "top" |

    "left" | "end" | "none", shape: "bar" | "dot" | "square", hang, color, length, thickness, gap} draws one mark

    above the title, beside it (a bar spans the title, a dot or square sits at its first line; hang: true puts it

    in the margin instead of pushing the text right) or after the last word ("end"; skipped when the title already

    ends in . ? ! … : ; so never type a mark into the title). gap is the space to the text everywhere. Both are

    brand-settable (kicker''s style, the marker); the kicker''s words are per chart. kicker.show: false (usually on

    a brand) hides kickers whatever their text; description.show: false does the same for descriptions. POINTS (line, area): chart.points is the one way to put dots on series — a list of rules {series?, at, label?,

    labelPosition?, align?, font?, fill?, ring?, radius?}. A label uses the brand''s data-label style; font overrides it

    key by key, and font.color "series" (here or in the brand''s data-label colour) takes the series'' colour. A note in

    words with the annotation look is an annotation, not a point label. at: "all" | "first" | "last" | "max" | "min" | [x values]. label fills in

    {value}, {series}, {x}: [{at: "max", label: "Peak {value}"}], [{at: [2008, 2020], label: "{x}"}]. markers

    ("none" | "end" | "all") is the end dot, the brand''s house style (default "end"): a chart''s own points are added to it,

    so set markers "none" to drop it; points: [] draws no points at all. LINE BREAKS: "

    " breaks a line in the words you write — title, kicker, description, source, annotations,

    reference-line and highlight labels, point labels, and series names in line/area end labels (which then take

    the room of their lines). A multi-line point label aligns by its side (centred above/below) unless

    points[].align says "left" | "center" | "right"; annotations and free text have align too. Legends and

    tooltips show a series name on one line. AXES: a value axis takes min/max, ticks {count | values: [0, 50, 100] — ticks and gridlines exactly there}, ticks.format,

    ticks.labels.text: the words at those values, one per value (["", "50", "100%"]; "" leaves a tick unlabelled, its

    gridline stays) — omit it for each value formatted.'
servers:
- url: https://chartlink.app
tags:
- name: Brands
paths:
  /api/brands/schema:
    get:
      operationId: getBrandTokensSchema
      summary: Brand settings JSON Schema — the machine-readable truth for every setting
      description: 'A brand is DEFAULT SETTINGS: the same shape as a chart''s config, minus the two things a brand cannot own — the words, and the type-specific chart options.'
      responses:
        '200':
          description: JSON Schema for brand settings
      tags:
      - Brands
  /api/brands:
    get:
      operationId: listBrands
      summary: 'List brands: the workspace''s own, then those shared with it (access: owner |…'
      responses:
        '200':
          description: Brands
      tags:
      - Brands
    post:
      operationId: createBrand
      summary: Create a brand
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                slug:
                  type: string
                  pattern: ^[a-z0-9-]+$
                  description: Stable handle agents pass as `brand`
                name:
                  type: string
                  minLength: 1
                tokens:
                  type: object
                  additionalProperties:
                    nullable: true
                  default: {}
                  description: Default settings for every chart using this brand — the same shape as a chart config, minus the words and the type-specific chart options — GET /brands/schema for the full shape. A chart's own config overrides these key by key.
                isDefault:
                  type: boolean
                  default: false
                  description: The workspace's default brand. A workspace's first brand is its default either way
                start:
                  type: string
                  enum:
                  - starter
                  - blank
                  - clean
                  - pop
                  - dark
                  - warm-serif
                  - swiss
                  - forest
                  - sunset
                  - newsroom
                  - midnight-serif
                  - vintage
                  - candy
                  - neon
                  - soft
                  - academic
                  - tropical
                  - mono
                  default: starter
                  description: 'Where a brand with no settings of its own begins: a starter look to change from there — "clean" (crisp sans on white), "pop" (sunflower yellow, black type, punchy colours), "dark" (deep navy canvas, bright data), "warm-serif" (heavy serif headlines on warm paper), "swiss" (heavy grotesque, black and red), "forest" (deep green canvas, warm serif), "sunset" (peach canvas, vivid warm colours), "newsroom" (bold condensed headlines, a red accent), "midnight-serif" (charcoal and gold, elegant serif), "vintage" (slab serif on cream, retro colours), "candy" (rounded type, bright candy colours), "neon" (black canvas, monospace, glowing colours), "soft" (rounded type, pastel colours), "academic" (book serif, quiet greys and one blue), "tropical" (deep teal canvas, tropical colours), "mono" (monospace, framed, technical); "starter" is "clean" (the default); "blank" is the engine''s bare defaults. GET /api/try/looks draws them. Ignored when tokens or templates are given'
                darkEnabled:
                  nullable: true
                  description: 'Removed (2026-10-27): a brand has one look — sending it is refused with what to do instead'
                dark:
                  nullable: true
                  description: 'Removed (2026-10-27): a brand has one look — sending it is refused with what to do instead'
                templates:
                  type: object
                  additionalProperties:
                    type: object
                    additionalProperties:
                      nullable: true
                  default: {}
                  description: 'Per starter template (bar, line, choropleth, …): settings charts from that template get over the brand — any key the chart type takes, style only.'
              required:
              - slug
              - name
      responses:
        '201':
          description: Created brand
      tags:
      - Brands
  /api/brands/{idOrSlug}:
    get:
      operationId: getBrand
      summary: Get a brand by id or slug
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      responses:
        '200':
          description: Brand
      tags:
      - Brands
    patch:
      operationId: updateBrand
      summary: 'Update a brand (tokens and templates deep-merge; replace: true replaces them)'
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                expectedVersion:
                  type: integer
                  minimum: 1
                name:
                  type: string
                tokens:
                  type: object
                  additionalProperties:
                    nullable: true
                templates:
                  type: object
                  additionalProperties:
                    type: object
                    additionalProperties:
                      nullable: true
                isDefault:
                  type: boolean
                dark:
                  nullable: true
                  description: 'Removed (2026-10-27): a brand has one look — sending it is refused with what to do instead'
                darkEnabled:
                  nullable: true
                  description: 'Removed (2026-10-27): a brand has one look — sending it is refused with what to do instead'
                changes:
                  type: array
                  items:
                    type: object
                    properties:
                      path:
                        type: string
                      value:
                        nullable: true
                    required:
                    - path
                  description: 'The changes setup or POST /brands/{slug}/vet returned, as they are: [{path, value}] — "family.<id>.…" a chart type, the rest the base; null removes. Instead of tokens/templates'
                replace:
                  type: boolean
                  default: false
                  description: 'true: tokens and templates REPLACE what is stored instead of deep-merging — how a key is removed.'
              required:
              - expectedVersion
      responses:
        '200':
          description: Updated brand
        '409':
          description: Version conflict
      tags:
      - Brands
    delete:
      operationId: deleteBrand
      summary: Soft-delete a brand (assets fall back to the default brand)
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      responses:
        '200':
          description: Deleted
      tags:
      - Brands
  /api/brands/{idOrSlug}/guide:
    get:
      operationId: brandGuide
      summary: Every brand setting by path — kind, range, default, what it also sets — and…
      description: 'The same catalogue the studio''s own AI works from. family= lists one chart type''s settings (family..… paths), family=all every type''s; without it, the base settings and the list of chart types. Change settings by path with POST /brands/{slug}/vet then PATCH with the vetted changes (MCP: edit_brand does both).'
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      - schema:
          type: string
        required: false
        name: family
        in: query
      responses:
        '200':
          description: The guide
      tags:
      - Brands
  /api/brands/{idOrSlug}/vet:
    post:
      operationId: vetBrandChanges
      summary: Check brand changes by path as the studio does — nothing is saved; PATCH the…
      description: 'Each change is checked against the settings guide: fonts against Google Fonts (and their weights), values against the setting''s kind, logos fetched from a public URL. Paths that also set others are expanded. Returns the changes to PATCH, what was applied, what was refused and why, and weights adjusted to ones the family ships.'
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                changes:
                  type: array
                  items:
                    type: object
                    properties:
                      path:
                        type: string
                      value:
                        nullable: true
                    required:
                    - path
                  minItems: 1
                  maxItems: 200
              required:
              - changes
      responses:
        '200':
          description: Vetted changes
      tags:
      - Brands
  /api/brands/{idOrSlug}/preview:
    post:
      operationId: previewBrandExample
      summary: Draw one of the brand's example charts as a PNG — from the stored brand, or…
      description: 'Examples: line-annotated, line-multi, line-highlight, line-projection, line-band, area-surplus, area-single, area-stacked, area-share, area-overlap, area-highlight, area-stream, bar-columns, bar-grouped, bar-ranked, bar-stacked, bar-share, bar-change, bar-pyramid, bar-histogram, scatter-all, scatter-plain, scatter-bubbles, scatter-emphasis, scatter-reference, scatter-connected, dumbbell-change, dumbbell-three, dot-plot, lollipop, map-world, map-europe, map-us-states, map-africa, map-us-counties, map-uk-houses, map-classes, map-labels, map-diverging, map-pins, map-symbols, slope-change, pie-donut, waterfall-steps, heatmap-grid, candle-daily. The same picture the studio shows; look at it before saving a brand.'
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                example:
                  type: string
                aspect:
                  type: string
                  enum:
                  - '2:1'
                  - '16:9'
                  - '3:2'
                  - '4:3'
                  - '1:1'
                  - '4:5'
                  - '3:4'
                  - '9:16'
                  default: '4:3'
                width:
                  type: integer
                  minimum: 320
                  maximum: 1600
                  default: 800
                tokens:
                  type: object
                  additionalProperties:
                    nullable: true
                templates:
                  type: object
                  additionalProperties:
                    type: object
                    additionalProperties:
                      nullable: true
                changes:
                  type: array
                  items:
                    type: object
                    properties:
                      path:
                        type: string
                      value:
                        nullable: true
                    required:
                    - path
                  description: 'Changes from setup or vet, laid over the settings above (or the stored brand): see them before PATCHing them'
              required:
              - example
      responses:
        '200':
          description: image/png
        '400':
          description: Unknown example or invalid settings
      tags:
      - Brands
  /api/brands/{idOrSlug}/setup:
    post:
      operationId: setupBrand
      summary: 'Set a brand up in one go from screenshots, words, a logo or a website: a strong…'
      description: 'Give any mix of: screenshots of anything (charts you like, your own old charts, a page, slides, a style guide; data: URLs, at most 6, ~1.5 MB each), text (instructions; they win when inputs disagree), a logo (data: URL) and a website (read for fonts, colours and a logo). A strong model works through every group of settings in order (Canvas, Colours, Layout, Kicker, Title, Title marker, Description, Axis labels, Unit labels, Grid, Data labels, Numbers, Legends, Annotations, Source, Brand, Bar charts, Line charts, Area charts, Slope charts, Pie and donut charts, Scatter plots, Dot and dumbbell charts, Waterfall charts, Candlestick charts, Heatmaps, Maps) and ends each with a decision, then renders examples, compares and fixes. It takes one to three minutes. Returns the {path, value} changes ("family.." family settings), a decision per group, what was refused and why, and a short reply. Nothing is saved: apply the changes and PATCH the brand when happy. 10 setups per workspace per day, within the monthly AI allowance.'
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                text:
                  type: string
                  maxLength: 8000
                  default: ''
                images:
                  type: array
                  items:
                    type: string
                    maxLength: 2000000
                  maxItems: 6
                  default: []
                url:
                  type: string
                  format: uri
                logo:
                  type: string
                  maxLength: 1000000
                measured:
                  type: string
                  maxLength: 1500
                  description: 'Colours measured from the screenshots'' pixels (the studio measures them): taken as exact'
                tokens:
                  type: object
                  additionalProperties:
                    nullable: true
                  description: The settings being edited (the unsaved draft); default the stored brand
                templates:
                  type: object
                  additionalProperties:
                    type: object
                    additionalProperties:
                      nullable: true
      responses:
        '200':
          description: Changes and decisions
        '400':
          description: Nothing given
        '403':
          description: View-only brand
        '429':
          description: Daily limit or AI allowance
        '503':
          description: AI not set up
      tags:
      - Brands
  /api/brands/{idOrSlug}/shares:
    get:
      operationId: listBrandShares
      summary: Who this brand is shared with, and pending invitations (the owning workspace)
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      responses:
        '200':
          description: Shares
      tags:
      - Brands
    post:
      operationId: shareBrand
      summary: Share this brand with someone by email (owners of the brand's workspace).
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  format: email
                role:
                  type: string
                  enum:
                  - editor
                  - viewer
                  default: viewer
              required:
              - email
      responses:
        '201':
          description: 'Invited: the link, and whether it was emailed'
      tags:
      - Brands
  /api/brands/{idOrSlug}/shares/{shareId}:
    delete:
      operationId: unshareBrand
      summary: 'End a share: the owner takes it back, or the receiving workspace lets it go'
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      - schema:
          type: string
        required: true
        name: shareId
        in: path
      responses:
        '200':
          description: Ended
      tags:
      - Brands
  /api/brands/{idOrSlug}/invites/{inviteId}:
    delete:
      operationId: revokeBrandInvite
      summary: Withdraw a pending brand invitation
      parameters:
      - schema:
          type: string
        required: true
        name: idOrSlug
        in: path
      - schema:
          type: string
        required: true
        name: inviteId
        in: path
      responses:
        '200':
          description: Withdrawn
      tags:
      - Brands