# OneOver — Full Developer Documentation Generated: 2026-10-09 Source: https://oneover.com/developers API base: https://api.oneover.com/functions/v1 OpenAPI: https://oneover.com/openapi.json MCP: https://api.oneover.com/functions/v1/mcp --- # OneOver Developer Docs OneOver is a self-serve API for frontier chat, image, video, and audio models. One `oo_live_` key, one credit pool, Stripe checkout when you run dry. **REST base:** `https://api.oneover.com/functions/v1` **Clean aliases:** `https://api.oneover.com/functions/v1/v1/chat` (and `/images`, `/video`, …) **OpenAI-compatible:** `https://api.oneover.com/functions/v1/openai-v1` **Auth:** `Authorization: Bearer oo_live_` **Idempotency:** send `Idempotency-Key` on every POST. **Live docs:** https://oneover.com/developers ## Endpoints | Method | Path | Scope | |--------|------|-------| | POST | api-v1-chat | chat | | POST | api-v1-images | images | | POST | api-v1-video | video | | GET | api-v1-video?request_id= | video | | POST | api-v1-audio | audio | | GET | api-v1-models | usage | | GET | api-v1-usage | usage | | POST | api-v1-files | files | | GET/POST | api-v1-apps | apps | | GET/DELETE | api-v1-assets | assets | | GET | api-v1-jobs | jobs | | GET/POST | api-v1-webhooks | webhooks | | POST | api-v1-billing | billing | ## Machine-readable - OpenAPI: https://oneover.com/openapi.json - MCP: https://oneover.com/developers/mcp.md - OpenAI compat: https://oneover.com/developers/openai.md ## Get a key Sign in and open https://oneover.com/developers/dashboard — a personal org is created on first visit and spends your existing account credits. Add the usual $5, $10, or $20 packs anytime. # Quickstart Make your first API call in minutes. Sign in at https://oneover.com/developers/dashboard — a personal org is created automatically. Send `Idempotency-Key` on POSTs so retries never double-charge. ## 1. Authenticate ``` Authorization: Bearer oo_live_YOUR_KEY # Optional: attribute spend to a team member X-Member-User-Id: ``` ## 2. Your first chat call ```bash curl -X POST "https://api.oneover.com/functions/v1/api-v1-chat" \ -H "Authorization: Bearer oo_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-5.6-sol","messages":[{"role":"user","content":"Hello"}]}' ``` ## 3. Streaming Set `"stream": true` for Server-Sent Events. Events: `connection_established`, `content`, `done`, `error`. ## 4. Generate an image ```bash curl -X POST "https://api.oneover.com/functions/v1/api-v1-images" \ -H "Authorization: Bearer oo_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"flux-2-pro","prompt":"A minimal logo","aspect_ratio":"1:1"}' ``` ## 5. List models and check balance ```bash curl "https://api.oneover.com/functions/v1/api-v1-models?type=text" \ -H "Authorization: Bearer oo_live_YOUR_KEY" curl "https://api.oneover.com/functions/v1/api-v1-usage?view=balance" \ -H "Authorization: Bearer oo_live_YOUR_KEY" ``` # Authentication Every request carries your organization's API key as a Bearer token. Keys are shown once at mint time and stored hashed server-side. ## Bearer token ``` Authorization: Bearer oo_live_ ``` Keys must start with `oo_live_`. Invalid format returns `401 invalid_key`. ## Member attribution For per-member soft limits and usage breakdowns, pass your internal user UUID: ``` X-Member-User-Id: ``` This does not forward identity to upstream model providers. ## Scopes | Scope | Endpoints | |-------|-----------| | `chat` | POST api-v1-chat | | `images` | POST api-v1-images | | `video` | POST api-v1-video, GET api-v1-video | | `audio` | POST api-v1-audio | | `usage` | GET api-v1-models, GET api-v1-usage | | `files` | GET/POST api-v1-files | | `apps` | GET/POST api-v1-apps | | `assets` | GET/DELETE api-v1-assets | | `jobs` | GET api-v1-jobs | | `webhooks` | GET/POST api-v1-webhooks | | `billing` | GET/POST api-v1-billing | Keys minted in the dashboard include this set. `jobs` also accepts a key that only has `video`. `billing` also accepts a key that only has `usage`. ## Model allowlists Keys can optionally be pinned to specific model IDs at mint time. ## Key hygiene - Store keys in a secrets manager, never in client-side source committed to git. - Rotate keys if exposed; revoke immediately in the admin console. - Use separate keys per environment (staging vs production). # Errors & Limits All errors use a consistent JSON envelope with a machine-readable `code` and `request_id` for support. ## Error envelope ```json { "error": { "code": "insufficient_credits", "message": "Insufficient credits", "request_id": "uuid" } } ``` ## Error codes | Code | Status | Meaning | |------|--------|---------| | unauthorized | 401 | Missing Authorization header | | invalid_key | 401 | Key does not start with oo_live_ | | key_not_found | 401 | Revoked or unknown API key | | org_inactive | 403 | Organization suspended or closed | | scope_denied | 403 | Key lacks the required scope | | model_not_allowed | 403 | Model outside your plan or key allowlist | | insufficient_credits | 402 | Not enough credits for the request | | rate_limit_exceeded | 429 | Per-key per-minute limit hit — retry after 60s | | validation_error | 400 | Malformed body or unsupported model for endpoint | | content_policy | 422 | Prompt blocked by content policy | | idempotency_conflict | 422 | Idempotency-Key reused with a different payload | | idempotency_in_progress | 409 | A request with this Idempotency-Key is still running | Send `Idempotency-Key` (8–256 chars) on POSTs. Replays return the stored response. 402s include `checkout_url`. Responses include `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`. 429s include `Retry-After`. ## Rate limits | Tier | Limit | |------|-------| | standard | 60 requests / minute / key | | elevated | 300 requests / minute / key | Exceeded limits return `429` with `rate_limit_exceeded`. # OpenAI-compatible API Point Cursor, Continue, Aider, LiteLLM, or any OpenAI SDK at OneOver. **Base URL:** `https://api.oneover.com/functions/v1/openai-v1` **API key:** your `oo_live_…` secret. Supported: - `POST /chat/completions` - `GET /models` - `POST /images/generations` ## Cursor 1. Settings → Models → OpenAI API Key → paste `oo_live_…` 2. Override OpenAI Base URL to `https://api.oneover.com/functions/v1/openai-v1` 3. Pick a model id from `GET api-v1-models` (for example `gpt-5.6-sol`) ## Python ```python from openai import OpenAI client = OpenAI( api_key="oo_live_YOUR_KEY", base_url="https://api.oneover.com/functions/v1/openai-v1", ) print(client.chat.completions.create( model="gpt-5.6-sol", messages=[{"role": "user", "content": "Hello"}], )) ``` Usage is billed to OneOver credits. A 402 includes `checkout_url`. # Webhooks Register HTTPS endpoints and receive HMAC-SHA256 signed events. **POST** `https://api.oneover.com/functions/v1/api-v1-webhooks` **Scope:** `webhooks` ```json { "url": "https://example.com/hooks/oneover", "events": ["job.completed", "job.failed", "credits.low"] } ``` ## Events that are sent | Event | When | |-------|------| | `job.completed` | A video job finishes successfully | | `job.failed` | A video job fails | | `credits.low` | A charge drops the org balance from at least 100 credits to under 100 | Images and audio finish inside the HTTP response. They do not emit `job.completed` or `job.failed`. The create response includes `secret` once. Verify: `X-OneOver-Signature: sha256=` over the raw JSON body. Retries use 30s / 2m / 10m / 1h / 6h backoff via `api-webhook-worker`. Disable an endpoint with `{ "action": "disable", "endpoint_id": "" }`. `GET` lists endpoints for the org. # OneOver MCP Server Connect AI agents to OneOver via the [Model Context Protocol](https://modelcontextprotocol.io/) (MCP). The server is remote HTTP. There is no package to install. It exposes the same Business API as tools — chat, image, video, audio, models, usage, apps, assets, jobs, and billing. ## Endpoint ``` https://api.oneover.com/functions/v1/mcp ``` **Transport:** Streamable HTTP (JSON-RPC 2.0) **Auth:** `Authorization: Bearer oo_live_` (same API key as the REST API) ## Tools | Tool | Scope | Description | |------|-------|-------------| | chat | chat | Stateless chat completion | | generate_image | images | Generate an image from a prompt | | generate_video | video | Submit async video job (returns request_id) | | check_video | video | Poll video job status | | generate_audio | audio | Speech or music generation | | list_models | usage | List org-visible models | | get_usage | usage | Balance or usage reporting | | run_app | apps | Run a Play app | | list_assets | assets | List library assets | | get_job | jobs | Poll a generation job | | create_topup | billing | Stripe Checkout URL | Video is async: call `generate_video`, then poll with `check_video` or `get_job` until status is `complete` or `failed`. Protocol: `2025-03-26` with negotiation for `2024-11-05`. ## Cursor Add to your MCP config (`.cursor/mcp.json` or Cursor Settings → MCP): ```json { "mcpServers": { "oneover": { "url": "https://api.oneover.com/functions/v1/mcp", "headers": { "Authorization": "Bearer oo_live_YOUR_KEY" } } } } ``` ## Claude Desktop Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS): ```json { "mcpServers": { "oneover": { "url": "https://api.oneover.com/functions/v1/mcp", "headers": { "Authorization": "Bearer oo_live_YOUR_KEY" } } } } ``` ## ChatGPT If your ChatGPT plan supports custom MCP connectors, add the same URL and Authorization header in Settings → Connectors. ## Claude Code ``` claude mcp add --transport http oneover https://api.oneover.com/functions/v1/mcp --header "Authorization: Bearer oo_live_YOUR_KEY" ``` ## Get a key Mint at https://oneover.com/developers/dashboard — a personal org is created automatically. New keys include the scopes these tools need. ## REST For REST integration without MCP, start at https://oneover.com/developers/quickstart.md or https://oneover.com/openapi.json. # Build an agent with OneOver Connect over HTTP. There is no package to install. 1. Mint a key at https://oneover.com/developers/dashboard 2. Call the REST API from the [quickstart](https://oneover.com/developers/quickstart.md), or connect MCP at `https://api.oneover.com/functions/v1/mcp` with `Authorization: Bearer oo_live_` 3. Call `GET api-v1-models` and pick a chat model 4. POST `api-v1-chat` with `tools` for function calling, or `web_search: true` 5. Persist outputs with `store: "library"` (default) so they appear in the owner's OneOver library 6. For video, poll `api-v1-jobs?request_id=` or subscribe to webhooks. Video emits `job.completed` and `job.failed`. Images and audio return in the HTTP response. 7. When you receive `402 insufficient_credits`, open `checkout_url` to add the usual $5 / $10 / $20 packs # API status Operational checks: - `GET https://api.oneover.com/functions/v1/health-check` - This page: https://oneover.com/developers/status Incident history is listed on the live status page in the developer docs. # Changelog ## 2026-09-14 — API platform - Self-serve personal orgs and `/developers/dashboard` - `Idempotency-Key` on POSTs - Reserve-then-settle billing, 402 `checkout_url` (personal accounts use the usual $5 / $10 / $20 packs) - Team/Business org packs and auto top-up stay on company orgs only - Library persist (`store`) - Files, apps, assets, jobs, webhooks - OpenAI-compatible `/openai-v1` and MCP protocol `2025-03-26` # Chat API **POST** `https://api.oneover.com/functions/v1/api-v1-chat` **Scope:** `chat` Stateless chat completions across every text model. Streaming and non-streaming. Prompts are not retained after the response. ## Request body | Field | Type | Required | Description | |-------|------|----------|-------------| | model | string | yes | Text model ID from your catalog | | messages | array | yes | `{ role, content }` turns | | stream | boolean | no | If true, returns SSE instead of JSON | | max_tokens | number | no | Optional completion budget cap | ## Response (non-streaming) ```json { "request_id": "uuid", "model": "gpt-5.6-sol", "message": { "role": "assistant", "content": "..." }, "credits_charged": 4, "balance": { "subscription": 14996, "anytime": 5000 }, "efficiency": { "original_estimated_tokens": 4200, "compacted_estimated_tokens": 2800, "tokens_saved": 1400, "actions": ["dropped_2_old_turns"] } } ``` ## Streaming events | Event | Description | |-------|-------------| | connection_established | Handshake with request_id | | content | Token chunk in content field | | done | Final event with credits_charged, balance, efficiency | | error | Failure during stream | # Images API **POST** `https://api.oneover.com/functions/v1/api-v1-images` **Scope:** `images` Generate images from text prompts. The call is synchronous: the image URLs are in the response. Images do not emit job webhooks. ## Request body | Field | Type | Required | Description | |-------|------|----------|-------------| | model | string | yes | Image model ID | | prompt | string | yes | Generation prompt | | negative_prompt | string | no | What to avoid | | aspect_ratio | string | no | e.g. `1:1`, `16:9` | | resolution_tier | string | no | `1k`, `2k`, or `4k` | | n | integer | no | How many images to generate, 1–4. Default 1. Credits are charged per image | | store | string | no | `library` (default), `url`, or `none`. `library` saves the result on the org owner's account | | mask | string | no | Base64-encoded mask for inpainting | | reference_image | string | no | One reference image, base64 or a URL the API can fetch | | reference_images | string[] | no | Additional reference images. Combined with `reference_image` | ## Response ```json { "request_id": "uuid", "model": "flux-2-pro", "image_url": "https://...", "image_urls": ["https://..."], "asset_ids": ["uuid"], "credits_charged": 6, "balance": { "subscription": 14994, "anytime": 5000 } } ``` `image_url` is the first image. `image_urls` is the full set when `n` is greater than 1. `asset_ids` is empty when `store` is not `library`. # Video API **POST** `https://api.oneover.com/functions/v1/api-v1-video` — submit job **GET** `https://api.oneover.com/functions/v1/api-v1-video?request_id=` — poll status **Scope:** `video` Async video generation. Submit a job, then poll every few seconds until `status` is `complete` or `failed`. ## Submit request body | Field | Type | Required | Description | |-------|------|----------|-------------| | model | string | yes | Video model ID | | prompt | string | usually | Generation prompt (optional for some models) | | duration | number | no | Duration in seconds | | resolution | string | no | e.g. `480p`, `720p` | | aspect_ratio | string | no | e.g. `wide` | | generate_audio | boolean | no | Include generated audio | | reference_image | string | no | Base64 reference image | | reference_video | string | no | Base64 reference video | | reference_audio | string | no | Base64 reference audio | ## Submit response ```json { "request_id": "uuid", "status": "processing", "model": "seedance-1.5-pro", "credits_estimate": 25 } ``` ## Poll response (complete) ```json { "request_id": "uuid", "status": "complete", "model": "seedance-1.5-pro", "video_url": "https://...", "credits_charged": 25, "balance": { "subscription": 14969, "anytime": 5000 } } ``` While running: `{ "status": "processing", "provider_status": "..." }`. # Audio API **POST** `https://api.oneover.com/functions/v1/api-v1-audio` **Scope:** `audio` Speech and music generation. ## Request body | Field | Type | Required | Description | |-------|------|----------|-------------| | model | string | yes | Audio model ID | | prompt | string | yes | Text to speak or music description | | audio_kind | string | no | `speech` (default) or `music` | | voice | string | no | Voice ID for speech | | speakers | array | no | Multi-speaker voice IDs | | speed | number | no | Speech speed multiplier | | music_style | string | no | Style hint for music | | duration_seconds | number | no | Target duration for music | ## Response ```json { "request_id": "uuid", "model": "gpt-4o-mini-tts", "audio_kind": "speech", "audio_url": "https://...", "credits_charged": 2, "balance": { "subscription": 14992, "anytime": 5000 } } ``` # Models API **GET** `https://api.oneover.com/functions/v1/api-v1-models` **Scope:** `usage` Returns the model catalog visible to your organization, filtered by plan and optional key allowlist. ## Query parameters | Param | Description | |-------|-------------| | type | Optional filter: `text`, `image`, or `video` | ## Response ```json { "request_id": "uuid", "org_id": "uuid", "org_plan": "org_business", "models": [ { "id": "gpt-5.6-sol", "name": "GPT 5.6 Sol", "type": "text", "provider": "OpenAI", "credits_per_request": 4 } ], "count": 42 } ``` # Usage API **GET** `https://api.oneover.com/functions/v1/api-v1-usage` **Scope:** `usage` Balance snapshot or usage reporting for your organization. ## Query parameters | Param | Description | |-------|-------------| | view | `balance` for credit snapshot; `usage` (default) for reporting | | days | Usage window in days (default 30, max 90) | | limit | Max requests returned (default 50, max 200) | ## Balance response (`?view=balance`) ```json { "org_id": "uuid", "plan": "org_team", "balance": { "subscription_credits": 12000, "anytime_credits": 5000, "total_credits": 17000, "subscription_credits_expire_at": "2026-08-12T00:00:00Z" }, "recent_ledger": [] } ``` ## Usage response Returns `summary`, `by_api_key`, `by_member`, and `requests` arrays. # Files `POST /api-v1-files` (scope `files`) Mint a `file_id` and a presigned S3 PUT URL. PUT the bytes, then use `file_id` / `url` as a reference on image and video jobs. ```json { "filename": "ref.png", "mime_type": "image/png" } ``` # Apps `GET /api-v1-apps` lists Play apps. `POST /api-v1-apps` runs one (`app_id`, `prompt`, optional `model`). # Assets **Scope:** `assets` `GET /api-v1-assets` lists library rows created by the API (`store: "library"`). | Query | Description | |-------|-------------| | `asset_id` | Return one asset instead of a page | | `limit` | Page size, 1–100. Default 20 | | `cursor` | Opaque cursor from the previous page's `next_cursor` | `GET /api-v1-assets?asset_id=` returns `{ asset }` for one row owned by the org. `DELETE /api-v1-assets?asset_id=` removes one owned by the org. `asset_id` is required. List responses include `assets`, `count`, and `next_cursor` (null on the last page). # Jobs **Scope:** `jobs` (a `video` key is also accepted) `GET /api-v1-jobs?request_id=` polls one video or other recorded generation. Omit `request_id` to list recent jobs for the org. | Query | Description | |-------|-------------| | `request_id` | One job | | `limit` | Page size, 1–100. Default 50 | | `cursor` | Opaque cursor from the previous page's `next_cursor` | List responses include `jobs` and `next_cursor` (null on the last page). Video completion is also delivered as `job.completed` / `job.failed` webhooks. # Billing `GET /api-v1-billing` returns `billing_mode`, the packs you can buy, and the current balance. `POST /api-v1-billing` Personal accounts use the same packs as Chat and Create: ```json { "action": "create_topup_session", "package_id": "credits_5" } ``` | package_id | Credits | Price | |------------|---------|-------| | credits_5 | 500 | $5 | | credits_10 | 1,000 | $10 | | credits_20 | 2,000 | $20 | Team and Business orgs use company packs (`org_credits_100`, `org_credits_500`, `org_credits_2000`) and optional auto top-up. Those are not required to use the API. Returns `checkout_url`. The same URL is attached to every `insufficient_credits` 402.