Docs

Call any provider through one endpoint

ModelRiver normalises request payloads, handles fallbacks, and returns structured metadata so your application stays simple.

Current section

API

Updated

This week

Build time

Minutes, not hours

Code snippet illustration for the ModelRiver API

Base configuration

  • Endpoint: https://api.modelriver.com/v1/ai
  • Authentication: Authorization: Bearer mr_live_... (project API key)
  • Content-Type: application/json

Synchronous requests

Standard requests return the AI response immediately. Use this for real-time interactions like chatbots or search.

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"
    }
  }'

Async requests

For long-running tasks, use the async endpoint. It returns a job ID immediately, and you receive the result via WebSocket or Webhook.

Endpoint: POST https://api.modelriver.com/v1/ai/async

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..."}
    ]
  }'

Response (Immediate)

{
  "message": "success",
  "status": "IN_PROGRESS",
  "channel_id": "550e8400-e29b-41d4-a716-446655440000",
  "websocket_url": "ws://api.modelriver.com/socket",
  "websocket_channel": "ai_response:550e8400-e29b-41d4-a716-446655440000"
}

WebSocket Flow

  1. Connect to the WebSocket URL.
  2. Join the channel ai_response:{channel_id}.
  3. Listen for success or error events containing the final payload.

Optional fields

  • workflow: name of a saved workflow. Overrides provider and model.
  • provider, model: required when not using workflows.
  • messages: chat-style payload (the most common format across providers).
  • response_format / structured_output_schema: pass a JSON schema directly if you do not want to create a workflow.
  • inputs, metadata, context: free-form fields your workflow can access. Add them to cache fields to surface in responses/logs.

Response payload

{
  "data": { "summary": "..." },
  "customer_data": { "metadata.audience": "enterprise customers" },
  "meta": {
    "status": "success",
    "http_status": 200,
    "workflow": "marketing-summary",
    "requested_provider": "openai",
    "requested_model": "gpt-4o-mini",
    "used_provider": "openai",
    "used_model": "gpt-4o-mini",
    "duration_ms": 1420,
    "usage": {
      "prompt_tokens": 123,
      "completion_tokens": 45,
      "total_tokens": 168
    },
    "structured_output": true,
    "attempts": [
      {"provider": "openai", "model": "gpt-4o-mini", "status": "success"}
    ]
  },
  "backups": [
    {"position": 1, "provider": "anthropic", "model": "claude-3-5-sonnet"}
  ]
}

Error payloads

  • 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).
{
  "data": null,
  "customer_data": {},
  "error": {
    "message": "Provider request failed",
    "details": {"status": 504, "message": "Upstream timeout"}
  },
  "meta": {
    "status": "error",
    "http_status": 502,
    "workflow": "marketing-summary",
    "attempts": [
      {"provider": "openai", "model": "gpt-4o-mini", "status": "error", "reason": "timeout"}
    ]
  }
}

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 logs, but you can export them or stream them elsewhere.