What is the SDK?
The Kittl SDK is the bridge between your sandboxed app and the editor host. It exposes async APIs through:
kittl.designfor design operationskittl.statefor editor/app statekittl.uploadfor image uploadskittl.authfor OAuth helper flows
These docs describe @kittl/[email protected]. Use the version selector to read another release. For every callable API and its fields, see the published API reference.
Add the SDK to your app
You can load the SDK in two ways.
Option 1: Package manager (recommended)
pnpm add @kittl/[email protected]
import { kittl } from '@kittl/sdk';
Option 2: Script tag
<script src="https://cdn.jsdelivr.net/npm/@kittl/[email protected]/dist/kittl-sdk.js"></script>
This URL loads the browser bundle from the exact npm release (0.0.5). Use window.kittl in this mode:
const { kittl } = window;
Wait for readiness
Call SDK APIs only after the bridge is ready:
import { kittl } from '@kittl/sdk';
kittl.onReady(async () => {
const result = await kittl.state.getSelectedObjectsIds();
if (result.isOk) {
console.log('Selected object IDs:', result.result);
}
});
Response format
Most async SDK calls return a SdkResult object: { isOk: true, result: T } on success, or { isOk: false, error: E } on failure. Check isOk and use result before accessing the value:
const addResult = await kittl.design.text.addText({ ... });
if (addResult.isOk) {
const text = addResult.result;
await kittl.state.setSelectedObjectsIds([text.id]);
}
Error types
For APIs that return SdkError (for example, most design APIs), the error property is a discriminated union you can narrow by error.name. Some SDK methods (e.g. font.createFont, ai.spendCredits) instead return a generic Error, so error.name should only be used as a discriminator when the specific API documents SdkError:
| Error Type | name | When |
|---|---|---|
SdkBadInputError | 'SdkBadInputError' | Invalid or missing parameters (validation failure) |
SdkInternalError | 'SdkInternalError' | Unexpected internal error in the SDK or host |
These SdkError variants extend Error and include message and an optional cause:
const result = await kittl.design.image.addImage({ ... });
if (!result.isOk) {
const { error } = result;
if (error.name === 'SdkBadInputError') {
console.error('Invalid input:', error.message);
} else if (error.name === 'SdkInternalError') {
console.error('Internal error:', error.message);
}
// Optionally inspect the underlying cause
if (error.cause) {
console.error('Caused by:', error.cause);
}
}
Async vs Sync results
The public kittl.design API uses async bridge wrappers, even when a host interface such as ShapeAPI declares a synchronous return type. Await the public call and inspect its SDK result. Subscription, lifecycle, and drag-and-drop helpers have their own return types; see the published API reference.
Minimal example
import { kittl } from '@kittl/sdk';
kittl.onReady(async () => {
const addResult = await kittl.design.text.addText({
text: 'Hello from my app',
position: { absolute: { left: 120, top: 120 } },
size: { width: 320, height: 80 },
});
if (addResult.isOk) {
await kittl.state.setSelectedObjectsIds([addResult.result.id]);
}
});
Image upload example
Use kittl.upload.image.upload to upload a blob, then add it to the canvas with kittl.design.image.addImage:
const uploadResult = await kittl.upload.image.upload({ blob });
if (uploadResult.isOk) {
const { objectName } = uploadResult.result[0];
await kittl.design.image.addImage({
src: objectName,
size: { width: 200, height: 200, applyViewportScale: false },
position: { relative: { to: 'viewport', location: 'center' } },
});
}
Notes
- The SDK is designed for sandboxed app frames.
- Bridge calls are async in app context; lifecycle and drag-and-drop helpers keep their published signatures.
- Declare required SDK permissions in your manifest
metadata.scopes; see SDK scopes.
Lifecycle Callback Property
kittl.onLoadedCallback is the nullable callback slot used by kittl.onReady(). Register readiness callbacks with onReady(); the SDK invokes the stored callback when it finishes loading.