Videos
Initiate asynchronous video generation jobs from descriptive text prompts across supported provider models with sealed job handles and lifecycle polling.
Last updated
The /v1/videos endpoint initiates asynchronous video generation jobs from descriptive text prompts across cutting-edge video synthesis models like Google Veo and OpenAI Sora. Because video generation is compute-intensive and requires prolonged rendering times, nRouter provides an asynchronous job lifecycle: requests return an immediate sealed job ID, followed by status polling via GET /v1/videos/{id} and binary download via GET /v1/videos/{id}/content.
POST https://api.nrouter.ai/v1/videosImmediate HTTP 200 response with unique video job identifier for non-blocking execution.
Prompt content is inspected before placing duration credit holds. Blocked requests cost $0.
Settled at raw provider per-second video generation rates with zero token markup.
Every job returns correlation IDs, model identifiers, and exact USD spend.
Architectural Role & Asynchronous Lifecycle
Video synthesis workflows span multiple seconds or minutes of GPU processing. nRouter handles video workloads through a three-stage asynchronous pattern:
sequenceDiagram
autonumber
Client->>Gateway: POST /v1/videos (prompt, model, seconds)
Note over Gateway: Preflight: Key Auth, Rate Limits, Guardrails, Credit Hold
Gateway-->>Client: HTTP 200 { id: "nrouter_video_abc123", status: "queued" }
loop Poll Progress
Client->>Gateway: GET /v1/videos/nrouter_video_abc123
Gateway-->>Client: HTTP 200 { status: "processing", progress: 65 }
end
Client->>Gateway: GET /v1/videos/nrouter_video_abc123
Gateway-->>Client: HTTP 200 { status: "completed" }
Client->>Gateway: GET /v1/videos/nrouter_video_abc123/content
Gateway-->>Client: HTTP 200 (video/mp4 binary stream)- Phase 1: In-Memory Validation: Verifies virtual key hash (
sk-nrouter-...) and checks tenant permissions for the target video generation model. - Phase 2: Concurrency & Rate Limit Validation: Validates that the organization has available concurrent video rendering slots.
- Phase 3: Content Moderation & Injection Screening: Inspects the descriptive prompt against safety classifiers and prompt injection defenses. Blocked prompts halt with HTTP 400 (
x-nr-guardrails: blocked). - Phase 4: Duration Credit Reservation: Places an atomic hold based on requested duration (seconds) and resolution tier. Zero credits are held on preflight failures.
- Upstream Job Dispatch: Registers the job with the upstream provider and returns a sealed job object (
nrouter_video_...).
Request Parameters
The request body must be a JSON object:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
model | string | Yes | — | Model ID for video generation (e.g. veo-2.0, sora-1.0). |
prompt | string | Yes | — | Detailed text description of the scene, camera movement, subject action, lighting, and visual aesthetic. |
seconds | integer | No | 5 | Target duration of the generated video in seconds (supported values depend on provider, typically 5 to 10 seconds). |
size | string | No | 1280x720 | Output resolution (e.g. 1280x720, 1920x1080, 720x1280). |
fps | integer | No | 24 | Frame rate of the rendered video (typically 24 or 30 fps). |
seed | integer | No | — | Optional random seed for deterministic generation across runs. |
Response Payloads
Immediate Job Creation Response
{
"id": "nrouter_video_01j89azxckm3287",
"object": "video.generation",
"status": "queued",
"created": 1709251200,
"model": "veo-2.0"
}Response Field Breakdown
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the video generation job. Used to poll status and download content. |
object | string | Always "video.generation". |
status | string | Initial lifecycle state: "queued" or "processing". |
created | integer | Unix timestamp of when the job was accepted by the gateway. |
model | string | The video generation model handling the request. |
Headers Reference
Inbound Request Headers
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | Bearer authentication format: Bearer sk-nrouter-.... |
Content-Type | string | Yes | Must be application/json. |
x-nr-tags | string | No | Cost attribution metadata (e.g. project=marketing,asset=intro). |
Outbound Response Headers
| Header | Type | Description |
|---|---|---|
x-nr-request-id | string | Unique UUID correlation identifier for tracing. |
x-nr-latency-ms | integer | Gateway edge turnaround time for job registration. |
x-nr-request-cost | float | Estimated initial USD reservation for the video duration. |
x-nr-cost-status | string | exact when priced or unpriced if pending rate metadata. |
x-nr-model | string | Physical model assigned to render the video. |
x-nr-routing | string | Routing chain outcome: direct or fallback:<n>. |
x-nr-attempts | integer | Provider dispatch attempts made. |
x-nr-guardrails | string | Guardrail evaluation result: none, monitor, pass, or blocked. |
SDK Code Examples
import { nRouter } from "@nrouter_ai/sdk";
const client = new nRouter({
apiKey: process.env.NROUTER_API_KEY,
});
// 1. Submit video generation job
const job = await client.videos.create({
model: "veo-2.0",
prompt: "Cinematic drone shot soaring over mist-covered pine forests at dawn.",
seconds: 5,
size: "1280x720",
});
console.log(`Video job initiated: ${job.id} (Status: ${job.status})`);Error Handling & Troubleshooting
{
"error": {
"type": "gateway_error",
"message": "Requested duration of 30 seconds exceeds maximum supported duration of 10 seconds.",
"code": "invalid_request"
}
}| HTTP Status | Error Code | Cause | Recommended Action |
|---|---|---|---|
| 400 Bad Request | invalid_request | Missing required model or prompt, or invalid duration/resolution parameters. | Check model-specific constraints in the model catalog. |
| 400 Bad Request | guardrail_blocked | Prompt violated safety policies or triggered prompt injection classifiers. | Sanitize prompt content; $0 is charged on blocked calls. |
| 401 Unauthorized | invalid_api_key | Virtual key missing, expired, or invalid. | Check Authorization: Bearer sk-nrouter-... key in dashboard. |
| 402 Payment Required | insufficient_credits | Organization balance is insufficient to reserve duration hold. | Add credit balance via dashboard; minimum top-up is $5. |
| 404 Not Found | model_not_found | Requested video model is unrecognized or disabled for tenant. | Query GET /v1/models to confirm active provider catalog entitlements. |
| 429 Too Many Requests | rate_limit_exceeded | Concurrent video generation limit exceeded. | Await completion of running jobs before submitting new renders. |
| 500 / 503 Provider Error | service_unavailable | Upstream video rendering engine unavailable or overloaded. | nRouter automatically initiates fallback routing if alternative models are configured. |
Authorization
NRouterApiKey Your nRouter virtual key (sk-nrouter-…). Sent as Authorization: Bearer sk-nrouter-….
In: header
Header Parameters
Request prompt compression: on to compress eligible prompts, off to skip
Value in
- "on"
- "off"
Target MCP server ID when routing MCP tool calls or prompts through the gateway
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/videos" \ -H "Content-Type: application/json" \ -d '{ "model": "string", "prompt": "string" }'{ "id": "nrouter_video_abc123", "object": "video.generation", "status": "queued"}