Quick Start Guide#
Get started with the Storyteller Integration API in minutes. This guide will walk you through your first successful workflow execution.
Prerequisites#
Before you begin, ensure you have:
- API Key - Contact [email protected] or get one from the Storyteller CMS
- Publicly accessible media URL - A video or image hosted online
- Development environment - Your preferred programming language setup
Step 1: Test Your API Key#
First, verify your API key works by fetching available workflows:
curl -X GET "https://integrations.usestoryteller.com/api/workflows" \
-H "x-storyteller-api-key: YOUR_API_KEY_HERE"
const fetch = require('node-fetch');
async function testConnection() {
const response = await fetch('https://integrations.usestoryteller.com/api/workflows', {
headers: {
'x-storyteller-api-key': 'YOUR_API_KEY_HERE'
}
});
if (response.ok) {
const workflows = await response.json();
console.log('ā
Connected! Available workflows:', workflows.map(w => w.code));
return workflows;
} else {
console.error('ā Connection failed:', await response.text());
}
}
testConnection();
import requests
def test_connection():
response = requests.get(
'https://integrations.usestoryteller.com/api/workflows',
headers={'x-storyteller-api-key': 'YOUR_API_KEY_HERE'}
)
if response.ok:
workflows = response.json()
print('ā
Connected! Available workflows:', [w['code'] for w in workflows])
return workflows
else:
print('ā Connection failed:', response.text)
test_connection()
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class ConnectionTester
{
private readonly HttpClient _httpClient;
public ConnectionTester(string apiKey)
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Add("x-storyteller-api-key", apiKey);
}
public async Task TestConnectionAsync()
{
try
{
var response = await _httpClient.GetAsync("https://integrations.usestoryteller.com/api/workflows");
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
var workflows = JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine("ā
Connected! Available workflows: " + workflows);
}
else
{
var error = await response.Content.ReadAsStringAsync();
Console.WriteLine("ā Connection failed: " + error);
}
}
catch (Exception ex)
{
Console.WriteLine($"ā Request failed: {ex.Message}");
}
}
}
// Usage
var tester = new ConnectionTester("YOUR_API_KEY_HERE");
await tester.TestConnectionAsync();
Expected Output:
ā
Connected! Available workflows: ['add-media', 'add-clip', 'add-to-story']
Step 2: Prepare Your Media#
You need a publicly accessible URL to a video or image file. For testing, you can use this sample video:
https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4
Media Requirements: - Must be accessible over HTTPS - Supported formats: MP4, MOV, AVI (video), JPG, PNG (images) - Must return proper HTTP status codes - Maximum file size depends on your account tier
Validate Your Media URL#
curl -I "https://your-domain.com/your-video.mp4"
Look for 200 OK status and appropriate Content-Type headers.
Step 3: Your First Workflow Execution#
Let's execute a simple workflow to add media to your Storyteller tenant:
const fetch = require('node-fetch');
async function executeFirstWorkflow() {
const payload = {
workflows: ['add-media'], // Use a workflow from step 1
mediaUrls: ['https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4'],
metadata: {
'https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4': {
'Title': 'My First Storyteller Video'
}
}
};
try {
const response = await fetch('https://integrations.usestoryteller.com/api/workflows/execute', {
method: 'POST',
headers: {
'x-storyteller-api-key': 'YOUR_API_KEY_HERE',
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (response.ok) {
const result = await response.json();
console.log('ā
Workflow started!');
console.log('Correlation ID:', result.correlationId);
return result.correlationId;
} else {
const error = await response.json();
console.error('ā Workflow failed:', error);
}
} catch (error) {
console.error('ā Request failed:', error);
}
}
executeFirstWorkflow();
import requests
import json
def execute_first_workflow():
payload = {
'workflows': ['add-media'], # Use a workflow from step 1
'mediaUrls': ['https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4'],
'metadata': {
'https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4': {
'Title': 'My First Storyteller Video'
}
}
}
try:
response = requests.post(
'https://integrations.usestoryteller.com/api/workflows/execute',
headers={
'x-storyteller-api-key': 'YOUR_API_KEY_HERE',
'Content-Type': 'application/json'
},
json=payload
)
if response.ok:
result = response.json()
print('ā
Workflow started!')
print('Correlation ID:', result['correlationId'])
return result['correlationId']
else:
error = response.json()
print('ā Workflow failed:', error)
except Exception as e:
print('ā Request failed:', e)
execute_first_workflow()
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class WorkflowExecutor
{
private readonly HttpClient _httpClient;
public WorkflowExecutor(string apiKey)
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Add("x-storyteller-api-key", apiKey);
}
public async Task<string> ExecuteFirstWorkflowAsync()
{
var payload = new
{
workflows = new[] { "add-media" },
mediaUrls = new[] { "https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4" },
metadata = new
{
[
"https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4"
] = new { Title = "My First Storyteller Video" }
}
};
try
{
var json = JsonConvert.SerializeObject(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(
"https://integrations.usestoryteller.com/api/workflows/execute",
content
);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<dynamic>(result);
Console.WriteLine("ā
Workflow started!");
Console.WriteLine($"Correlation ID: {data.correlationId}");
return data.correlationId;
}
else
{
var error = await response.Content.ReadAsStringAsync();
Console.WriteLine($"ā Workflow failed: {error}");
return null;
}
}
catch (Exception ex)
{
Console.WriteLine($"ā Request failed: {ex.Message}");
return null;
}
}
}
// Usage
var executor = new WorkflowExecutor("YOUR_API_KEY_HERE");
var correlationId = await executor.ExecuteFirstWorkflowAsync();
curl -X POST "https://integrations.usestoryteller.com/api/workflows/execute" \
-H "x-storyteller-api-key: YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"workflows": ["add-media"],
"mediaUrls": ["https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4"],
"metadata": {
"https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4": {
"Title": "My First Storyteller Video"
}
}
}'
Expected Output:
{
"correlationId": "12345678-1234-1234-1234-123456789012",
"message": "Workflow execution started",
"status": "processing"
}
Step 4: Check Workflow Status#
Use the correlation ID from step 3 to check the workflow progress:
async function checkWorkflowStatus(correlationId) {
try {
const response = await fetch(`https://integrations.usestoryteller.com/api/${correlationId}/status`, {
headers: {
'x-storyteller-api-key': 'YOUR_API_KEY_HERE'
}
});
if (response.ok) {
const status = await response.json();
console.log('š Workflow Status:');
status.forEach(workflow => {
console.log(` ${workflow.code}: ${workflow.status}`);
console.log(` Message: ${workflow.message}`);
workflow.steps.forEach(step => {
console.log(` ${step.name}: ${step.status}`);
if (step.locations) {
console.log(` š View in Storyteller:`, step.locations[0]);
}
});
});
return status;
} else {
console.error('ā Status check failed:', await response.text());
}
} catch (error) {
console.error('ā Request failed:', error);
}
}
// Use the correlation ID from step 3
checkWorkflowStatus('12345678-1234-1234-1234-123456789012');
def check_workflow_status(correlation_id):
try:
response = requests.get(
f'https://integrations.usestoryteller.com/api/{correlation_id}/status',
headers={'x-storyteller-api-key': 'YOUR_API_KEY_HERE'}
)
if response.ok:
status = response.json()
print('š Workflow Status:')
for workflow in status:
print(f' {workflow["code"]}: {workflow["status"]}')
print(f' Message: {workflow["message"]}')
for step in workflow['steps']:
print(f' {step["name"]}: {step["status"]}')
if 'locations' in step:
print(f' š View in Storyteller: {step["locations"][0]}')
return status
else:
print('ā Status check failed:', response.text)
except Exception as e:
print('ā Request failed:', e)
# Use the correlation ID from step 3
check_workflow_status('12345678-1234-1234-1234-123456789012')
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class StatusChecker
{
private readonly HttpClient _httpClient;
public StatusChecker(string apiKey)
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Add("x-storyteller-api-key", apiKey);
}
public async Task CheckWorkflowStatusAsync(string correlationId)
{
try
{
var response = await _httpClient.GetAsync(
$"https://integrations.usestoryteller.com/api/{correlationId}/status"
);
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
var status = JsonConvert.DeserializeObject<dynamic[]>(json);
Console.WriteLine("š Workflow Status:");
foreach (var workflow in status)
{
Console.WriteLine($" {workflow.code}: {workflow.status}");
Console.WriteLine($" Message: {workflow.message}");
foreach (var step in workflow.steps)
{
Console.WriteLine($" {step.name}: {step.status}");
if (step.locations != null && step.locations.Count > 0)
{
Console.WriteLine($" š View in Storyteller: {step.locations[0]}");
}
}
}
}
else
{
var error = await response.Content.ReadAsStringAsync();
Console.WriteLine($"ā Status check failed: {error}");
}
}
catch (Exception ex)
{
Console.WriteLine($"ā Request failed: {ex.Message}");
}
}
}
// Usage
var checker = new StatusChecker("YOUR_API_KEY_HERE");
await checker.CheckWorkflowStatusAsync("12345678-1234-1234-1234-123456789012");
# Check workflow status
curl -X GET "https://integrations.usestoryteller.com/api/12345678-1234-1234-1234-123456789012/status" \
-H "x-storyteller-api-key: YOUR_API_KEY_HERE"
# Pretty print JSON (if you have jq installed)
curl -X GET "https://integrations.usestoryteller.com/api/12345678-1234-1234-1234-123456789012/status" \
-H "x-storyteller-api-key: YOUR_API_KEY_HERE" | jq '.'
Expected Output:
š Workflow Status:
add-media: Finished
Message: Workflow successfully completed
Create Media Asset: Finished
š View in Storyteller: https://yourtenant.usestoryteller.com/assets/...
Step 5: Complete Example#
Here's a complete example that combines all the steps:
const fetch = require('node-fetch');
class StorytellerClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://integrations.usestoryteller.com';
}
async request(endpoint, options = {}) {
const response = await fetch(`${this.baseUrl}${endpoint}`, {
...options,
headers: {
'x-storyteller-api-key': this.apiKey,
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`API Error: ${error.message || response.statusText}`);
}
return response.json();
}
async getWorkflows() {
return this.request('/api/workflows');
}
async executeWorkflow(workflows, mediaUrls, metadata, webhooks = {}) {
return this.request('/api/workflows/execute', {
method: 'POST',
body: JSON.stringify({ workflows, mediaUrls, metadata, ...webhooks })
});
}
async getWorkflowStatus(correlationId) {
return this.request(`/api/${correlationId}/status`);
}
async waitForCompletion(correlationId, maxAttempts = 30, intervalMs = 5000) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
const status = await this.getWorkflowStatus(correlationId);
const allComplete = status.every(workflow =>
workflow.status === 'Finished' || workflow.status === 'Failed'
);
if (allComplete) {
return status;
}
console.log(`ā³ Attempt ${attempt}: Still processing...`);
if (attempt < maxAttempts) {
await new Promise(resolve => setTimeout(resolve, intervalMs));
}
}
throw new Error('Workflow did not complete within the timeout period');
}
}
// Usage
async function quickStartExample() {
const client = new StorytellerClient('YOUR_API_KEY_HERE');
try {
// 1. Get available workflows
console.log('š Getting available workflows...');
const workflows = await client.getWorkflows();
console.log('ā
Available workflows:', workflows.map(w => w.code));
// 2. Execute a workflow
console.log('\nš Executing workflow...');
const result = await client.executeWorkflow(
['add-media'],
['https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4'],
{
'https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4': {
'Title': 'Quick Start Example Video'
}
}
);
console.log('ā
Workflow started! Correlation ID:', result.correlationId);
// 3. Wait for completion
console.log('\nā³ Waiting for workflow to complete...');
const finalStatus = await client.waitForCompletion(result.correlationId);
console.log('\nš Workflow completed!');
finalStatus.forEach(workflow => {
console.log(`š ${workflow.code}: ${workflow.status}`);
workflow.steps.forEach(step => {
if (step.locations) {
console.log(`š View result: ${step.locations[0]}`);
}
});
});
} catch (error) {
console.error('ā Error:', error.message);
}
}
quickStartExample();
import requests
import time
import json
class StorytellerClient:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = 'https://integrations.usestoryteller.com'
self.headers = {
'x-storyteller-api-key': api_key,
'Content-Type': 'application/json'
}
def request(self, endpoint, method='GET', data=None):
response = requests.request(
method=method,
url=f'{self.base_url}{endpoint}',
headers=self.headers,
json=data
)
if not response.ok:
try:
error = response.json()
raise Exception(f"API Error: {error.get('message', response.text)}")
except ValueError:
raise Exception(f"API Error: {response.text}")
return response.json()
def get_workflows(self):
return self.request('/api/workflows')
def execute_workflow(self, workflows, media_urls, metadata, **webhooks):
payload = {
'workflows': workflows,
'mediaUrls': media_urls,
'metadata': metadata,
**webhooks
}
return self.request('/api/workflows/execute', 'POST', payload)
def get_workflow_status(self, correlation_id):
return self.request(f'/api/{correlation_id}/status')
def wait_for_completion(self, correlation_id, max_attempts=30, interval_seconds=5):
for attempt in range(1, max_attempts + 1):
status = self.get_workflow_status(correlation_id)
all_complete = all(
workflow['status'] in ['Finished', 'Failed']
for workflow in status
)
if all_complete:
return status
print(f'ā³ Attempt {attempt}: Still processing...')
if attempt < max_attempts:
time.sleep(interval_seconds)
raise Exception('Workflow did not complete within the timeout period')
# Usage
def quick_start_example():
client = StorytellerClient('YOUR_API_KEY_HERE')
try:
# 1. Get available workflows
print('š Getting available workflows...')
workflows = client.get_workflows()
print('ā
Available workflows:', [w['code'] for w in workflows])
# 2. Execute a workflow
print('\nš Executing workflow...')
result = client.execute_workflow(
['add-media'],
['https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4'],
{
'https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4': {
'Title': 'Quick Start Example Video'
}
}
)
print('ā
Workflow started! Correlation ID:', result['correlationId'])
# 3. Wait for completion
print('\nā³ Waiting for workflow to complete...')
final_status = client.wait_for_completion(result['correlationId'])
print('\nš Workflow completed!')
for workflow in final_status:
print(f'š {workflow["code"]}: {workflow["status"]}')
for step in workflow['steps']:
if 'locations' in step and step['locations']:
print(f'š View result: {step["locations"][0]}')
except Exception as error:
print(f'ā Error: {error}')
if __name__ == '__main__':
quick_start_example()
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class StorytellerClient
{
private readonly HttpClient _httpClient;
private readonly string _baseUrl = "https://integrations.usestoryteller.com";
public StorytellerClient(string apiKey)
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Add("x-storyteller-api-key", apiKey);
}
private async Task<T> RequestAsync<T>(string endpoint, HttpMethod method = null, object data = null)
{
method = method ?? HttpMethod.Get;
var request = new HttpRequestMessage(method, $"{_baseUrl}{endpoint}");
if (data != null)
{
var json = JsonConvert.SerializeObject(data);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
}
var response = await _httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
var error = await response.Content.ReadAsStringAsync();
throw new Exception($"API Error: {error}");
}
var responseContent = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseContent);
}
public async Task<dynamic[]> GetWorkflowsAsync()
{
return await RequestAsync<dynamic[]>("/api/workflows");
}
public async Task<dynamic> ExecuteWorkflowAsync(string[] workflows, string[] mediaUrls,
Dictionary<string, object> metadata, object webhooks = null)
{
var payload = new
{
workflows,
mediaUrls,
metadata
};
return await RequestAsync<dynamic>("/api/workflows/execute", HttpMethod.Post, payload);
}
public async Task<dynamic[]> GetWorkflowStatusAsync(string correlationId)
{
return await RequestAsync<dynamic[]>($"/api/{correlationId}/status");
}
public async Task<dynamic[]> WaitForCompletionAsync(string correlationId,
int maxAttempts = 30, int intervalMs = 5000)
{
for (int attempt = 1; attempt <= maxAttempts; attempt++)
{
var status = await GetWorkflowStatusAsync(correlationId);
bool allComplete = true;
foreach (var workflow in status)
{
if (workflow.status != "Finished" && workflow.status != "Failed")
{
allComplete = false;
break;
}
}
if (allComplete)
{
return status;
}
Console.WriteLine($"ā³ Attempt {attempt}: Still processing...");
if (attempt < maxAttempts)
{
await Task.Delay(intervalMs);
}
}
throw new Exception("Workflow did not complete within the timeout period");
}
}
// Usage
public class Program
{
public static async Task QuickStartExample()
{
var client = new StorytellerClient("YOUR_API_KEY_HERE");
try
{
// 1. Get available workflows
Console.WriteLine("š Getting available workflows...");
var workflows = await client.GetWorkflowsAsync();
Console.WriteLine("ā
Available workflows: " + string.Join(", ", workflows.Select(w => w.code)));
// 2. Execute a workflow
Console.WriteLine("\nš Executing workflow...");
var result = await client.ExecuteWorkflowAsync(
new[] { "add-media" },
new[] { "https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4" },
new Dictionary<string, object>
{
["https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4"] =
new { Title = "Quick Start Example Video" }
}
);
Console.WriteLine($"ā
Workflow started! Correlation ID: {result.correlationId}");
// 3. Wait for completion
Console.WriteLine("\nā³ Waiting for workflow to complete...");
var finalStatus = await client.WaitForCompletionAsync(result.correlationId);
Console.WriteLine("\nš Workflow completed!");
foreach (var workflow in finalStatus)
{
Console.WriteLine($"š {workflow.code}: {workflow.status}");
foreach (var step in workflow.steps)
{
if (step.locations != null && step.locations.Count > 0)
{
Console.WriteLine($"š View result: {step.locations[0]}");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"ā Error: {ex.Message}");
}
}
public static async Task Main(string[] args)
{
await QuickStartExample();
}
}
#!/bin/bash
# Complete workflow execution script
# Configuration
API_KEY="YOUR_API_KEY_HERE"
BASE_URL="https://integrations.usestoryteller.com"
MEDIA_URL="https://cdn.coverr.co/videos/coverr-overhead-view-of-the-highway-8903/1080p.mp4"
echo "š Getting available workflows..."
WORKFLOWS=$(curl -s -X GET "$BASE_URL/api/workflows" \
-H "x-storyteller-api-key: $API_KEY")
if [[ $? -eq 0 ]]; then
echo "ā
Available workflows: $WORKFLOWS"
else
echo "ā Failed to get workflows"
exit 1
fi
echo -e "\nš Executing workflow..."
RESULT=$(curl -s -X POST "$BASE_URL/api/workflows/execute" \
-H "x-storyteller-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"workflows\": [\"add-media\"],
\"mediaUrls\": [\"$MEDIA_URL\"],
\"metadata\": {
\"$MEDIA_URL\": {
\"Title\": \"Quick Start Example Video\"
}
}
}")
if [[ $? -eq 0 ]]; then
CORRELATION_ID=$(echo $RESULT | jq -r '.correlationId')
echo "ā
Workflow started! Correlation ID: $CORRELATION_ID"
else
echo "ā Failed to execute workflow"
exit 1
fi
echo -e "\nā³ Waiting for workflow to complete..."
MAX_ATTEMPTS=30
ATTEMPT=1
while [[ $ATTEMPT -le $MAX_ATTEMPTS ]]; do
STATUS=$(curl -s -X GET "$BASE_URL/api/$CORRELATION_ID/status" \
-H "x-storyteller-api-key: $API_KEY")
# Check if all workflows are finished or failed
COMPLETED=$(echo $STATUS | jq -r '.[].status' | grep -v -E "(Finished|Failed)" | wc -l)
if [[ $COMPLETED -eq 0 ]]; then
echo -e "\nš Workflow completed!"
echo "š Final Status: $STATUS"
# Extract and display any result locations
LOCATIONS=$(echo $STATUS | jq -r '.[].steps[] | select(.locations != null) | .locations[0]')
if [[ -n "$LOCATIONS" ]]; then
echo "š View results:"
echo "$LOCATIONS"
fi
break
fi
echo "ā³ Attempt $ATTEMPT: Still processing..."
sleep 5
((ATTEMPT++))
done
if [[ $ATTEMPT -gt $MAX_ATTEMPTS ]]; then
echo "ā Workflow did not complete within the timeout period"
exit 1
fi
Common Issues & Solutions#
ā "Invalid or missing API key"#
- Solution: Verify your API key is correct and included in the
x-storyteller-api-keyheader
ā "Media URL is not accessible"#
- Solution: Ensure your URL returns HTTP 200 and is publicly accessible
- Test: Run
curl -I "your-media-url"to check accessibility
ā "Workflow not found"#
- Solution: Use
GET /api/workflowsto see available workflow codes for your account
ā "Required metadata missing"#
- Solution: Check workflow requirements using
GET /api/workflows/{workflowId}and include all required metadata fields
Next Steps#
Now that you've successfully executed your first workflow, explore these advanced features:
šÆ Set Up Webhooks#
Instead of polling for status, receive real-time notifications:
const webhooks = {
workflowProcessedWebhookUrl: 'https://your-app.com/webhooks/success',
workflowFailedWebhookUrl: 'https://your-app.com/webhooks/failure'
};
š Organize Content#
Use categories and collections to organize your content:
// Get available categories
const categories = await client.request('/api/categories');
// Add category to metadata
const metadata = {
'https://example.com/video.mp4': {
'Title': 'My Video',
'categoryId': categories.categories[0].id
}
};
š Validate Before Execution#
Use the validation endpoint to catch issues early:
const validation = await client.request('/api/workflows/validate', {
method: 'POST',
body: JSON.stringify({ workflows, mediaUrls, metadata })
});
if (!validation.isValid) {
console.log('ā Validation errors:', validation.validationResults);
}
š Batch Processing#
Process multiple files efficiently:
const mediaUrls = [
'https://example.com/video1.mp4',
'https://example.com/video2.mp4',
'https://example.com/video3.mp4'
];
const metadata = {};
mediaUrls.forEach((url, index) => {
metadata[url] = { 'Title': `Video ${index + 1}` };
});
const result = await client.executeWorkflow(['add-media'], mediaUrls, metadata);
Documentation Links#
- Authentication - Complete API key setup guide
- Workflows - Detailed workflow documentation
- Webhooks - Real-time notification setup
- Troubleshooting - Common issues and solutions
Support#
Need help? We're here for you:
- Email: [email protected]
- Documentation Issues: GitHub Issues
- Status Page: status.storyteller.com
Congratulations! š You've successfully integrated with the Storyteller API. Your media is now available in your Storyteller tenant and ready to be used in your applications.