Savee Boards API
The Boards API from Savee — 3 operation(s) for boards.
The Boards API from Savee — 3 operation(s) for boards.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/savee-boards-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
info:
title: Savee Public Boards API
version: 1.0.0
contact:
name: Savee
url: https://docs.savee.com
email: hey@savee.com
termsOfService: https://savee.com/terms/
license:
name: Proprietary — Savee Terms of Service
url: https://savee.com/terms/
description: 'Read-only REST API exposing a Savee user’s own saves, boards, and home feed, plus search over Savee’s public library.
Authenticate with either a personal access token (`sv_live_…`) generated in your Savee settings, or an OAuth 2.1 access token (`sv_at_…`) obtained on one of your users’ behalf. OAuth tokens are limited to the scopes the user approved; personal tokens carry all of them.
**Image format** — `media.thumbnail` and `media.original` for image saves are AVIF by default. Clients that cannot decode AVIF should send the request header `Avif-Fallback: 1` to receive JPG URLs instead. Video originals are always MP4.'
servers:
- url: https://api.savee.com
tags:
- name: Boards
paths:
/v1/boards:
get:
summary: List the authenticated user's boards
description: 'Returns every board the caller can see as a tree in a single response (not paginated): personal boards they own, boards they collaborate on, and boards from any Savee Teams workspace they''re a member of. Only top-level boards appear at the root of `data`; a board''s children are nested under its `sub_boards` array (single-level, so each sub-board is a leaf). Use the `ownership_type` field on each board to tell user-owned boards apart from team boards. The order at every level follows the caller''s chosen boards-sort preference on savee.com.'
tags:
- Boards
security:
- BearerAuth: []
- OAuth2:
- boards:read
responses:
'200':
description: All boards visible to the caller, as a tree.
content:
application/json:
schema:
$ref: '#/components/schemas/BoardsList'
'400':
description: Invalid input.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid Bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Authenticated but the user has no active subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: The Public API is not available on this account.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
description: Rate limit exceeded. Retry after the number of seconds in `Retry-After`.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/boards/{boardID}:
get:
summary: Get a single board
description: '`boardID` is the board `id` returned by `/v1/boards`. Returns the board with its child boards nested under `sub_boards` — the same shape as a node in the `/v1/boards` tree — so there is no separate sub-boards endpoint. Accessible by any user with a role on the board (owner, admin, editor, viewer) and by team members for team-owned boards. Returns 404 when the board does not exist or the caller has no role on it — the API does not confirm whether someone else’s board exists.'
tags:
- Boards
security:
- BearerAuth: []
- OAuth2:
- boards:read
parameters:
- schema:
type: string
description: The board id (the `id` returned by `/v1/boards`).
required: true
description: The board id (the `id` returned by `/v1/boards`).
name: boardID
in: path
responses:
'200':
description: The board, with its sub-boards nested.
content:
application/json:
schema:
$ref: '#/components/schemas/BoardResponse'
'400':
description: Invalid input.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid Bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Authenticated but the user has no active subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: The Public API is not available on this account.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Board not found or not accessible to the caller.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
description: Rate limit exceeded. Retry after the number of seconds in `Retry-After`.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/boards/{boardID}/saves:
get:
summary: List saves on a specific board
description: '`boardID` is the board `id` returned by `/v1/boards`. Accessible by any user with a role on the board (owner, admin, editor, viewer) and by team members for team-owned boards. Returns 404 when the board does not exist or the caller has no role on it — the API does not confirm whether someone else’s board exists.'
tags:
- Boards
security:
- BearerAuth: []
- OAuth2:
- boards:read
- saves:read
parameters:
- schema:
type: string
description: The board id (the `id` returned by `/v1/boards`).
required: true
description: The board id (the `id` returned by `/v1/boards`).
name: boardID
in: path
- schema:
type: integer
minimum: 1
maximum: 100
description: Page size (default 30, max 100).
example: 30
required: false
name: limit
in: query
- schema:
type: string
description: Opaque cursor returned in `next_cursor` from the previous page. Pass it through verbatim — the encoding is an implementation detail and may change.
example: eyJjIjoiMjAyNi0wNS0wOFQxMjowMDowMFoiLCJpIjoiNjdhYWRhMjAifQ
required: false
name: cursor
in: query
responses:
'200':
description: A page of saves on the board.
content:
application/json:
schema:
$ref: '#/components/schemas/SavesPage'
'400':
description: Invalid input.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid Bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Authenticated but the user has no active subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: The Public API is not available on this account.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Board not found or not accessible to the caller.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
description: Rate limit exceeded. Retry after the number of seconds in `Retry-After`.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
SubBoard:
type: object
properties:
id:
type: string
description: Board identifier. Stable across renames and slug changes; safe to store as a foreign key on the caller’s side.
name:
type: string
slug:
type: string
url:
type: string
format: uri
description: Canonical page on savee.com for this board (uses the current slug).
is_private:
type: boolean
saves_count:
type: integer
minimum: 0
created_at:
type: string
format: date-time
og_image:
type:
- string
- 'null'
format: uri
ownership_type:
type: string
enum:
- team
- user
description: '`user` if the board belongs to a person (the caller, or someone who''s added the caller as a collaborator); `team` if it belongs to a Savee Teams workspace the caller is a member of.'
sub_boards:
type: array
description: Always empty — sub-boards do not nest further (nesting is single-level).
items: {}
maxItems: 0
required:
- id
- name
- slug
- url
- is_private
- saves_count
- created_at
- og_image
- ownership_type
- sub_boards
User:
type: object
properties:
id:
type: string
description: User identifier. Stable across renames; safe to store as a foreign key on the caller’s side.
example: 63e1a4c2d242ec00094007f1
username:
type: string
description: Current username. May change if the user renames.
example: aliceb
name:
type: string
example: Alice Bauer
url:
type: string
format: uri
example: https://savee.com/aliceb/
avatar_url:
type: string
format: uri
example: https://dm.savee.com/user-avatar/original/8kQ2mZp.jpg
required:
- id
- username
- name
- url
- avatar_url
description: The user who created this save. Omitted on /v1/saves (the caller is implicitly the author); present on /v1/feed and /v1/boards/{id}/saves where the author may differ from the caller.
SavesPage:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Save'
next_cursor:
type:
- string
- 'null'
description: Pass as `cursor` to fetch the next page. `null` on the last page.
example: eyJjIjoiMjAyNi0wNS0wOFQxMjowMDowMFoiLCJpIjoiNjdhYWRhMjAifQ
has_more:
type: boolean
description: Whether another page is available. Keep paging while this is `true`.
example: true
required:
- data
- next_cursor
- has_more
BoardResponse:
type: object
properties:
data:
$ref: '#/components/schemas/Board'
required:
- data
ErrorResponse:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
required:
- code
- message
required:
- error
Board:
type: object
properties:
id:
type: string
description: Board identifier. Stable across renames and slug changes; safe to store as a foreign key on the caller’s side.
example: 69fbaf96d242ec48009df59a
name:
type: string
example: Posters
slug:
type: string
example: posters
url:
type: string
format: uri
description: Canonical page on savee.com for this board (uses the current slug).
example: https://savee.com/aliceb/posters/
is_private:
type: boolean
example: false
saves_count:
type: integer
minimum: 0
example: 128
created_at:
type: string
format: date-time
example: '2026-04-01T09:00:00.000Z'
og_image:
type:
- string
- 'null'
format: uri
description: Share image for the board. `null` if one has not been generated yet.
example: https://dm.savee.com/board-og/original/Lp9wQ2s.jpg
ownership_type:
type: string
enum:
- team
- user
description: '`user` if the board belongs to a person (the caller, or someone who''s added the caller as a collaborator); `team` if it belongs to a Savee Teams workspace the caller is a member of.'
example: user
sub_boards:
type: array
items:
$ref: '#/components/schemas/SubBoard'
description: Child boards nested one level under this board, ordered by the same boards-sort preference as the top level.
required:
- id
- name
- slug
- url
- is_private
- saves_count
- created_at
- og_image
- ownership_type
- sub_boards
Save:
type: object
properties:
id:
type: string
description: Save identifier. Stable across renames; safe to store as a foreign key on the caller’s side.
example: 67aada20d242ec0009400825
url:
type: string
format: uri
description: Canonical page on savee.com for this save.
example: https://savee.com/i/UXb_bvc/
name:
type: string
example: Brutalist poster
source_url:
type:
- string
- 'null'
description: Where the save was originally taken from. `null` if unknown.
example: https://example.com/poster
created_at:
type: string
format: date-time
example: '2026-05-08T12:00:00.000Z'
is_private:
type: boolean
description: Whether the save itself is marked private. This is a property of the save, independent of whether it also sits in a private board.
example: false
total_saves:
type: integer
minimum: 0
description: How many users across Savee have saved this same asset.
example: 42
media:
$ref: '#/components/schemas/SaveMedia'
colors:
type: array
items:
$ref: '#/components/schemas/SaveColor'
description: Dominant colors of the media, most prominent first. Empty when colors have not been extracted for this save (e.g. shortly after saving).
user:
$ref: '#/components/schemas/User'
required:
- id
- url
- name
- source_url
- created_at
- is_private
- total_saves
- media
- colors
SaveMedia:
type: object
properties:
type:
type: string
enum:
- image
- video
example: image
width:
type: integer
minimum: 0
example: 1600
height:
type: integer
minimum: 0
example: 2400
thumbnail:
type: string
format: uri
description: 'Grid-sized preview (~420px wide). AVIF by default; clients that cannot decode AVIF should send `Avif-Fallback: 1` to receive JPG. Applies to both image and video assets (videos return a JPG/AVIF poster frame).'
example: https://dm.savee.com/asset_image/w420/6r4nDqE.avif
original:
type: string
format: uri
description: 'Full-quality asset. Image: AVIF by default (JPG with `Avif-Fallback: 1`). Video: MP4.'
example: https://dm.savee.com/asset_image/original/6r4nDqE.avif
required:
- type
- width
- height
- thumbnail
- original
BoardsList:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Board'
required:
- data
SaveColor:
type: object
properties:
color:
type: string
pattern: ^#[0-9A-F]{6}$
description: Hex color code, e.g. `#1A2B3C`.
example: '#1A1A1A'
amount:
type: number
minimum: 0
maximum: 1
description: Fraction of the media covered by this color (0–1).
example: 0.62
required:
- color
- amount
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: sv_live_…
description: '**Personal access token** (`sv_live_…`) — represents you and carries every scope, so no scope is required for this call. Best for your own scripts and internal tools. Generate one at https://savee.com/developers/.'
OAuth2:
type: oauth2
description: '**OAuth access token** (`sv_at_…`) — obtained on one of your users’ behalf and limited to the scopes they approved. Use this when you’re building a product other people sign into with Savee. See https://docs.savee.com/api/oauth.
Missing the scope below returns `403` with a `WWW-Authenticate: Bearer error="insufficient_scope"` header naming it.'
flows:
authorizationCode:
authorizationUrl: https://savee.com/oauth/authorize/
tokenUrl: https://savee.com/api/oauth/token/
refreshUrl: https://savee.com/api/oauth/token/
scopes:
profile:read: Read the user’s username, name, and avatar
saves:read: Read the user’s saves and home feed
boards:read: Read the user’s boards and the saves on them
search:read: Search Savee’s public library on the user’s behalf