Skip to content

Images ​

An image you store here belongs to your workspace and is addressed by the name you give it, e.g., company-logo, rather than a URL you have to keep serving. Papermill keeps the bytes, so a document does not depend on a file staying where you first put it.

A name is 3–64 characters of lowercase letters, digits and single hyphens. Names are pointers: storing under a name you already hold replaces the image, and anything that draws that name draws the new one from then on. A name that breaks the rules is rejected with message Invalid image name '<name>': <the rule it broke>.

The bytes decide the format, not the Content-Type you send. Papermill accepts PNG, JPEG, WebP and SVG; anything else is rejected whatever it was labelled. One image is limited to 50 MB, and a workspace to 1 GB across at most 1000 names.

Upload an image​

PUT
/v2/images/{name}

Stores image bytes under a name in your workspace. Send the file as the request body, with Content-Type set to one of image/png, image/jpeg, image/webp, image/svg+xml. The bytes decide the format: a declared type that disagrees with them is ignored, and bytes that are none of those types are refused. A name is a pointer: storing under a name you already hold replaces the image, and every document referencing that name renders the new one from then on. One image is limited to 50 MB, and a workspace to 1 GB across at most 1000 names. An upload the workspace has no room for is refused, and the refusal names what you hold now.

Authorizations​

ApiKeyHeader

Your Papermill API key, sent as an x-api-key header.

Type
API Key (header: x-api-key)
or
BearerAuth

Your Papermill API key, sent as Authorization: Bearer <key>. Equivalent to the x-api-key form.

Type
HTTP (bearer)

Parameters​

Path Parameters

name*

Lowercase letters, digits and single hyphens — company-logo.

Type
string
Required
Min Length
3
Max Length
64

Request Body​

Format"binary"

Responses​

The stored image

application/json
JSON
{
  
"name": "string",
  
"content_type": "string",
  
"bytes": 0,
  
"width": 0,
  
"height": 0,
  
"sha256": "string",
  
"created_at": "string",
  
"created_by": {
  
  
"id": "string",
  
  
"name": "string",
  
  
"email": "string"
  
},
  
"updated_at": "string",
  
"updated_by": {
  
  
"id": "string",
  
  
"name": "string",
  
  
"email": "string"
  
}
}

Playground​

Authorization
Variables
Key
Value
Body

Samples​

Store an image from a URL or inline data​

POST
/v2/images

Stores an image Papermill fetches for you, or one carried in the request as base64 — the same result as uploading the bytes, for callers that have a URL or cannot set a binary body. Give exactly one of source_url and data. A name is a pointer: storing under a name you already hold replaces the image, and every document referencing that name renders the new one from then on. One image is limited to 50 MB, and a workspace to 1 GB across at most 1000 names. An upload the workspace has no room for is refused, and the refusal names what you hold now.

Authorizations​

ApiKeyHeader

Your Papermill API key, sent as an x-api-key header.

Type
API Key (header: x-api-key)
or
BearerAuth

Your Papermill API key, sent as Authorization: Bearer <key>. Equivalent to the x-api-key form.

Type
HTTP (bearer)

Request Body​

application/json
JSON
{
  
"name": "string",
  
"source_url": "string",
  
"data": "string"
}

Responses​

The stored image

application/json
JSON
{
  
"name": "string",
  
"content_type": "string",
  
"bytes": 0,
  
"width": 0,
  
"height": 0,
  
"sha256": "string",
  
"created_at": "string",
  
"created_by": {
  
  
"id": "string",
  
  
"name": "string",
  
  
"email": "string"
  
},
  
"updated_at": "string",
  
"updated_by": {
  
  
"id": "string",
  
  
"name": "string",
  
  
"email": "string"
  
}
}

Playground​

Authorization
Body

Samples​

List stored images​

GET
/v2/images

The images your workspace holds, ordered by name, alongside what they occupy in total. next_cursor is present exactly when there is another page; send it back as start_after to continue. usage covers the whole workspace, not the page.

Authorizations​

ApiKeyHeader

Your Papermill API key, sent as an x-api-key header.

Type
API Key (header: x-api-key)
or
BearerAuth

Your Papermill API key, sent as Authorization: Bearer <key>. Equivalent to the x-api-key form.

Type
HTTP (bearer)

Parameters​

Query Parameters

limit

Images per page. Defaults to 100.

Type
integer
Minimum
1
Maximum
1000
start_after

The previous page’s next_cursor.

Type
string
Min Length
3
Max Length
64

Responses​

Images held

application/json
JSON
{
  
"images": [
  
  
{
  
  
  
"name": "string",
  
  
  
"content_type": "string",
  
  
  
"bytes": 0,
  
  
  
"width": 0,
  
  
  
"height": 0,
  
  
  
"sha256": "string",
  
  
  
"created_at": "string",
  
  
  
"created_by": {
  
  
  
  
"id": "string",
  
  
  
  
"name": "string",
  
  
  
  
"email": "string"
  
  
  
},
  
  
  
"updated_at": "string",
  
  
  
"updated_by": {
  
  
  
  
"id": "string",
  
  
  
  
"name": "string",
  
  
  
  
"email": "string"
  
  
  
}
  
  
}
  
],
  
"next_cursor": "string",
  
"usage": {
  
  
"total_bytes": 0,
  
  
"count": 0
  
}
}

Playground​

Authorization
Variables
Key
Value

Samples​

Read one image​

GET
/v2/images/{name}

What a name holds: its format, size, dimensions and digest. The bytes themselves are not served back — reference the name from a document to draw the image.

Authorizations​

ApiKeyHeader

Your Papermill API key, sent as an x-api-key header.

Type
API Key (header: x-api-key)
or
BearerAuth

Your Papermill API key, sent as Authorization: Bearer <key>. Equivalent to the x-api-key form.

Type
HTTP (bearer)

Parameters​

Path Parameters

name*

Lowercase letters, digits and single hyphens — company-logo.

Type
string
Required
Min Length
3
Max Length
64

Responses​

The stored image

application/json
JSON
{
  
"name": "string",
  
"content_type": "string",
  
"bytes": 0,
  
"width": 0,
  
"height": 0,
  
"sha256": "string",
  
"created_at": "string",
  
"created_by": {
  
  
"id": "string",
  
  
"name": "string",
  
  
"email": "string"
  
},
  
"updated_at": "string",
  
"updated_by": {
  
  
"id": "string",
  
  
"name": "string",
  
  
"email": "string"
  
}
}

Playground​

Authorization
Variables
Key
Value

Samples​

Delete an image​

DELETE
/v2/images/{name}

Removes an image and frees the space it occupied. Documents referencing the name stop finding an image, so delete a name only when nothing renders it.

Authorizations​

ApiKeyHeader

Your Papermill API key, sent as an x-api-key header.

Type
API Key (header: x-api-key)
or
BearerAuth

Your Papermill API key, sent as Authorization: Bearer <key>. Equivalent to the x-api-key form.

Type
HTTP (bearer)

Parameters​

Path Parameters

name*

Lowercase letters, digits and single hyphens — company-logo.

Type
string
Required
Min Length
3
Max Length
64

Responses​

Image deleted

Playground​

Authorization
Variables
Key
Value

Samples​

Example ​

Store a logo, then check what your workspace holds.

shell
set -e
curl -fsS -X PUT "https://api.papermill.io/v2/images/company-logo" \
  -H "Authorization: Bearer $PAPERMILL_API_KEY" \
  -H "Content-Type: image/png" \
  --data-binary @logo.png

curl -fsS "https://api.papermill.io/v2/images" \
  -H "Authorization: Bearer $PAPERMILL_API_KEY"
python
import os
import requests

key = os.environ["PAPERMILL_API_KEY"]
auth = {"Authorization": f"Bearer {key}"}

with open("logo.png", "rb") as f:
    stored = requests.put(
        "https://api.papermill.io/v2/images/company-logo",
        headers={**auth, "Content-Type": "image/png"},
        data=f.read(),
    )
stored.raise_for_status()
print(stored.json()["bytes"], stored.json()["content_type"])

held = requests.get("https://api.papermill.io/v2/images", headers=auth)
held.raise_for_status()
print(held.json()["usage"])
javascript
import fs from 'node:fs/promises'

const key = process.env.PAPERMILL_API_KEY
const auth = { Authorization: `Bearer ${key}` }

const stored = await fetch('https://api.papermill.io/v2/images/company-logo', {
  method: 'PUT',
  headers: { ...auth, 'Content-Type': 'image/png' },
  body: await fs.readFile('logo.png'),
})
if (!stored.ok) throw new Error(`${stored.status} ${stored.statusText}`)

const held = await fetch('https://api.papermill.io/v2/images', { headers: auth })
if (!held.ok) throw new Error(`${held.status} ${held.statusText}`)
console.log((await held.json()).usage)

Sending the same name again replaces the image and succeeds, so this is safe to repeat from a setup script.

When you have a URL instead of a file ​

POST /v2/images takes a source_url and downloads the image for you, which saves a round trip when the file already lives somewhere public. Only http and https URLs are fetched, and only addresses reachable from the public internet — a URL that resolves to a private network is refused.

The same request accepts data instead: the image as unwrapped base64, under its own cap — lower than the upload route's, because encoding grows the value by a third and the whole thing has to travel inside one JSON request. The exact figure is on the data field above. It exists for callers that cannot set a binary request body, and for assistants working from a file they already hold. Give exactly one of the two; a request carrying both is rejected with message Give either 'source_url' or 'data', not both.

Keeping track of what you hold ​

GET /v2/images returns a page of names alongside a usage object covering the whole workspace — total_bytes and count. When there is another page, next_cursor names where it starts; send it back as start_after.

An upload the workspace has no room for is rejected with a message naming what you hold now and the limit you are held to, so a script can report the position rather than only the failure. Deleting frees the space immediately.

Deleting ​

DELETE /v2/images/{name} removes the image and frees its space. Anything that draws the name stops finding an image, so delete a name only when nothing renders it. When the workspace holds no image of that name, Papermill rejects the request with message This workspace holds no image named '<name>'.