dotsy Assets API

Upload, list and delete images, fonts and other files a site serves.

Operations 9

GET /api/v1/sites/{slug}/assets List a site's uploaded assets #
POST /api/v1/sites/{slug}/assets/bulk Upload up to 200 assets in one call #
POST /api/v1/sites/{slug}/assets/optimize Shrink up to 50 heavy images to WebP #
GET /api/v1/sites/{slug}/assets/{key} Download an asset, or read its metadata #
PUT /api/v1/sites/{slug}/assets/{key} Upload or replace one asset #
DELETE /api/v1/sites/{slug}/assets/{key} Delete an asset #
PUT /api/v1/sites/{slug}/assets-raw/{key} Upload one asset as raw bytes #
PUT /api/v1/sites/{slug}/static-files/{path} Upload a file at an exact site path #
DELETE /api/v1/sites/{slug}/static-files/{path} Delete a file at an exact site path #

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/dotsy-ai:dotsy-ai-assets-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

dotsy-ai-assets-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: dotsy Assets API
  version: 1.0.0
  description: 'Build, edit and publish dotsy sites over HTTP. The dashboard, the `dotsy` CLI and the MCP server all use this API.


    Production base URL: `https://api.dotsy.ai`. The **Try it** console in this reference sends requests to the origin you are reading it on, so it needs no host setting.


    ## Authentication


    Send `Authorization: Bearer ` on every request. Three kinds of token work:


    - **Account API key** (`pga_…`). Create one in the dashboard or with `POST /api/v1/account/keys`. It acts as one account.

    - **OAuth token.** MCP clients that sign in with OAuth send their opaque access token in the same header.

    - **Guest token** (`pgg_…`). `POST /api/v1/anon/sites` returns one with a new site. It works on that one site only, and publish, rename, delete, domains, imports and asset writes need an account instead.


    To choose the workspace a request acts in, send `X-Dotsy-Workspace: `. It applies to sign-in sessions and OAuth tokens. A `pga_` key is tied to one account and ignores it. A workspace you don''t belong to answers `403`.


    ## Errors


    Failures answer with a JSON body `{ "error": "", "hint": "" }`. `error` is a stable machine code, so branch on it and not on the text. Validation failures add `issues`, the list of problems, and some errors add fields that belong to them, such as `jobId` or `keys`. Every error response in this reference uses the `ApiError` schema.


    ## Lists and paging


    Each list operation that supports paging documents `limit` (1 to 1000) and `cursor`. Send `limit` to page. The response then carries `nextCursor`: a string while more results remain, and `null` on the last page. Pass it back unchanged as `cursor` to get the next page. Cursors are opaque, so don''t build or parse them.


    ## Sites, slugs and ids


    Site operations live under `/api/v1/sites/{slug}`. `{slug}` takes the site''s slug or its id (a UUID, returned as `id`). A slug changes when the site is renamed, so keep the id if you need a handle that stays put.


    - While a renamed, published site''s old slug stays reserved, it answers `301` for GET and HEAD and `308` for every other method. `Location` holds the same path under the current slug.

    - A site id answers `307` with `Location` set to the path under the current slug.


    **Follow redirects** (`curl -L`, and the default in `fetch`), then use the slug from `Location` from that point on. Slug-scoped API keys and guest tokens only work with the site''s current slug.


    Content keys and asset paths in `{key}` and `{path}` can contain `/`. Percent-encode each segment. A `/` may be sent raw or as `%2F`.


    ## Rate limits


    Writes (POST, PUT, PATCH and DELETE under `/api/v1/sites/…`) share a budget of 600 per minute per account. Raw asset uploads (`PUT …/assets-raw/…`) have their own budget of 3,000 per minute, and sending site invites has another of 30 per minute. Reads are not counted. Over budget, you get `429` with `error: "rate_limited"` and a `Retry-After` header in seconds.


    ## Long-running work


    Imports, large renames and large changesets answer `202 Accepted` with a `job` object (`id`, `kind`, `status`). Poll `GET /api/v1/sites/{slug}/jobs/{id}` every few seconds until `status` is `succeeded` or `failed`. An operation that finishes right away returns its result and no job.'
servers:
- url: /
security:
- BearerAuth: []
tags:


# --- truncated at 32 KB (61 KB total) ---
# Full source: https://artifacts.apis.io/dotsy-ai/openapi/dotsy-ai-assets-api-openapi.yml