Skip to content

Troubleshooting#

This guide covers common issues when working with the Storyteller Integration API and provides solutions to help you resolve them quickly.

Authentication Issues#

❌ "Invalid or missing API key"#

Symptoms:

  • HTTP 401 Unauthorized responses
  • Error message: "Invalid or missing API key"

Solutions: 1. Verify API key is correct:

# Test your API key with a simple request
curl -X GET "https://integrations.usestoryteller.com/api/workflows" \
  -H "x-storyteller-api-key: YOUR_API_KEY_HERE"

  1. Check header name: Ensure you're using x-storyteller-api-key, not Authorization

    // ✅ Correct
    headers: {
      'x-storyteller-api-key': 'your-api-key'
    }
    
    // ❌ Wrong
    headers: {
      'Authorization': 'Bearer your-api-key'
    }
    

  2. Verify API key scope: Contact [email protected] if you're unsure about your API key permissions

Media URL Issues#

❌ "Media URL is not accessible"#

Symptoms: - HTTP 400 Bad Request - Error message mentioning media URL accessibility - Workflow execution fails during validation

Solutions: 1. Test URL accessibility:

# Check if URL returns 200 OK
curl -I "https://your-domain.com/video.mp4"

# Should return:
# HTTP/1.1 200 OK
# Content-Type: video/mp4

  1. Common URL requirements:
  2. Must use HTTPS (not HTTP)
  3. Must be publicly accessible (no authentication required)
  4. Must return proper Content-Type headers
  5. File must exist and be downloadable

  6. Check file formats: Ensure your media format is supported

    // Supported formats
    const supportedVideoFormats = ['mp4', 'mov', 'avi'];
    const supportedImageFormats = ['jpg', 'jpeg', 'png'];
    

❌ "Media file too large"#

Symptoms: - Upload fails during processing - Timeout errors during workflow execution

Solutions: 1. Check file size limits: - Free accounts: 50MB per file - Pro accounts: 500MB per file - Enterprise: Custom limits

  1. Optimize media files:
    # Reduce video file size with ffmpeg
    ffmpeg -i input.mp4 -c:v libx264 -crf 28 -c:a aac -b:a 128k output.mp4
    

Workflow Execution Issues#

❌ "Required metadata missing"#

Symptoms: - HTTP 400 Bad Request - Error specifying missing metadata fields - Workflow validation fails

Solutions: 1. Check workflow requirements:

// Get workflow details including required metadata
const workflows = await fetch('/api/workflows');
const workflow = workflows.find(w => w.code === 'your-workflow');
console.log('Required metadata:', workflow.requiredMetadata);

  1. Ensure all required fields are provided:

    // ✅ Complete metadata
    const metadata = {
      'https://example.com/video.mp4': {
        'Title': 'Video Title',        // Usually required
        'Description': 'Description'   // Check workflow requirements
      }
    };
    

  2. Match field names exactly: Metadata field names are case-sensitive

❌ "Workflow not found"#

Symptoms: - HTTP 400 Bad Request - Error message: "Workflow 'xyz' not found or not available"

Solutions: 1. Use correct workflow codes:

// Get available workflow codes
const response = await fetch('/api/workflows');
const workflows = await response.json();
const availableCodes = workflows.map(w => w.code);
console.log('Available workflows:', availableCodes);

  1. Check spelling: Workflow codes are exact strings (e.g., 'add-media', not 'add_media')

Status Checking Issues#

❌ "Correlation ID not found"#

Symptoms: - HTTP 404 Not Found when checking status - Error: "Workflow execution not found for correlation ID"

Solutions: 1. Verify correlation ID format: Should be a valid UUID

// Valid correlation ID format
const correlationId = "12345678-1234-1234-1234-123456789012";

  1. Check timing: Status may not be immediately available

    // Wait a moment before first status check
    setTimeout(() => checkStatus(correlationId), 2000);
    

  2. Store correlation IDs properly: Don't modify or truncate the returned ID

❌ Workflow stuck in "Running" status#

Symptoms: - Status remains "Running" for extended periods - No progress updates in workflow steps

Solutions: 1. Check typical processing times: - Simple media addition: 30 seconds - 2 minutes - Complex workflows: 2-10 minutes - Large files: Longer processing times

  1. Contact support if workflows run longer than expected:
  2. Include correlation ID
  3. Include workflow codes executed
  4. Include media file details (size, format)

Webhook Issues#

❌ Webhooks not being received#

Symptoms: - No webhook calls to your endpoints - Missing workflow completion notifications

Solutions: 1. Verify webhook URL accessibility:

# Test webhook endpoint externally
curl -X POST "https://your-domain.com/webhooks/test" \
  -H "Content-Type: application/json" \
  -d '{"test": true}'

  1. Check HTTPS requirement: All webhook URLs must use HTTPS

    // ✅ Correct
    workflowProcessedWebhookUrl: "https://myapp.com/webhook"
    
    // ❌ Wrong
    workflowProcessedWebhookUrl: "http://myapp.com/webhook"
    

  2. Verify response codes: Webhooks must return 2xx status codes

    app.post('/webhook', (req, res) => {
      // Process webhook...
    
      // ✅ Return success status
      res.status(200).json({ received: true });
    });
    

❌ Webhook timeouts#

Symptoms: - Webhook retries from Storyteller - Missing webhook calls after initial attempts

Solutions: 1. Respond quickly: Return 200 status within 30 seconds

app.post('/webhook', async (req, res) => {
  // ✅ Respond immediately
  res.status(200).json({ received: true });

  // Process webhook data asynchronously
  setImmediate(() => processWebhook(req.body));
});

  1. Offload heavy processing: Move complex operations to background jobs

Network and Connectivity Issues#

❌ Connection timeouts#

Symptoms: - Request timeouts - Network errors during API calls

Solutions: 1. Implement retry logic:

async function apiCallWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      if (response.ok) return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
}

  1. Check firewall settings: Ensure outbound HTTPS is allowed
  2. Verify DNS resolution: Ensure integrations.usestoryteller.com resolves correctly

❌ SSL/TLS certificate errors#

Symptoms: - Certificate validation errors - SSL handshake failures

Solutions: 1. Update certificates: Ensure your system has up-to-date CA certificates 2. Check system time: Ensure server time is accurate 3. Test with curl:

curl -v "https://integrations.usestoryteller.com/api/workflows"

Data Format Issues#

❌ "Invalid JSON format"#

Symptoms: - HTTP 400 Bad Request - JSON parsing errors

Solutions: 1. Validate JSON structure:

// Use JSON.stringify to ensure valid JSON
const payload = {
  workflows: ['add-media'],
  mediaUrls: ['https://example.com/video.mp4'],
  metadata: {
    'https://example.com/video.mp4': {
      'Title': 'My Video'
    }
  }
};

const jsonString = JSON.stringify(payload);

  1. Check Content-Type header:
    headers: {
      'Content-Type': 'application/json',
      'x-storyteller-api-key': 'your-key'
    }
    

❌ "Invalid date format"#

Symptoms: - Date/timestamp parsing errors - Workflow execution failures

Solutions: 1. Use ISO 8601 format for all dates:

// ✅ Correct format
const timestamp = new Date().toISOString();
// "2025-01-15T10:30:00.000Z"

Error Response Examples#

All error responses follow the RFC 7807 Problem Details format.

Validation Error Response#

{
  "status": 400,
  "type": "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
  "title": "Bad Request",
  "detail": "Required metadata 'Title' missing for workflow 'add-media'",
  "instance": "correlation-id-here"
}

Authentication Error Response#

{
  "status": 401,
  "type": "https://datatracker.ietf.org/doc/html/rfc7235#section-3.1",
  "title": "Unauthorized",
  "detail": "No valid API key provided",
  "instance": ""
}

Not Found Error Response#

{
  "status": 404,
  "type": "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.4",
  "title": "Not Found",
  "detail": "The requested resource was not found",
  "instance": ""
}

Internal Server Error Response#

{
  "status": 500,
  "type": "https://datatracker.ietf.org/doc/html/rfc7231#section-6.6.1",
  "title": "Internal Server Error",
  "detail": "An unexpected error occurred",
  "instance": ""
}

Debugging Tips#

Enable Detailed Logging#

// Log all API requests and responses
async function debugApiCall(url, options = {}) {
  console.log('🚀 API Request:', {
    url,
    method: options.method || 'GET',
    headers: options.headers,
    body: options.body
  });

  try {
    const response = await fetch(url, options);
    const responseData = await response.json();

    console.log('✅ API Response:', {
      status: response.status,
      statusText: response.statusText,
      data: responseData
    });

    return { response, data: responseData };
  } catch (error) {
    console.error('❌ API Error:', error);
    throw error;
  }
}

Getting Help#

Before Contacting Support#

Gather this information: 1. Correlation ID (if applicable) 2. API key 3. Error messages (full text) 4. Request details (URL, headers, body) 5. Expected vs actual behavior 6. Timestamp when issue occurred

Contact Information#

API Support Information Template#

Subject: Integration API Issue - [Brief Description]

## Issue Details
- **Issue Type**: [Authentication/Workflow/Webhook/Other]
- **Error Message**: [Exact error message]
- **Correlation ID**: [If applicable]
- **Timestamp**: [When issue occurred]

## Request Information
- **Endpoint**: [URL called]
- **Method**: [GET/POST/etc.]
- **API Key**: [Last 4 characters only]

## Expected Behavior
[What you expected to happen]

## Actual Behavior
[What actually happened]

## Steps to Reproduce
1. [Step 1]
2. [Step 2]
3. [Step 3]

## Additional Context
[Any other relevant information]