API Documentation
Introduction
The framer.art API lets you programmatically upload, list, update, and delete images in your workspace. It's available to workspaces on a paid plan.
All endpoints are relative to the base URL:
https://www.framer.artRequest and response bodies are JSON. Send Content-Type: application/json with any request that includes a body.
Authentication
Every request must include an API key as a bearer token in the Authorization header:
Authorization: Bearer <YOUR_API_KEY>Generate an API key from your workspace's API Access page (/workspaces/:workspace_uid/api-access), available on paid plans. Keys are shown once at creation time, so save it somewhere safe.
Images
GET/api/v1/imageList the images in your workspace, most recently created first. Only images with status published or draft are returned.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
skip | number | No | Number of images to skip. Defaults to 0. |
limit | number | No | Maximum number of images to return. Defaults to 100. |
googlePlaceId | string | No | Filter to images whose location matches this Google Place ID. |
Example Request
curl "https://www.framer.art/api/v1/image?limit=100&skip=0" \
-H "Authorization: Bearer <YOUR_API_KEY>"Example Response
{
"count": 214,
"result": [
{
"id": "a3f5c8e2-4b91-4d67-9a12-8e3f6c7d1b45",
"createdAt": "2026-08-20T14:32:00.000Z",
"publishedAt": "2026-08-20T14:33:10.000Z",
"location": {
"name": "Golden Gate Bridge",
"city": "San Francisco",
"state": "California",
"country": "United States",
"postalCode": "94129",
"latitude": 37.8199,
"longitude": -122.4783,
"googlePlaceId": "ChIJw____96GhYARCVVwg5cT7c0"
},
"monochrome": false,
"orientation": "vertical",
"artType": "Photography",
"artist": "Ansel Adams",
"externalId": "golden-gate-001",
"title": "Golden Gate at Sunset",
"description": "A photo of the Golden Gate Bridge taken at sunset.",
"status": "published",
"sourceImages": [
{ "id": "7c2e9a41-6f38-4d5c-b2a9-1e4f8d3c6a90", "width": 2000, "height": 3000 }
],
"3000pxImageSrc": "https://cdn.framer.art/3000px/golden-gate-at-sunset-abc123.jpg",
"keywords": ["Bridge", "Sunset", "San Francisco"],
"slug": "golden-gate-at-sunset-abc123"
}
]
}GET/api/v1/image/:idGet a single image by its id.
Example Request
curl "https://www.framer.art/api/v1/image/a3f5c8e2-4b91-4d67-9a12-8e3f6c7d1b45" \
-H "Authorization: Bearer <YOUR_API_KEY>"Example Response
{
"id": "a3f5c8e2-4b91-4d67-9a12-8e3f6c7d1b45",
"createdAt": "2026-08-20T14:32:00.000Z",
"publishedAt": "2026-08-20T14:33:10.000Z",
"location": {
"name": "Golden Gate Bridge",
"city": "San Francisco",
"state": "California",
"country": "United States",
"postalCode": "94129",
"latitude": 37.8199,
"longitude": -122.4783,
"googlePlaceId": "ChIJw____96GhYARCVVwg5cT7c0"
},
"monochrome": false,
"orientation": "vertical",
"artType": "Photography",
"artist": "Ansel Adams",
"externalId": "golden-gate-001",
"title": "Golden Gate at Sunset",
"description": "A photo of the Golden Gate Bridge taken at sunset.",
"status": "published",
"sourceImages": [
{ "id": "7c2e9a41-6f38-4d5c-b2a9-1e4f8d3c6a90", "width": 2000, "height": 3000 }
],
"3000pxImageSrc": "https://cdn.framer.art/3000px/golden-gate-at-sunset-abc123.jpg",
"keywords": ["Bridge", "Sunset", "San Francisco"],
"slug": "golden-gate-at-sunset-abc123"
}Returns 404 if no image with that ID exists in your workspace. See Errors.
POST/api/v1/imageUpload a new image.
Body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | The image's title. |
description | string | Yes | The image's description. |
keywords | string[] | Yes | Keywords/subjects for the image. Can be an empty array. |
artType | string | Yes | One of: Photography, Painting, Illustration, Collage, Digital Art, Mixed Media, Drawing, Typography, Maps, Screen Print, Line Drawing, Woodblock, Linocut. |
artist | string | No | The artist associated with the image. Omitted or empty stores as null. |
externalId | string | No | Your own unique ID for the image, unique within your workspace. Omitted or empty stores as null. |
sourceImages | { url: string }[] | Yes | One or more source images, each given as a URL to fetch. All source images must share the same orientation. |
monochrome | boolean | No | Whether the image is black & white. |
collections | { slug: string, name: string }[] | No | Collections to add the image to. Collections that don't yet exist in your workspace are created. |
location | object | No | Where the image was taken. All fields optional: name, city, state, country, postalCode, latitude, longitude, googlePlaceId. |
Example Request
curl -X POST "https://www.framer.art/api/v1/image" \
-H "Authorization: Bearer <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"title": "Golden Gate at Sunset",
"description": "A photo of the Golden Gate Bridge taken at sunset.",
"artType": "Photography",
"monochrome": false,
"keywords": ["Bridge", "Sunset", "San Francisco"],
"collections": [{ "slug": "bay-area", "name": "Bay Area" }],
"location": {
"name": "Golden Gate Bridge",
"city": "San Francisco",
"state": "California",
"country": "United States"
},
"sourceImages": [{ "url": "https://picsum.photos/2000/3000" }]
}'Example Response
{
"id": "a3f5c8e2-4b91-4d67-9a12-8e3f6c7d1b45",
"createdAt": "2026-08-20T14:32:00.000Z",
"publishedAt": "2026-08-20T14:33:10.000Z",
"location": {
"name": "Golden Gate Bridge",
"city": "San Francisco",
"state": "California",
"country": "United States",
"postalCode": "94129",
"latitude": 37.8199,
"longitude": -122.4783,
"googlePlaceId": "ChIJw____96GhYARCVVwg5cT7c0"
},
"monochrome": false,
"orientation": "vertical",
"artType": "Photography",
"artist": "Ansel Adams",
"externalId": "golden-gate-001",
"title": "Golden Gate at Sunset",
"description": "A photo of the Golden Gate Bridge taken at sunset.",
"status": "published",
"sourceImages": [
{ "id": "7c2e9a41-6f38-4d5c-b2a9-1e4f8d3c6a90", "width": 2000, "height": 3000 }
],
"3000pxImageSrc": "https://cdn.framer.art/3000px/golden-gate-at-sunset-abc123.jpg",
"keywords": ["Bridge", "Sunset", "San Francisco"],
"slug": "golden-gate-at-sunset-abc123"
}New images are created with status processing while their mockups are generated, then move to published once ready (or draft if the source images can't produce a mockup yet).
PATCH/api/v1/image/:idUpdate fields on an existing image. All fields are optional: only send what you want to change. keywords, collections, and sourceImages use an add/remove shape rather than replacing the whole list.
Body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | No | The image's title. |
description | string | No | The image's description. |
artType | string | No | One of: Photography, Painting, Illustration, Collage, Digital Art, Mixed Media, Drawing, Typography, Maps, Screen Print, Line Drawing, Woodblock, Linocut. |
artist | string | No | The artist associated with the image. Omit to leave unchanged; empty string clears it. |
externalId | string | No | Your own unique ID for the image. Omit to leave unchanged; empty string clears it. Must be unique within your workspace. |
monochrome | boolean | No | Whether the image is black & white. |
keywords.add | string[] | No | Keywords to add. |
keywords.remove | string[] | No | Keywords to remove. |
collections.add | { slug: string, name: string }[] | No | Collections to add the image to, created if they don't yet exist. |
collections.remove | { slug: string }[] | No | Collections to remove the image from. |
sourceImages.add | { url: string }[] | No | Additional source images to add, given as URLs. Must share the same orientation as the image's existing source images. There's no way to remove a source image via the API. |
location | object | No | Replaces the image's location entirely. Same shape as on create. |
Example Request
curl -X PATCH "https://www.framer.art/api/v1/image/a3f5c8e2-4b91-4d67-9a12-8e3f6c7d1b45" \
-H "Authorization: Bearer <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"title": "Golden Gate at Golden Hour",
"keywords": { "add": ["Golden Hour"], "remove": ["Sunset"] }
}'Example Response
{
"id": "a3f5c8e2-4b91-4d67-9a12-8e3f6c7d1b45",
"createdAt": "2026-08-20T14:32:00.000Z",
"publishedAt": "2026-08-20T14:33:10.000Z",
"location": {
"name": "Golden Gate Bridge",
"city": "San Francisco",
"state": "California",
"country": "United States",
"postalCode": "94129",
"latitude": 37.8199,
"longitude": -122.4783,
"googlePlaceId": "ChIJw____96GhYARCVVwg5cT7c0"
},
"monochrome": false,
"orientation": "vertical",
"artType": "Photography",
"artist": "Ansel Adams",
"externalId": "golden-gate-001",
"title": "Golden Gate at Sunset",
"description": "A photo of the Golden Gate Bridge taken at sunset.",
"status": "published",
"sourceImages": [
{ "id": "7c2e9a41-6f38-4d5c-b2a9-1e4f8d3c6a90", "width": 2000, "height": 3000 }
],
"3000pxImageSrc": "https://cdn.framer.art/3000px/golden-gate-at-sunset-abc123.jpg",
"keywords": ["Bridge", "Sunset", "San Francisco"],
"slug": "golden-gate-at-sunset-abc123"
}Returns 404 if no image with that ID exists in your workspace. See Errors.
DELETE/api/v1/image/:idDeletes an image. It stops appearing in list/get requests, storefronts, and marketplaces.
Example Request
curl -X DELETE "https://www.framer.art/api/v1/image/a3f5c8e2-4b91-4d67-9a12-8e3f6c7d1b45" \
-H "Authorization: Bearer <YOUR_API_KEY>"Example Response
The response body is null.
nullReturns 404 if no image with that ID exists in your workspace. See Errors.
MCP Server
The same API is also available as an MCP (Model Context Protocol) server, so MCP-compatible AI tools (Claude Desktop, custom agents, etc.) can call it directly instead of you writing REST requests by hand. It supports the Streamable HTTP transport at:
https://www.framer.art/api/v1/mcpAuthenticate the same way as the REST API: send your API key as a bearer token in the Authorization header. There's no separate MCP credential.
Tools
Each tool mirrors one of the REST endpoints above 1:1, including the same validation and error behavior.
| Tool | Equivalent REST endpoint |
|---|---|
list_images | GET /api/v1/image |
get_image | GET /api/v1/image/:id |
create_image | POST /api/v1/image |
update_image | PATCH /api/v1/image/:id |
delete_image | DELETE /api/v1/image/:id |
Errors
Errors are returned as JSON in the shape { "error": string }, with one exception noted below.
400 Bad Request: a request failed validation or a business rule (e.g. you've hit your plan's image limit, source images don't share an orientation, or a referenced collection doesn't exist).404 Not Found: no image exists with the givenidin your workspace, forGET/PATCH/DELETEon/api/v1/image/:id.409 Conflict: another image in your workspace already uses thisexternalId.405 Method Not Allowed: the HTTP method isn't supported on that path.
A few cases currently fall through as an unstructured 500 Internal Server Error rather than a clean error response; this is existing behavior, not a documented contract, so don't rely on the response body in these cases:
- The Authorization header is missing.
- The API key in the Authorization header doesn't exist.
- The request body doesn't match the expected shape (e.g. a required field is missing or the wrong type).
If your workspace's plan doesn't include API access, you'll get a clean 400 with { "error": "You must be a paid user to use the API." }.
Have a question or a use case that isn't yet supported? Contact us and we'll help you out.
