☁️ Streamkit API

Secure cloud storage for streaming configurations. Sync your text cyclers, source swaps, layouts, and notes across devices.

Edge-Powered 🔒 Multi-Tenant 🍪 SSO Ready 🎮 OBS Integration

✨ Features

📝

Text Cyclers

Store rotating text configurations for dynamic stream overlays. Cycle through messages, tips, and announcements.

🔄

Source Swaps

Save source swap configurations for quick scene transitions. Switch between cameras, games, and overlays.

📐

Layout Presets

Store layout presets with source positions, scales, and visibility. Perfect for multi-scene setups.

📋

Notes & Checklists

Keep stream notes, checklists, and reminders synced. Never forget your pre-stream routine.

📊

Scene Activity

Track scene usage with 30-day rolling analytics. See which scenes you use most often.

🔐

Customer Isolation

All data is isolated per customer. Your configs are yours alone, secured with JWT auth.

🔌 API Endpoints

📦 Generic Config API

One API for all config types: text-cyclers, swaps, layouts, notes

GET /configs/:type List all configs of a type
POST /configs/:type Create a new config
GET /configs/:type/:id Get a specific config
PUT /configs/:type/:id Update a config
DELETE /configs/:type/:id Delete a config

📊 Scene Activity API

Track scene usage with 30-day TTL (FIFO rolling)

POST /scene-activity/record Record a scene switch
GET /scene-activity/top Get top N most active scenes

💚 Health Check

GET /health Service health status

🏗️ Architecture

flowchart TB subgraph Client["🌐 Client"] SK["Streamkit App
(streamkit.idling.app)"] end subgraph Auth["🔐 Authentication"] OTP["OTP Auth Service
(auth.idling.app)"] Cookie["HttpOnly Cookie
(auth_token)"] end subgraph API["☁️ Streamkit API"] Worker["Cloudflare Worker
(streamkit-api.idling.app)"] JWT["JWT Verification"] Routes["Route Handler"] end subgraph Storage["💾 Storage"] KV["Cloudflare KV
(STREAMKIT_KV)"] end subgraph Data["📦 Data Types"] TC["Text Cyclers"] SW["Swaps"] LY["Layouts"] NT["Notes"] SA["Scene Activity"] end SK -->|"1. Login"| OTP OTP -->|"2. Set Cookie"| Cookie SK -->|"3. API Request
+ Cookie"| Worker Worker --> JWT JWT -->|"4. Verify"| Routes Routes -->|"5. Read/Write"| KV KV --> TC KV --> SW KV --> LY KV --> NT KV --> SA style SK fill:#252017,stroke:#edae49,color:#f9f9f9 style OTP fill:#252017,stroke:#6495ed,color:#f9f9f9 style Cookie fill:#252017,stroke:#28a745,color:#f9f9f9 style Worker fill:#252017,stroke:#edae49,color:#f9f9f9 style KV fill:#252017,stroke:#6495ed,color:#f9f9f9

💻 Code Examples

📝 List Text Cyclers

// Fetch all text cycler configs
const response = await fetch('https://streamkit-api.idling.app/configs/text-cyclers', {
  method: 'GET',
  credentials: 'include', // Include HttpOnly cookie
  headers: {
    'Content-Type': 'application/json',
  },
});

const data = await response.json();
console.log(data.configs); // Array of text cycler configs
console.log(data.count);   // Total count

➕ Create a Layout Preset

// Create a new layout preset
const response = await fetch('https://streamkit-api.idling.app/configs/layouts', {
  method: 'POST',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    id: 'gaming-layout-v1',
    name: 'Gaming Layout',
    sources: [
      { name: 'Game Capture', x: 0, y: 0, width: 1920, height: 1080 },
      { name: 'Webcam', x: 1600, y: 800, width: 320, height: 180 },
      { name: 'Chat', x: 0, y: 800, width: 400, height: 280 },
    ],
  }),
});

const result = await response.json();
console.log(result.configId); // 'gaming-layout-v1'

📊 Record Scene Activity

// Record a scene switch
const response = await fetch('https://streamkit-api.idling.app/scene-activity/record', {
  method: 'POST',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    sceneName: 'Gaming Scene',
  }),
});

// Get top scenes
const topResponse = await fetch('https://streamkit-api.idling.app/scene-activity/top?limit=5', {
  method: 'GET',
  credentials: 'include',
});

const topScenes = await topResponse.json();
console.log(topScenes.scenes); // [{ sceneName, count, lastUsed }, ...]

🔄 Update a Config

// Update an existing config
const response = await fetch('https://streamkit-api.idling.app/configs/text-cyclers/my-cycler-id', {
  method: 'PUT',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Updated Cycler Name',
    messages: ['Message 1', 'Message 2', 'Message 3'],
    interval: 30000, // 30 seconds
  }),
});

const result = await response.json();
console.log(result.message); // 'Config updated'

📖 Interactive API Documentation