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

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

  • Sketchpad owns hosted frame mounting, readiness, and teardown.
  • HostedSketchAPI is the async drawing API returned by mount().
  • SketchpadAppDefinition is optional JSON-safe product configuration.
  • document and layer handles are instance-scoped data references.
  • sketchpad.files is an optional hosted browser document library.
  • your server owns API-key custody and session creation.

Continue

CodeAtlas generates the browser reference from the canonical hosted entrypoint. This site does not maintain a second table of signatures or private exports.