On this page
Assets
Assets are files served from /assets/<path> on the site's hostname: images, diagrams, downloads, logos. They belong to the site, so every version shares one namespace.
For usage guidance — filenames, caching, and referencing from markdown — see Images and assets.
All endpoints require an organization API key. :site accepts a slug or an id.
List assets
GET /v1/sites/:site/assets
curl -s -H "authorization: Bearer $DOCSARY_KEY" \
"$DOCSARY_API/v1/sites/acme/assets"
{
"assets": [
{
"path": "img/architecture.png",
"content_type": "image/png",
"size": 48213,
"sha256": "9f2c1a..."
}
]
}
Results are ordered by path. size is in bytes; compare sha256 with your file to avoid an unnecessary upload.
Upload an asset
POST /v1/sites/:site/assets/<path>
The file is the raw request body. The content-type header declares the file's own type and is stored verbatim.
curl -s -X POST "$DOCSARY_API/v1/sites/acme/assets/img/architecture.png" \
-H "authorization: Bearer $DOCSARY_KEY" \
-H "content-type: image/png" \
--data-binary @architecture.png
{ "path": "img/architecture.png", "size": 48213, "sha256": "9f2c1a..." }
201 confirms a new or replacement asset. Existing browser or offline copies may remain older.
A missing content-type header stores the asset as application/octet-stream, and it is served back that way — browsers will download it rather than display it. Set the header explicitly.
Path rules
The path is everything after /assets/ in the request URL, percent-decoded.
- Must match
^[a-z0-9][a-z0-9._/-]*$, case-insensitively: letters, digits, dots, underscores, hyphens, and slashes. - Must begin with a letter or a digit.
- May not contain
..anywhere.
Errors
| Response | Cause |
|---|---|
400 {"error":"bad path"} |
Path fails the pattern or contains .. |
400 {"error":"malformed percent-encoding in asset path"} |
The path could not be decoded |
400 {"error":"empty body"} |
Zero-length body |
413 {"error":"asset too large (20MB cap)"} |
Body over 20 MB |
413 with quota: "asset_bytes" |
The upload would cross your organization's storage ceiling |
503 |
Asset storage is temporarily unavailable |
Replacement uploads and pending cleanup can affect available storage. Read quota errors and cleanup status before retrying.
Upload failures can return 409 for a conflicting upload, 502 for a storage rejection, or 503 for unavailable storage or blocked cleanup. Check the current asset and retry after the conflict clears.
A successful upload with cleanup: "pending" means the new asset is published but the replaced file still awaits deletion. Those bytes count toward storage until cleanup finishes. A later upload to the same path can complete cleanup.
Delete an asset
DELETE /v1/sites/:site/assets/<path>
curl -s -X DELETE "$DOCSARY_API/v1/sites/acme/assets/img/architecture.png" \
-H "authorization: Bearer $DOCSARY_KEY"
{ "deleted": "img/architecture.png" }
200 confirms deletion and releases the storage allowance. A missing asset returns 404 {"error":"asset not found"}.
409 can mean an upload is in progress or the asset changed during deletion; check it before retrying. 503 can mean prior cleanup is blocked.
A 503 response with cleanup: "pending" means the asset URL is removed but its stored bytes still count toward your limit. Retry the same delete to finish cleanup.
Check references across all versions before deleting. Docsary does not check whether a page still uses the asset.
How assets are served
Assets use the uploaded content type and this cache policy:
cache-control: public, max-age=60, s-maxage=31536000
Use a new filename for changed images, upload it first, then update page references. Cached or offline copies of an older URL can remain. See Images and assets.