Error Codes

Every SketchAPI failure carries a stable, machine-readable code. Branch on the code, never on the human-readable message.

Table of Contents

Control Plane Responses

Control-plane errors use one JSON envelope on every status:

{
	"error": {
		"code": "origin_not_allowed",
		"message": "Parent origin is not allowed for this project.",
		"details": {}
	}
}

details appears only when a field-level breakdown exists, such as validation failures.

Codes returned by POST /v1/sessions and GET /v1/usage:

CodeStatusMeaningAction
invalid_request400The request body or query failed validation.Fix the request; details.fieldErrors names each invalid field.
invalid_usage_period400period was not day or month.Send a supported period.
authentication_required401No API key was provided.Send the key as Authorization: Bearer or x-api-key.
invalid_api_key401The key is unknown or revoked.Mint a new key in the dashboard and update your server secret.
insufficient_scope403The key lacks the required scope.details.required names the missing scope; mint a key with it.
origin_not_allowed403parentOrigin is not registered for the project.Register the exact origin in the dashboard before minting sessions for it.
subscription_required403The owning account has no active SketchAPI subscription.Start a plan from the pricing page, then retry.
not_found404The route does not exist.Check the request path and method.
rate_limit_exceeded429Per-minute session creation limit reached.Wait retry-after seconds; the x-ratelimit-* headers describe the window.
monthly_session_limit_reached429Monthly session quota exhausted.Contact us to raise your plan limit, or wait for the next calendar month.
internal_error500Unexpected control-plane failure.Retry with backoff; contact support if it persists.
accounts_unavailable503Entitlement verification is temporarily unavailable.Retry with backoff.

Session creation also returns x-ratelimit-limit, x-ratelimit-remaining, and x-ratelimit-reset on success (201) and on minute-limited failure (429), so one code path can implement backoff.

Browser Client Errors

The browser client rejects with HostedSketchAPIError; read error.code:

import { HostedSketchAPIError, Sketchpad } from 'https://sketchapi.com/sdk/v1/sketchapi.js'

try {
	await sketchpad.mount(container)
} catch (error) {
	if (error instanceof HostedSketchAPIError && error.code === 'session_expired') {
		// Request a fresh session from your server and mount a new instance.
	}
}
CodeWhenAction
session_expiredThe session passed expiresAt before mount().Mint a fresh session; sessions gate mounting only.
session_unavailableThe instance no longer holds a session.Create a new Sketchpad with a new session.
session_token_in_urlThe session token appeared inside frameUrl.Never place the token in URLs; pass the session object untouched.
instance_destroyedA call arrived after destroy().Create a new instance; instances are single-use.
parent_window_unavailableThe host element is detached from a live window.Mount into a connected element.
frame_unavailableThe hosted frame lost its browsing context.Retry the mount with a fresh session.
frame_load_failedThe frame document failed to load.Check network access to sketchapi.com, then retry.
frame_timeoutThe frame did not finish loading in time.Retry; raise requestTimeoutMs for slow networks.
frame_handshake_timeoutThe frame loaded but never announced readiness.Retry; if persistent, check for frame-blocking extensions or CSP.
protocol_version_unsupportedThe cached client and hosted frame speak different protocol versions.Reload the page so the browser fetches the current client.
connection_timeoutThe frame channel did not connect in time.Retry the mount.
connection_closedThe frame connection ended, usually after a fatal frame error.Listen for onStateChange('destroyed') and remount with a fresh session.
request_timeoutOne API operation exceeded requestTimeoutMs.Retry the operation; raise the timeout for heavy work such as large imports.
message_errorA frame message failed to deserialize.Retry; report the payload to support if reproducible.

Session expiry never interrupts a mounted editor: expiresAt gates mounting only, and a user who is already drawing keeps working. There is no session renewal; remounting always uses a fresh session and a fresh Sketchpad instance.