Backend SDKs
Start jobs, update progress, and mark complete from your server.
Backend SDKs are for server-side use only. They use secret API keys (
sk_*) that should never be exposed to clients. For mobile/web clients, use the Client SDKs.
Producer vs Consumer Pattern
Backend SDKs act as producers that create and update jobs, while Client SDKs are consumers that listen for updates:
Backend SDK (Producer)
jobs.start() ──────┐
│
job.setProgress() ─┤
│
job.complete() ────┤
│
job.fail() ────────┘
WRITE operations
S
Seenn
Client SDK (Consumer)
┌───── subscribe(jobId)
│
├───── onProgress.listen()
│
├───── onComplete.listen()
│
└───── onFailed.listen()
READ operations
When to Use Backend SDK
✓ Use Backend SDK when:
- Starting async jobs (video generation, image processing, AI tasks)
- Reporting progress from your server
- Marking jobs as complete with results
- Marking jobs as failed with error details
- Integrating with workflow tools (n8n, Zapier, Temporal)
✗ Don't use Backend SDK for:
- Displaying progress in mobile/web apps → Use Client SDK
- Reading job status from browser → Use Client SDK
- Exposing API keys to clients → Security risk!
Node.js
TypeScript
Full TypeScript support with fluent API for job management.
npm install @seenn/node
Python
Async
Async support with sync wrappers for any Python backend.
pip install seenn
Quick Start
Here's a typical workflow using the backend SDK:
import { SeennClient } from '@seenn/node';
// 1. Initialize client with your secret key
const seenn = new SeennClient({
apiKey: process.env.SEENN_SECRET_KEY, // sk_live_xxx
});
// 2. Start a job when user triggers async work
async function generateVideo(userId: string, prompt: string) {
const job = await seenn.jobs.start({
userId,
jobType: 'video-generation',
title: 'Creating your video...',
metadata: { prompt },
});
// Return job ID to client
return job.id;
}
// 3. Update progress as processing continues
async function processVideo(jobId: string) {
const job = await seenn.jobs.get(jobId);
await job.setProgress(25, { message: 'Analyzing prompt...' });
// ... do work
await job.setProgress(50, {
message: 'Generating frames...',
stage: { name: 'generation', current: 2, total: 3 },
});
// ... do work
await job.setProgress(75, { message: 'Rendering video...' });
// ... do work
// 4. Complete with result
await job.complete({
result: { url: 'https://cdn.example.com/video.mp4' },
});
}
Authentication
Backend SDKs use secret API keys that start with sk_:
sk_live_xxx— Production keysk_test_xxx— Test/development key
Never expose secret keys to clients. Store them as environment variables and only use them in server-side code.
Core Concepts
Job Lifecycle
Every job goes through these states:
pending
→
running
→
completed
or
failed
Job Object
When you start or get a job, you receive a Job object with these properties:
| Property | Type | Description |
|---|---|---|
id |
string |
Unique job identifier |
userId |
string |
User who owns this job |
jobType |
string |
Type identifier (e.g., 'video-generation') |
title |
string |
Human-readable title |
status |
JobStatus |
Current state: pending | running | completed | failed |
progress |
number |
Progress percentage (0-100) |
message |
string? |
Current status message |
stage |
StageInfo? |
Current stage info (name, current, total) |
queue |
QueueInfo? |
Queue position info |
result |
JobResult? |
Result data (on completion) |
error |
JobError? |
Error details (on failure) |
metadata |
object? |
Custom metadata (max 10KB) |