SketchAPI Documentation
SketchAPI embeds a hosted Sketchpad drawing surface without shipping the editor runtime or its private source to your application. Your server creates a short-lived session, the browser loads the versioned client, and each mounted frame exposes its own asynchronous document, layer, selection, event, tool, brush, media, open, and save API.
Create a project, register every browser origin that may embed Sketchpad, and mint an API key in the dashboard. Keep that key on your server.
Table of Contents
- Create a Session
- Mount a Sketchpad
- Lifecycle
- Active Document
- Hosted Browser Files
- Contract Boundaries
- Continue
Create a Session
Call the control plane from your server and return only the session object to
your browser. parentOrigin must exactly match a registered project origin:
export async function createSketchApiSession(parentOrigin) {
const response = await fetch('https://api.sketchapi.com/v1/sessions', {
body: JSON.stringify({ parentOrigin }),
headers: {
'content-type': 'application/json',
'x-api-key': process.env.SKETCHAPI_API_KEY
},
method: 'POST'
})
if (!response.ok) throw new Error(`SketchAPI session failed: ${response.status}`)
return response.json()
} The key is accepted as x-api-key or as Authorization: Bearer. A created
session is a one-time credential:
{
"expiresAt": "2026-07-16T12:05:00.000Z",
"frameUrl": "https://sketchapi.com/frame/ses_…",
"sessionId": "ses_…",
"token": "sks_…"
} Log sessionId on your server if you want to correlate support requests and
usage; only frameUrl, token, and expiresAt are needed in the browser.
Expose this through an authenticated endpoint owned by your application. Never place the project API key in browser code, HTML, logs, or a session response. See the service API reference for the exact request, response, error, and rate-limit contracts.
Mount a Sketchpad
Give the host element a real height, request a session from your server, and load the versioned browser client directly from SketchAPI:
import { Sketchpad } from 'https://sketchapi.com/sdk/v1/sketchapi.js'
const response = await fetch('/api/sketchapi/session', { method: 'POST' })
if (!response.ok) throw new Error('Could not start SketchAPI.')
const sketchpad = new Sketchpad({ session: await response.json() })
const api = await sketchpad.mount(document.querySelector('#sketchpad'))
await api.tool?.use('paintbrush') #sketchpad {
height: 640px;
width: 100%;
} mount() resolves the same async API exposed by sketchpad.api. A session is
short-lived, exact-origin, one-time, and valid for one mount only.
Lifecycle
Keep the Sketchpad instance and destroy it when the host view is removed.
Abort a mount when navigation or component teardown starts:
const controller = new AbortController()
try {
await sketchpad.mount(container, { signal: controller.signal })
} finally {
controller.abort()
sketchpad.destroy()
} Create a fresh session and Sketchpad for every independently mounted editor.
Instances do not share documents, selection, renderer state, input, or API
objects.
Pass onStateChange to observe the lifecycle, including destruction caused by
a lost frame connection:
const sketchpad = new Sketchpad({
onStateChange: (state) => {
if (state === 'destroyed') showRemountPrompt()
},
session
}) Session Expiry
expiresAt gates mounting only. A session that expires while your user is
drawing changes nothing: the mounted editor keeps working until you destroy it.
There is no renewal. When a mount fails with session_expired, or after a destroyed state you did not initiate, request a fresh session from your
server and mount a new Sketchpad instance. The error code reference lists every session and connection code.
Versioning
Pin nothing yourself; the URLs already do it. /sdk/v1/sketchapi.js and POST /v1/sessions name the major version, and non-breaking additions ship
within v1 without action on your side. Breaking changes ship as v2 URLs
next to v1; a stale cached client never mixes with a newer frame because the
mount fails fast with protocol_version_unsupported instead of degrading.
Active Document
Document-aware operations use the active document by default. Activate another
document explicitly or pass a one-operation { doc } override:
await api.document.activate(firstDocument)
await api.layer.create(rectangle)
await api.save.json({ as: 'object' })
await api.layer.create(watermark, { doc: secondDocument }) The override does not change the active document. Handles returned by one Sketchpad instance cannot be used with another instance.
Hosted Browser Files
After mounting, sketchpad.files exposes the hosted frame’s optional native
document library:
const stored = await sketchpad.files?.save({ name: 'Cover artwork' })
const recent = await sketchpad.files?.list() This browser-backed library is isolated from your application page and does not
imply account storage, cloud sync, sharing, or collaboration. Export through api.save when your application needs to upload or persist artwork elsewhere.
Contract Boundaries
Sketchpadowns hosted frame mounting, readiness, and teardown.HostedSketchAPIis the async drawing API returned bymount().SketchpadAppDefinitionis optional JSON-safe product configuration.- document and layer handles are instance-scoped data references.
sketchpad.filesis an optional hosted browser document library.- your server owns API-key custody and session creation.
Continue
- App Configuration explains the portable definition.
- Examples covers cancellation, files, and multiple mounts.
- Tools explains tool selection and async control.
- Document Boundary covers documents, layers, and IO.
- API Reference is generated from the hosted browser contract and public JSDoc.
CodeAtlas generates the browser reference from the canonical hosted entrypoint. This site does not maintain a second table of signatures or private exports.
Ready to build?