Documentation
Troubleshooting

Troubleshooting Guide

Common issues and solutions when working with the Corridorly orchestration platform.


Authentication Errors

Missing or Invalid API Key

Symptoms

401 UnauthorizedNo authorization context found

Common Causes

  • X-Api-Key header not included in request
  • API key is revoked or expired
  • Using Sandbox API key in Production (or vice versa)

Solution

Verify your API key configuration:

  • 1.Check that X-Api-Key header is present in all requests
  • 2.Confirm API key is active in Corridorly dashboard (Settings > API Keys)
  • 3.Ensure you're using the correct API key for your environment (Sandbox vs Production)
  • 4.Verify your API key hasn't been rotated or revoked
// Correct API call with authentication headers
const response = await fetch(
'https://orchestrate.corridorly.com/symphony/execute/marketplace/smart_global_router',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': process.env.CORRIDORLY_API_KEY, // Required
'X-Tenant-Id': process.env.CORRIDORLY_TENANT_ID, // Required
},
body: JSON.stringify({ context: { /* ... */ } }),
}
);

Missing or Invalid Tenant ID

Symptoms

401 UnauthorizedNo authorization context foundInvalid tenant context

Common Causes

  • X-Tenant-Id header not included in request
  • Incorrect Tenant ID value

Solution

Verify your Tenant ID:

  • 1.Check that X-Tenant-Id header is present in all requests
  • 2.Find your Tenant ID in the Corridorly dashboard (Settings > General)
  • 3.Ensure Tenant ID matches your organization exactly

Request Validation Errors

Missing Context Object

Symptoms

400 Bad RequestRequest validation failedcontext is required

Common Causes

  • Request body missing required 'context' property
  • Empty context object
  • Malformed JSON

Solution

Symphony execution requests require a context object:

  • 1.Ensure request body includes a 'context' object
  • 2.Validate your JSON is well-formed
  • 3.Include all required fields for your symphony
// Correct request structure
{
"context": {
"amount": 9900,
"currency": "GBP",
"customer": {
"id": "cust_123",
"email": "customer@example.com",
"country": "GB"
}
}
}
// INCORRECT - missing context wrapper
{
"amount": 9900,
"currency": "GBP"
}

Invalid JSON in Request Body

Symptoms

400 Bad RequestUnexpected tokenJSON parse error

Common Causes

  • Malformed JSON syntax
  • Trailing commas
  • Unescaped special characters

Solution

Validate your JSON before sending:

  • 1.Use a JSON validator to check syntax
  • 2.Remove trailing commas from objects/arrays
  • 3.Properly escape quotes and special characters
  • 4.Use JSON.stringify() when building requests programmatically

Symphony Execution Errors

Symphony Not Found (404)

Symptoms

404 Not FoundSYMPHONY_NOT_FOUNDSymphony {id} not found

Common Causes

  • Symphony ID doesn't exist
  • Symphony not published to marketplace
  • Typo in symphony ID
  • Using instance symphony endpoint with marketplace ID

Solution

Verify symphony exists and you're using the correct endpoint:

  • 1.Check symphony ID spelling carefully
  • 2.Marketplace symphonies: POST /symphony/execute/marketplace/{symphonyId}
  • 3.Instance symphonies: POST /symphony/execute/instance/{symphonyId}
  • 4.Verify symphony is published and active in dashboard
// Marketplace symphony (like smart_global_router)
POST /symphony/execute/marketplace/smart_global_router
// Custom instance symphony
POST /symphony/execute/instance/your_custom_symphony_id

Subscription Required (403)

Symptoms

403 ForbiddenSUBSCRIPTION_REQUIREDActive subscription required

Common Causes

  • No active subscription for the symphony
  • Subscription expired
  • Symphony not included in your subscription tier

Solution

Check your symphony subscriptions:

  • 1.Go to Dashboard > Subscriptions
  • 2.Verify you have an active subscription for the symphony
  • 3.Check subscription status and expiry date
  • 4.Contact your account manager if subscription issues persist

Symphony Stage Failed

Symptoms

status: 'partial' or 'failed'Stage execution error in responseSome stages completed, others failed

Common Causes

  • Recipe execution error in a stage
  • Invalid data passed to recipe
  • Timeout in stage execution

Solution

Check symphony execution response for details:

  • 1.Examine the 'stages' array in the response
  • 2.Look for stages with status: 'failed'
  • 3.Check the 'error' object for specific error message
  • 4.Review 'decisions' object for context about what was attempted
  • 5.Check execution logs in dashboard for detailed trace
// Example error response
{
"executionId": "exec_abc123",
"symphonyId": "smart_global_router",
"status": "partial",
"stages": [
{
"stageNumber": 1,
"recipeId": "payment_routing",
"status": "complete",
"executionTimeMs": 234
},
{
"stageNumber": 2,
"recipeId": "fraud_check",
"status": "failed",
"error": {
"code": "EXECUTION_ERROR",
"message": "Fraud check service unavailable"
},
"executionTimeMs": 102
}
]
}

Webhook Delivery Issues

Webhook Signature Verification Failed

Symptoms

Invalid signatureSignature mismatchWebhook rejected

Common Causes

  • Using wrong webhook secret
  • Incorrect signature verification implementation
  • Timestamp drift (>5 minutes)

Solution

Verify webhook signature correctly:

  • 1.Get webhook secret from Corridorly dashboard (Settings > Webhooks)
  • 2.Implement HMAC-SHA256 verification correctly
  • 3.Check timestamp is within 5-minute window
  • 4.Verify you're using raw request body (not parsed JSON)
// Correct webhook verification
import crypto from 'crypto';
function verifyWebhook(payload, signature, timestamp, secret) {
// 1. Check timestamp (must be within 5 minutes)
const currentTime = Date.now();
const requestTime = parseInt(timestamp, 10);
if (Math.abs(currentTime - requestTime) > 300000) {
return false; // Timestamp too old/new
}
// 2. Create signed payload
const signedPayload = `${timestamp}.${payload}`;
// 3. Compute expected signature
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload, 'utf8')
.digest('hex');
// 4. Compare signatures (timing-safe)
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}
// In your webhook handler
app.post('/webhooks/corridorly', (req, res) => {
const signature = req.headers['x-corridorly-signature'];
const timestamp = req.headers['x-corridorly-timestamp'];
const payload = JSON.stringify(req.body); // Use raw body!
if (!verifyWebhook(payload, signature, timestamp, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook...
res.status(200).send('OK');
});

Webhook Not Received

Symptoms

No webhook deliveredMissing webhook events

Common Causes

  • Webhook URL not registered in dashboard
  • Endpoint not accessible (firewall, private network)
  • HTTPS not configured properly
  • Webhook disabled in settings

Solution

Verify webhook configuration:

  • 1.Check webhook URL is registered in Settings > Webhooks
  • 2.Ensure endpoint is publicly accessible via HTTPS
  • 3.Verify webhook is enabled (not paused)
  • 4.Test endpoint with webhook testing tool in dashboard
  • 5.Check webhook delivery logs for retry attempts

Webhook Endpoint Timeout

Symptoms

Webhook retry attemptsEndpoint timed out

Common Causes

  • Endpoint takes >10 seconds to respond
  • Slow processing in webhook handler
  • Blocking operations in request handler

Solution

Optimize webhook handler for fast response:

  • 1.Return 2xx status immediately (within 3 seconds)
  • 2.Process webhook payload asynchronously
  • 3.Use queue/background job for heavy processing
  • 4.Acknowledge receipt first, process later
// Good: Fast response
app.post('/webhooks/corridorly', async (req, res) => {
// 1. Verify signature
if (!verifyWebhook(...)) {
return res.status(401).send('Invalid signature');
}
// 2. Acknowledge immediately
res.status(200).send('OK');
// 3. Process asynchronously
processWebhookAsync(req.body).catch(err => {
console.error('Webhook processing error:', err);
});
});
// Bad: Slow response
app.post('/webhooks/corridorly', async (req, res) => {
await verifySignature(...);
await updateDatabase(...); // Slow!
await sendEmail(...); // Slow!
await callExternalAPI(...); // Slow!
res.status(200).send('OK'); // Too late!
});

Environment & Configuration

Wrong Environment URL

Symptoms

Connection refusedDNS resolution failed401 errors with valid credentials

Common Causes

  • Using production API key with sandbox URL
  • Using sandbox API key with production URL
  • Incorrect base URL in configuration

Solution

Verify you're using the correct environment URLs:

  • 1.Sandbox: https://orchestrate.sandbox.corridorly.com
  • 2.Production: https://orchestrate.corridorly.com
  • 3.Match API key environment with URL environment
  • 4.Check environment variables are set correctly
// Environment configuration
const API_URLS = {
sandbox: 'https://orchestrate.sandbox.corridorly.com',
production: 'https://orchestrate.corridorly.com',
};
const CORRIDOR_ENV = process.env.CORRIDORLY_ENV || 'production';
const API_KEY = process.env[`CORRIDORLY_API_KEY_${CORRIDOR_ENV.toUpperCase()}`];
const TENANT_ID = process.env[`CORRIDORLY_TENANT_ID_${CORRIDOR_ENV.toUpperCase()}`];
const baseUrl = API_URLS[CORRIDOR_ENV];

CORS Errors in Browser

Symptoms

CORS policy blockedNo 'Access-Control-Allow-Origin' header

Common Causes

  • Making API calls directly from browser
  • Missing CORS configuration

Solution

API calls must come from your backend:

  • 1.NEVER call Corridorly API directly from browser/client-side code
  • 2.Create a backend endpoint that calls Corridorly API
  • 3.Your backend forwards results to frontend
  • 4.This keeps API keys secure and avoids CORS issues
// CORRECT: Backend endpoint
// server.js (Node.js backend)
app.post('/api/process-payment', async (req, res) => {
const response = await fetch(
'https://orchestrate.corridorly.com/symphony/execute/marketplace/smart_global_router',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': process.env.CORRIDORLY_API_KEY, // Secure!
'X-Tenant-Id': process.env.CORRIDORLY_TENANT_ID,
},
body: JSON.stringify({ context: req.body }),
}
);
const result = await response.json();
res.json(result);
});
// WRONG: Direct browser call
// frontend.js - DO NOT DO THIS!
fetch('https://orchestrate.corridorly.com/...', {
headers: {
'X-Api-Key': 'your_key', // EXPOSED TO USERS!
}
});

Debugging Tips

Enable Request Logging

Log full request and response details to diagnose issues:

// Comprehensive request logging
const makeCorridorlyRequest = async (endpoint, body) => {
const url = `https://orchestrate.corridorly.com${endpoint}`;
const requestData = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': process.env.CORRIDORLY_API_KEY,
'X-Tenant-Id': process.env.CORRIDORLY_TENANT_ID,
},
body: JSON.stringify(body),
};
console.log('[Corridorly] Request:', {
url,
headers: { ...requestData.headers, 'X-Api-Key': '***' },
body,
});
try {
const response = await fetch(url, requestData);
const data = await response.json();
console.log('[Corridorly] Response:', {
status: response.status,
statusText: response.statusText,
data,
});
return { response, data };
} catch (error) {
console.error('[Corridorly] Error:', error);
throw error;
}
};

Check Execution Logs

Use the Corridorly dashboard to view detailed execution traces:

  • Go to Dashboard > Executions
  • Find your execution by ID or timestamp
  • View detailed stage-by-stage execution log
  • Check timing, decisions, and error messages
  • Export logs for deeper analysis

Test in Sandbox First

Always test changes in Sandbox before Production:

  • Use Sandbox environment for all testing
  • Sandbox URL: https://orchestrate.sandbox.corridorly.com
  • Create separate API keys for Sandbox and Production
  • Test error scenarios and edge cases
  • Verify webhook delivery and signature validation
  • Only promote to Production after thorough testing

Still Need Help?

If you cannot resolve your issue using this guide, contact our support team. Include your execution ID, request details, and error messages for faster resolution.