@creativekit/server
v1.0.23
Published
Server-side CreativeKit SDK with OAuth authentication
Maintainers
Readme
@creativekit/server
Server-side CreativeKit SDK with OAuth2 authentication
⚠️ Node.js only - Never expose to browsers
Quick Start
npm install @creativekit/serverimport { CreativeKitServer } from "@creativekit/server";
const ck = new CreativeKitServer({
apiBase: "https://api.creativekit.com",
clientId: process.env.CREATIVEKIT_CLIENT_ID!,
clientSecret: process.env.CREATIVEKIT_CLIENT_SECRET!,
});
// Create creative with presigned upload URL (AWS-style)
const creative = await ck.creatives.create("audio:podcast-aac");
// Return to frontend (client uploads directly to presigned URL)
// IMPORTANT: After upload, client must call commit to start processing
res.json({
creativeId: creative.id,
uploadUrl: creative.uploadSlots?.[0]?.url,
uploadHeaders: creative.uploadSlots?.[0]?.headers,
});
// Commit endpoint - triggers processing
await ck.creatives.commit(creative.id);API Reference
Creatives
// Create creative + get presigned URL (AWS-style)
const creative = await ck.creatives.create(profile, options);
// Options:
// multipart?: boolean - Use multipart upload for large files
// fileSize?: number - File size (required for multipart)
// metadata?: object - Custom metadata to attach
// autoFinalize?: boolean - Auto-finalize when processing succeeds (skip draft workflow)
// Commit after upload (starts processing)
await ck.creatives.commit(id);
// Get creative status and artifacts
const creative = await ck.creatives.get(id);
// Status values: "AWAITING_UPLOAD" | "QUEUED" | "PROCESSING" | "SUCCEEDED" | "FAILED" | "CANCELED"
// AWAITING_UPLOAD = created with directUpload, waiting for file upload + commit
// Progress is 0.0-1.0 (multiply by 100 for percentage)
// List creatives with filtering
const list = await ck.creatives.list({ status: "SUCCEEDED", limit: 20 });
// Options: status?, profile?, finalized?, limit?, pageToken?
// Finalize (mark as permanent, prevent auto-cleanup)
await ck.creatives.finalize(id);
// Generate preview URL for completed creative
const preview = await ck.creatives.preview(id);
// Returns: { url: string, expiresAt: number }
// Management
await ck.creatives.delete(id);
await ck.creatives.cancel(id);
await ck.creatives.retry(id);
// Server-side upload (Node.js scripts/workers)
const result = await ck.creatives.upload({ profile, files });
// SSE proxy to frontend (recommended)
await ck.creatives.getEventsStream(id, res);Auth (Client Token Generation)
Generate short-lived tokens for client-side use without exposing your client secret:
// Generate a scoped access token
const tokenData = await ck.auth.generateToken("creative:create creative:read creative:commit");
// Return to frontend
res.json({
token: tokenData.accessToken,
expiresIn: tokenData.expiresIn, // seconds
});Profiles
// List available processing profiles
const profiles = await ck.profiles.list();
// Returns: Profile[] with id, type, description, etc.Health
// Comprehensive health check (API + credentials)
const health = await ck.health.check();
// Returns: { isHealthy, apiReachable, credentialsValid, details }
// Basic connectivity test
const reachable = await ck.health.ping();
// Returns: boolean
// Validate OAuth credentials
const validation = await ck.health.validateCredentials();
// Returns: { valid: boolean, error?: string }Utils
// Check if client has valid credentials configured
const authenticated = ck.utils.isAuthenticated();
// Get current API configuration
const config = ck.utils.getConfig();
// Returns: { apiBase, hasCredentials }
// Get last known connection status
const status = ck.utils.getConnectionStatus();Debug
Troubleshooting methods for diagnosing authentication issues:
// Validate credentials with detailed error info
const result = await ck.debug.validateCredentials();
// Returns: { valid, error?, details? }
// Test API connection with diagnostics
const conn = await ck.debug.testConnection();
// Returns: { apiReachable, credentialsValid, responseTime?, error?, details? }
// Get current token information
const tokenInfo = await ck.debug.getTokenInfo();
// Returns: { hasCredentials, tokenCached, tokenExpiry?, error? }SSE Events Proxy
Proxy real-time processing events to your frontend with a single method call:
// NestJS
@Get(':id/events')
async streamEvents(@Param('id') id: string, @Res() res: Response) {
await ck.creatives.getEventsStream(id, res);
}
// Express
app.get('/creatives/:id/events', async (req, res) => {
await ck.creatives.getEventsStream(req.params.id, res);
});The SDK handles:
- ✅ SSE headers (Content-Type, Cache-Control, Connection)
- ✅ Terminal state detection (auto-closes on SUCCEEDED, FAILED, CANCELED)
- ✅ Automatic stream cleanup
- ✅ Client disconnect handling
- ✅ CORS headers (optional)
With CORS support and callbacks:
await ck.creatives.getEventsStream(id, res, {
corsOrigin: req.headers.origin,
onComplete: (status) => console.log(`Creative ${id}: ${status}`),
onError: (error) => console.error(`Stream error: ${error.message}`),
});Note: SSE events are minimal signals (
id,status,progress). Clients should callGET /creatives/:idfor full details on terminal states.
Finalize Workflow (Draft → Permanent)
Processed creatives start as "drafts" that can be previewed but will be automatically cleaned up after the draft TTL expires (default: 24h). To keep a creative permanently:
// After user reviews the preview and confirms
await ck.creatives.finalize(creativeId);
// Check finalization status
const creative = await ck.creatives.get(creativeId);
console.log(creative.finalized); // true
console.log(creative.finalizedAt); // timestamp in msWhy finalize?
- Cost control: Storage costs only for confirmed creatives
- User confirmation: Let users preview before committing
- Idempotent: Safe to call multiple times
Skip draft workflow with autoFinalize:
If you don't need user preview confirmation, auto-finalize on success:
const creative = await ck.creatives.create("video:web-1080p-h264", {
autoFinalize: true, // Automatically finalized when processing succeeds
});Express endpoint example:
app.post("/creatives/:id/finalize", async (req, res) => {
await ck.creatives.finalize(req.params.id);
res.status(204).send();
});Preview URLs
Generate signed preview URLs for completed creatives:
// Get a signed preview URL (expires after a period)
const { url, expiresAt } = await ck.creatives.preview(creativeId);
// Return to frontend for display
res.json({ previewUrl: url, expiresAt });Express endpoint example:
// Note: The SDK uses POST internally to generate the preview URL
app.post("/creatives/:id/preview", async (req, res) => {
const preview = await ck.creatives.preview(req.params.id);
res.json(preview);
});Full Documentation
See the main SDK documentation for:
- Complete API reference
- Architecture patterns
- Full examples (Express, Next.js, NestJS)
- Security best practices
- Troubleshooting
Security
- ✅ Use environment variables for credentials
- ✅ Never expose this SDK to browsers
- ✅ Keep
clientSecretsecure - ✅ Add auth middleware to your backend
License
MIT
