Enterprise Video API Design
Enterprise APIs need patterns beyond CRUD. Long-running jobs, webhooks, rate limiting, and idempotency are table stakes. This guide covers what makes a video API enterprise-ready.
Idempotency
Every POST must be idempotent — retries should be safe:
Idempotency Keys
POST /v1/jobs
X-Idempotency-Key: customer-generated-uuid
# First request: creates job, returns job_id
# Retry with same key: returns same job_id, no duplicate
Implementation
- Hash the idempotency key
- Check if key exists in store
- If exists, return cached response
- If not, process request, store response with key
TTL
Idempotency keys should expire:
- Too short: legitimate retries fail
- Too long: storage bloat
- Recommendation: 24-48 hours
Webhook Design
Webhook Payload
{
"event": "job.completed",
"job_id": "job_abc123",
"timestamp": "2026-07-11T14:30:00Z",
"data": {
"status": "completed",
"output_url": "https://...",
"processing_time_ms": 45000
}
}
Security
Sign webhook payloads:
X-Signature: sha256=abc123...
# Verify:
expected = hmac_sha256(webhook_secret, raw_body)
if signature != expected:
reject()
Reliability
- Retry with exponential backoff (1s, 2s, 4s, 8s...)
- Maximum retries (e.g., 10)
- Failure notification to customer
- Manual retry endpoint
Timeout
Enforce timeout on webhook delivery:
- Connection: 5 seconds
- Response: 30 seconds
- Consider 2xx success, anything else retry
API Versioning
URL-Based Versioning
/v1/jobs → Current stable
/v2/jobs → Breaking changes
When to Version
New version for breaking changes:
- Removing fields
- Changing field types
- Changing behavior
Same version for additions:
- New optional fields
- New endpoints
- New parameters with defaults
Deprecation
- Announce deprecation (email, docs, headers)
- Deprecation period (6-12 months)
- Sunset date (hard removal)
Sunset: Sat, 1 Jan 2027 00:00:00 GMT
Deprecation: Sat, 1 Jul 2026 00:00:00 GMT
Rate Limiting
Rate Limit Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1625097600
Retry-After: 60
Tiered Limits
| Tier | Requests/min | Jobs/day |
|---|---|---|
| Free | 10 | 100 |
| Pro | 100 | 10,000 |
| Enterprise | 1,000 | Unlimited |
Graceful Degradation
When rate limited:
- Return 429 with Retry-After
- Don't drop request silently
- Consider queuing at limit (delayed execution)
Error Handling
Error Response Format
{
"error": {
"code": "video_too_long",
"message": "Video duration exceeds 10 minute limit",
"details": {
"duration_seconds": 725,
"max_seconds": 600
},
"request_id": "req_xyz789"
}
}
HTTP Status Codes
- 400: Bad request (invalid input)
- 401: Unauthorized (no/invalid auth)
- 403: Forbidden (valid auth, no permission)
- 404: Not found (job doesn't exist)
- 409: Conflict (idempotency key reused)
- 422: Unprocessable (valid JSON, invalid semantics)
- 429: Rate limited
- 500: Internal error (our fault)
- 503: Service unavailable (temporary)
Request IDs
Include in every response:
X-Request-ID: req_xyz789
Customers include this in support requests for tracing.
Frequently Asked Questions
Accept an X-Idempotency-Key header on POSTs. Store the key with the response. On retry with same key, return the stored response instead of re-processing.
Retry with exponential backoff (1s, 2s, 4s...), max 10 retries, then notify customer. Provide a manual retry endpoint.
Only for breaking changes: removing fields, changing types, changing behavior. Add new optional fields without versioning.
Ready to get started?
Try BetterVideo's privacy-first video enhancement API — free sandbox, no credit card required.