Master error codes, debugging strategies, and retry patterns for production systems
All WAVE API errors follow a consistent format for easy parsing
{
"error": {
"code": "invalid_request",
"message": "Missing required field: title",
"details": [
{
"field": "title",
"issue": "required field missing",
"expected": "string (1-200 characters)"
}
],
"request_id": "req_abc123xyz789",
"documentation_url": "https://docs.wave.inc/api-reference/errors#invalid_request"
}
}X-Request-ID: req_abc123xyz789
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1705312800
Errors caused by invalid client requests - fix your request and retry
Errors from WAVE infrastructure - retry with exponential backoff
Incoming stream protocol does not match configured input
{"error": {"code": "STREAM_001", "message": "Expected RTMP but received SRT connection"}}Resolution:
Stream bitrate exceeds plan limits or configured maximum
{"error": {"code": "STREAM_002", "message": "Bitrate 15Mbps exceeds plan limit of 10Mbps"}}Resolution:
Maximum concurrent streams for your plan has been reached
{"error": {"code": "STREAM_003", "message": "5/5 concurrent streams active. Upgrade for more."}}Resolution:
Stream key is invalid, expired, or already in use
{"error": {"code": "STREAM_004", "message": "Stream key 'sk_live_xxx' is invalid or expired"}}Resolution:
Video or audio codec is not supported
{"error": {"code": "STREAM_005", "message": "VP9 codec not supported. Use H.264 or enable transcoding."}}Resolution:
Transcoding capacity temporarily exhausted
{"error": {"code": "TRANSCODE_001", "message": "Transcoding queue full. Retry in 30s."}}Resolution:
Specified transcoding profile does not exist or is misconfigured
{"error": {"code": "TRANSCODE_002", "message": "Profile '4k_ultra' not found"}}Resolution:
Source stream quality too low for requested output
{"error": {"code": "TRANSCODE_003", "message": "Cannot upscale 480p source to 1080p output"}}Resolution:
JWT or session token has expired
{"error": {"code": "AUTH_001", "message": "Token expired at 2024-01-15T10:00:00Z"}}Resolution:
API key does not have required scope for this operation
{"error": {"code": "AUTH_002", "message": "Scope 'analytics:read' required but not present"}}Resolution:
Request originated from IP address not in allowlist
{"error": {"code": "AUTH_003", "message": "IP 203.0.113.50 not in allowlist"}}Resolution:
Account has unpaid invoices blocking operations
{"error": {"code": "BILLING_001", "message": "Payment required. Invoice INV-2024-001 overdue."}}Resolution:
Resource usage has reached plan limits
{"error": {"code": "BILLING_002", "message": "500GB storage limit reached on Pro plan"}}Resolution:
Feature requires upgrade to access
{"error": {"code": "BILLING_003", "message": "Multi-region requires Enterprise plan"}}Resolution:
Uploaded file exceeds maximum size limit
{"error": {"code": "STORAGE_001", "message": "File size 15GB exceeds 10GB limit"}}Resolution:
File type not accepted for this endpoint
{"error": {"code": "STORAGE_002", "message": "File type 'application/x-rar' not accepted"}}Resolution:
Webhook delivery failed after all retries
{"error": {"code": "WEBHOOK_001", "message": "Delivery failed after 5 attempts to https://api.example.com/webhooks"}}Resolution:
Webhook signature verification failed
{"error": {"code": "WEBHOOK_002", "message": "Signature mismatch - possible replay attack"}}Resolution:
Showing 18 of 18 error codes
Battle-tested retry patterns with exponential backoff across all SDKs
import { WaveClient, WaveError } from '@wave/sdk';
const client = new WaveClient({
apiKey: process.env.WAVE_API_KEY!,
retry: {
maxAttempts: 3,
initialDelay: 1000,
maxDelay: 30000,
exponentialBase: 2,
jitter: 0.1, // 10% randomization
retryableStatuses: [408, 429, 500, 502, 503, 504],
},
});
// Custom retry handler for specific errors
async function createStreamWithRetry(data: CreateStreamInput) {
try {
return await client.streams.create(data);
} catch (error) {
if (error instanceof WaveError) {
if (error.code === 'rate_limit_exceeded') {
const retryAfter = error.headers['retry-after'];
console.log(`Rate limited. Retrying in ${retryAfter}s`);
await sleep(retryAfter * 1000);
return client.streams.create(data);
}
if (error.code === 'STREAM_003') {
// Max streams reached - notify user
throw new Error('Upgrade required for more streams');
}
}
throw error;
}
}| Parameter | Value | Description |
|---|---|---|
| maxAttempts | 3 | Total attempts including initial request |
| initialDelay | 1000ms | Wait time before first retry |
| maxDelay | 30000ms | Maximum wait between retries |
| exponentialBase | 2 | Multiplier for exponential backoff |
| jitter | 0.1 | Random variance (10%) to prevent thundering herd |
| retryableStatuses | [408, 429, 500, 502, 503, 504] | HTTP status codes to retry |
Quick commands for debugging common issues
Verify WAVE API is responding
curl -s https://api.wave.inc/v1/health | jq .
{
"status": "healthy",
"latency_ms": 12,
"region": "us-east-1",
"version": "2024.01.15"
}Check if your API key is valid and see its scopes
curl -s -H "Authorization: Bearer $WAVE_API_KEY" \ https://api.wave.inc/v1/auth/validate | jq .
{
"valid": true,
"key_id": "key_live_abc123",
"scopes": ["streams:read", "streams:write"],
"expires_at": null
}View your current rate limit consumption
curl -s -I -H "Authorization: Bearer $WAVE_API_KEY" \ https://api.wave.inc/v1/streams | grep -i "x-ratelimit"
x-ratelimit-limit: 1000 x-ratelimit-remaining: 847 x-ratelimit-reset: 1705312800
Fetch recent error events from your account
curl -s -H "Authorization: Bearer $WAVE_API_KEY" \ "https://api.wave.inc/v1/events?type=error&limit=10" | jq .
{
"data": [
{
"id": "evt_123",
"type": "stream.error",
"error_code": "STREAM_002",
"created_at": "2024-01-15T10:30:00Z"
}
]
}Send a test webhook to your endpoint
curl -X POST -H "Authorization: Bearer $WAVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://api.example.com/webhooks"}' \
https://api.wave.inc/v1/webhooks/test | jq .{
"success": true,
"response_time_ms": 245,
"status_code": 200
}Test stream connectivity and protocols
wave-cli stream debug --stream-id str_abc123
Stream ID: str_abc123 Protocol: RTMP Ingest: rtmp://ingest.wave.inc/live Status: CONNECTED Bitrate: 4500 kbps Codec: H.264/AAC Latency: 850ms
Every error includes a unique request_id for tracing.
logger.error('API error', { request_id: error.request_id })Use TypeScript types or JSON Schema validation client-side.
const validated = StreamSchema.parse(streamData)Set alerts for error rates above 5% or specific codes like 429.
Sentry, Datadog, Dash0, or CloudWatchInclude Idempotency-Key for safe retries.
Idempotency-Key: uuid-v4-generated-clientFail fast when services are unavailable to prevent cascade failures.
Open after 5 failures, half-open after 30sBefore debugging extensively, check for known incidents.
status.wave.inc - Subscribe for updatesResponse: 24-48 hours
Channels:
Features:
Response: 4-8 hours
Channels:
Features:
Response: < 1 hour (P1)
Channels:
Features:
Include request_id
From error response or logs
Describe expected vs actual
What should happen vs what did
Share minimal reproduction
Curl command or code snippet