Documentation

API endpoints & request patterns

Send synchronous or asynchronous AI requests through the unified ModelRiver endpoint. Get structured responses with full metadata.

Base configuration

SettingValue
Base URLhttps://api.modelriver.com
Primary endpointPOST /v1/ai
Async endpointPOST /v1/ai/async
AuthenticationAuthorization: Bearer mr_live_...
Content-Typeapplication/json

All requests require a valid project API key. Create and manage keys in your project settings.


Synchronous requests

Standard requests return the AI response immediately. Use this for real-time interactions like chatbots, search, or any use case where latency matters.

Endpoint: POST /v1/ai

Bash
curl -X POST https://api.modelriver.com/v1/ai \
-H "Authorization: Bearer mr_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"workflow": "marketing-summary",
"messages": [
{"role": "user", "content": "Summarise this week's launch."}
],
"metadata": {
"audience": "enterprise customers"
}
}'

Python example

PYTHON
1import requests
2 
3response = requests.post(
4 "https://api.modelriver.com/v1/ai",
5 headers={
6 "Authorization": "Bearer mr_live_your_key",
7 "Content-Type": "application/json"
8 },
9 json={
10 "workflow": "marketing-summary",
11 "messages": [
12 {"role": "user", "content": "Summarise this week's launch."}
13 ]
14 }
15)
16 
17data = response.json()
18print(data["data"])

Node.js example

JAVASCRIPT
1const response = await fetch("https://api.modelriver.com/v1/ai", {
2 method: "POST",
3 headers: {
4 "Authorization": "Bearer mr_live_your_key",
5 "Content-Type": "application/json",
6 },
7 body: JSON.stringify({
8 workflow: "marketing-summary",
9 messages: [
10 { role: "user", content: "Summarise this week's launch." }
11 ],
12 }),
13});
14 
15const data = await response.json();
16console.log(data.data);

Asynchronous requests

For long-running tasks (batch processing, complex workflows, event-driven pipelines), use the async endpoint. It returns a job ID immediately, and you receive the result via WebSocket or webhook.

Endpoint: POST /v1/ai/async

Bash
curl -X POST https://api.modelriver.com/v1/ai/async \
-H "Authorization: Bearer mr_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"workflow": "batch-processor",
"messages": [
{"role": "user", "content": "Process this large document..."}
]
}'

Async response (immediate)

JSON
1{
2 "message": "success",
3 "status": "pending",
4 "channel_id": "550e8400-e29b-41d4-a716-446655440000",
5 "websocket_url": "ws://api.modelriver.com/socket",
6 "websocket_channel": "ai_response:550e8400-e29b-41d4-a716-446655440000"
7}

WebSocket flow

  1. Connect to the WebSocket URL with your ws_token
  2. Join the channel ai_response:{project_id}:{channel_id}
  3. Listen for response events containing the final payload

Tip: Use the official Client SDK to handle WebSocket connections, reconnection, and progress tracking automatically.


Request fields

FieldRequiredDescription
workflowName of a saved workflow. Overrides provider and model
providerProvider name (required when not using workflows)
modelModel name (required when not using workflows)
messagesChat-style payload: array of {role, content} objects
temperatureSampling temperature (0–2), passed to provider
max_tokensMaximum tokens in response
top_pNucleus sampling parameter
streamtrue for SSE streaming (see Streaming)
format"raw" (default) or "wrapped" (see Response formats)
response_formatJSON schema for structured output (or use workflow's schema)
structured_output_schemaPass a JSON schema directly without creating a workflow
toolsArray of tool definitions for function calling
tool_choiceHow the model should use tools (auto, none, etc.)
inputsFree-form fields your workflow can access
metadataFree-form metadata (echoed via cache fields)
contextAdditional context passed to the provider

Response payload

Synchronous response (wrapped format)

JSON
1{
2 "data": { "summary": "..." },
3 "customer_data": { "metadata.audience": "enterprise customers" },
4 "meta": {
5 "status": "success",
6 "http_status": 200,
7 "workflow": "marketing-summary",
8 "requested_provider": "openai",
9 "requested_model": "gpt-4o-mini",
10 "used_provider": "openai",
11 "used_model": "gpt-4o-mini",
12 "duration_ms": 1420,
13 "usage": {
14 "prompt_tokens": 123,
15 "completion_tokens": 45,
16 "total_tokens": 168
17 },
18 "structured_output": true,
19 "attempts": [
20 {"provider": "openai", "model": "gpt-4o-mini", "status": "success"}
21 ]
22 },
23 "backups": [
24 {"position": 1, "provider": "anthropic", "model": "claude-3-5-sonnet"}
25 ]
26}

Response fields explained

FieldDescription
dataThe AI-generated response content
customer_dataCached fields echoed from your request metadata
meta.status"success" or "error"
meta.workflowThe workflow that processed this request
meta.used_providerThe provider that actually served the response
meta.duration_msEnd-to-end request duration in milliseconds
meta.usageToken consumption breakdown
meta.attemptsArray of all provider attempts (including failovers)
backupsConfigured fallback providers for this workflow

Error responses

ModelRiver returns 200 with an error object when the request was valid but the provider failed. Transport/authentication problems return standard HTTP status codes (401, 403, 429, 5xx).

JSON
1{
2 "data": null,
3 "customer_data": {},
4 "error": {
5 "message": "Provider request failed",
6 "details": {"status": 504, "message": "Upstream timeout"}
7 },
8 "meta": {
9 "status": "error",
10 "http_status": 502,
11 "workflow": "marketing-summary",
12 "attempts": [
13 {"provider": "openai", "model": "gpt-4o-mini", "status": "error", "reason": "timeout"}
14 ]
15 }
16}

For complete error handling details, see Error handling.


Tips for production use

  • Use workflows so you can change providers and prompts without redeploying applications
  • Leverage cache fields to echo request metadata in responses: especially helpful for tracing user IDs or experiment variants
  • Handle backups in the response if you need to know which fallback succeeded
  • Respect rate limits: if you see 429, implement exponential backoff or reach out to increase limits
  • Store responses if you need historical context: ModelRiver retains Request Logs, but you can export them or stream them elsewhere

Next steps