### SSE format example Source: https://ruvicode.com/docs/streaming Shows the Server-Sent Events format where each line starts with data: and the stream ends with data: [DONE]. ```text data: {"choices":[{"delta":{"content":"Hello"}}]} data: {"choices":[{"delta":{"content":" world"}}]} data: {"choices":[{"finish_reason":"stop"}]} data: [DONE] ``` -------------------------------- ### Response: GET /v1/models JSON Source: https://ruvicode.com/docs/models Example response showing the list object and a model entry with fields like id, name, context_length, max_completion_tokens, and cache_read_price. ```json { "object": "list", "data": [ { "id": "glm-5.2", "object": "model", "name": "GLM 5.2", "created": 1754592000, "owned_by": "ruvicode", "context_length": 1000000, "max_completion_tokens": 128000, "cache_read_price": 0.0376 } ] } ``` -------------------------------- ### API key format example Source: https://ruvicode.com/docs/authentication Shows the format of a Ruvicode API key: starts with 'rvcd_' followed by 32 random hex characters. ```text rvcd_a1b2c3d4e5f6... ``` -------------------------------- ### Python streaming example Source: https://ruvicode.com/docs/streaming Streams chat completions in Python, printing each content delta as it arrives. ```python stream = client.chat.completions.create( model="glm-5.2", messages=[{"role": "user", "content": "Hello!"}], stream=True ) for chunk in stream: content = chunk.choices[0].delta.content if content: print(content, end="", flush=True) ``` -------------------------------- ### Node.js streaming example Source: https://ruvicode.com/docs/streaming Streams chat completions in Node.js, writing each content delta to stdout. ```javascript const stream = await client.chat.completions.create({ model: "glm-5.2", messages: [{ role: "user", content: "Hello!" }], stream: true, }); for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content; if (content) process.stdout.write(content); } ``` -------------------------------- ### X-Cost header example Source: https://ruvicode.com/docs/chat-completions Shows the X-Cost header included in non-streaming responses, indicating the exact charge in USD for the request. ```http X-Cost: 0.00000698 ``` -------------------------------- ### Request: GET /v1/models with curl Source: https://ruvicode.com/docs/models Public endpoint, no API key required. Returns the model catalog. ```bash curl https://api.ruvicode.com/v1/models ``` -------------------------------- ### Error format example Source: https://ruvicode.com/docs/error-handling Shows the standard error response format used by the Ruvicode API, following the OpenAI format. ```json { "error": { "message": "Human-readable error message", "type": "error_type" } } ``` -------------------------------- ### GET /v1/models Source: https://ruvicode.com/docs/models Returns a list of all models available on Ruvicode, including pricing, context window, and max output tokens. This endpoint is public and does not require an API key. ```APIDOC ## GET /v1/models ### Description Returns a list of all models available on Ruvicode, including pricing, context window, and max output tokens. This endpoint is public and does not require an API key. ### Method GET ### Endpoint /v1/models ### Request Example ``` curl https://api.ruvicode.com/v1/models ``` ### Response #### Success Response (200) - **object** (string) - Always "list" - **data** (array) - List of model objects - **id** (string) - Model id, the exact string to pass as `model` in requests - **object** (string) - Always "model" - **name** (string) - Display name for UIs - **created** (integer) - Creation timestamp - **owned_by** (string) - Always "ruvicode" - **context_length** (integer) - Context window in tokens - **max_completion_tokens** (integer) - Maximum output tokens - **cache_read_price** (number) - Price per 1M cached prompt tokens in USD, when the model supports prompt caching #### Response Example ``` { "object": "list", "data": [ { "id": "glm-5.2", "object": "model", "name": "GLM 5.2", "created": 1754592000, "owned_by": "ruvicode", "context_length": 1000000, "max_completion_tokens": 128000, "cache_read_price": 0.0376 } ] } ``` ``` -------------------------------- ### Python: Create chat completion with OpenAI SDK Source: https://ruvicode.com/docs/chat-completions Use the OpenAI Python SDK to send a chat completion request to Ruvicode. Set the api_key to your Ruvicode key (e.g., rvcd_...) and base_url to https://api.ruvicode.com/v1. The example uses model glm-5.2 and a simple user message. ```python from openai import OpenAI client = OpenAI(api_key="rvcd_...", base_url="https://api.ruvicode.com/v1") response = client.chat.completions.create( model="glm-5.2", messages=[{"role": "user", "content": "Hello!"}] ) ``` -------------------------------- ### Node.js: Create chat completion with OpenAI SDK Source: https://ruvicode.com/docs/chat-completions Use the OpenAI Node.js SDK to send a chat completion request to Ruvicode. Set apiKey to your Ruvicode key (e.g., rvcd_...) and baseURL to https://api.ruvicode.com/v1. The example uses model glm-5.2 and a simple user message. ```javascript import OpenAI from "openai"; const client = new OpenAI({ apiKey: "rvcd_...", baseURL: "https://api.ruvicode.com/v1" }); const response = await client.chat.completions.create({ model: "glm-5.2", messages: [{ role: "user", content: "Hello!" }], }); ``` -------------------------------- ### Authenticated curl request to chat completions Source: https://ruvicode.com/docs/authentication Example curl command to make an authenticated request to the chat completions endpoint. Requires a valid API key in the Authorization header. ```bash curl https://api.ruvicode.com/v1/chat/completions \ -H "Authorization: Bearer rvcd_..." \ -H "Content-Type: application/json" \ -d '{...}' ``` -------------------------------- ### Chat Completions response JSON Source: https://ruvicode.com/docs/chat-completions Example response from the Chat Completions API. Shows the assistant's reply, finish reason, and usage details including cached token counts. ```json { "id": "chatcmpl-...", "object": "chat.completion", "model": "glm-5.2", "choices": [{ "index": 0, "message": { "role": "assistant", "content": "2 + 2 = 4" }, "finish_reason": "stop" }], "usage": { "prompt_tokens": 25, "completion_tokens": 7, "total_tokens": 32, "prompt_cache_hit_tokens": 0, "prompt_tokens_details": { "cached_tokens": 0 } } } ``` -------------------------------- ### Account rate limit error response Source: https://ruvicode.com/docs/error-handling Example error response when the account-wide budget is exceeded. The message explicitly states that all keys share one requests-per-minute budget. ```json { "error": { "message": "Account rate limit exceeded. All of your keys share one requests-per-minute budget. Retry after 60 seconds.", "type": "rate_limit_error" } } ``` -------------------------------- ### Rate limit error response Source: https://ruvicode.com/docs/error-handling Example error response when the rate limit is exceeded. The message indicates retry after 60 seconds. ```json { "error": { "message": "Rate limit exceeded. Retry after 60 seconds.", "type": "rate_limit_error" } } ``` -------------------------------- ### 401 error response for invalid API key Source: https://ruvicode.com/docs/authentication Example JSON error response returned when authentication fails, such as an invalid or revoked API key. ```json { "error": { "message": "Invalid API key", "type": "authentication_error" } } ``` -------------------------------- ### Make your first request with curl Source: https://ruvicode.com/docs Use this curl command to send a chat completion request to Ruvicode's API. Replace 'rvcd_...' with your actual API key. The response includes an X-Cost header showing the charge. ```bash curl https://api.ruvicode.com/v1/chat/completions \ -H "Authorization: Bearer rvcd_..." \ -H "Content-Type: application/json" \ -d '{ "model": "glm-5.2", "messages": [{"role": "user", "content": "Hello!"}] }' ``` -------------------------------- ### Enable streaming with curl Source: https://ruvicode.com/docs/streaming Set stream:true in the request body to receive token-by-token output from the chat completions endpoint. ```bash curl https://api.ruvicode.com/v1/chat/completions \ -H "Authorization: Bearer rvcd_..." \ -H "Content-Type: application/json" \ -d '{ "model": "glm-5.2", "messages": [{"role": "user", "content": "Write a poem"}], "stream": true }' ``` -------------------------------- ### Tool call response with tool_calls Source: https://ruvicode.com/docs/chat-completions Shows the assistant message format when the model decides to call a tool. The response contains a tool_calls array with the function name and arguments. ```json { "choices": [{ "message": { "role": "assistant", "content": null, "tool_calls": [{ "id": "call_1", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\": \"Jakarta\"}" } }] }, "finish_reason": "tool_calls" }] } ``` -------------------------------- ### Send tool result back as tool role message Source: https://ruvicode.com/docs/chat-completions Shows how to continue the conversation after a tool call by sending the tool result as a tool role message. The assistant message with tool_calls is included, followed by the tool result and a user message. ```json { "model": "glm-5.2", "messages": [ {"role": "user", "content": "What's the weather in Jakarta?"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "call_1", "type": "function", "function": {"name": "get_weather", "arguments": "{\"city\": \"Jakarta\"}"}}]}, {"role": "tool", "tool_call_id": "call_1", "content": "30°C, sunny"}, {"role": "user", "content": "Great, thanks!"} ], "tools": [{"type": "function", "function": {"name": "get_weather", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}}}}] } ``` -------------------------------- ### POST /v1/chat/completions (streaming) Source: https://ruvicode.com/docs/streaming Enables token-by-token streaming responses by setting stream:true in the request body. The response is delivered as Server-Sent Events. ```APIDOC ## [POST] /v1/chat/completions ### Description Enables streaming of AI responses in real time using Server-Sent Events. Set `stream: true` in the request body to receive token-by-token output. ### Method POST ### Endpoint /v1/chat/completions ### Parameters #### Request Body - **model** (string) - Required - The model identifier, e.g., "glm-5.2". - **messages** (array) - Required - List of message objects, each with `role` and `content`. - **stream** (boolean) - Required - Set to `true` to enable streaming. ### Request Example ``` curl https://api.ruvicode.com/v1/chat/completions \ -H "Authorization: Bearer rvcd_..." \ -H "Content-Type: application/json" \ -d '{ "model": "glm-5.2", "messages": [{"role": "user", "content": "Write a poem"}], "stream": true }' ``` ### Response #### Success Response (200) Streaming response using Server-Sent Events. Each line starts with `data: ` and contains a JSON chunk. The stream ends with `data: [DONE]`. #### Response Example ``` data: {"choices":[{"delta":{"content":"Hello"}}]} data: {"choices":[{"delta":{"content":" world"}}]} data: {"choices":[{"finish_reason":"stop"}]} data: [DONE] ``` ### Notes - Usage information is included in the final SSE chunk before `[DONE]`. - Streaming responses do not include the `X-Cost` header; check the dashboard usage history for cost. - If the client disconnects mid-stream, the request may record zero tokens and not be billed. ``` -------------------------------- ### POST /v1/chat/completions Source: https://ruvicode.com/docs/chat-completions Creates a chat completion for the given messages. The endpoint accepts a model, messages, and optional max_tokens, and returns a completion with usage information. ```APIDOC ## POST /v1/chat/completions ### Description Creates a chat completion for the given messages. The endpoint accepts a model, messages, and optional max_tokens, and returns a completion with usage information. ### Method POST ### Endpoint https://api.ruvicode.com/v1/chat/completions ### Parameters #### Request Body - **model** (string) - Required - The model identifier, e.g., "glm-5.2". - **messages** (array) - Required - A list of message objects, each with a role (e.g., "system", "user") and content. - **max_tokens** (integer) - Optional - Maximum number of tokens to generate. ### Request Example ``` curl https://api.ruvicode.com/v1/chat/completions \ -H "Authorization: Bearer rvcd_..." \ -H "Content-Type: application/json" \ -d '{ "model": "glm-5.2", "messages": [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is 2+2?"} ], "max_tokens": 100 }' ``` ### Response #### Success Response (200) - **id** (string) - The completion ID. - **object** (string) - Always "chat.completion". - **model** (string) - The model used. - **choices** (array) - List of completion choices, each with index, message (role and content), and finish_reason. - **usage** (object) - Token usage details, including prompt_tokens, completion_tokens, total_tokens, prompt_cache_hit_tokens, and prompt_tokens_details.cached_tokens. #### Response Example ``` { "id": "chatcmpl-...", "object": "chat.completion", "model": "glm-5.2", "choices": [{ "index": 0, "message": { "role": "assistant", "content": "2 + 2 = 4" }, "finish_reason": "stop" }], "usage": { "prompt_tokens": 25, "completion_tokens": 7, "total_tokens": 32, "prompt_cache_hit_tokens": 0, "prompt_tokens_details": { "cached_tokens": 0 } } } ``` ### Additional Information #### Cached tokens in usage When a request reuses a prompt prefix that was already processed, the cached portion is billed at a lower cache read rate instead of the full input rate. Caching is automatic, there is no parameter to set. The usage object reports the split, and clients can read it from these fields: - `prompt_cache_hit_tokens`: Prompt tokens served from cache - `cached_tokens`: Same count, nested in `prompt_tokens_details` - `prompt_tokens` is always the full prompt token count, including cached tokens. #### Cost header Every non-streaming response includes an `X-Cost` header showing the exact charge in USD. This is the amount deducted from your wallet for this request. For streaming responses, headers are sent before generation starts, so your per-request cost appears in your dashboard usage history instead. Example header: ``` X-Cost: 0.00000698 ``` ``` -------------------------------- ### POST /v1/chat/completions Source: https://ruvicode.com/docs/chat-completions Sends a chat completion request to any AI model via the OpenAI-compatible endpoint. Accepts a list of messages and returns a model-generated response, with support for streaming, tool calls, vision, and JSON mode. ```APIDOC ## POST /v1/chat/completions ### Description Sends a chat completion request to any AI model via the OpenAI-compatible endpoint. Accepts a list of messages and returns a model-generated response, with support for streaming, tool calls, vision, and JSON mode. ### Method POST ### Endpoint https://api.ruvicode.com/v1/chat/completions ### Parameters #### Request Body - **model** (string) - Required - Model ID (e.g., `glm-5.2`) - **messages** (array) - Required - List of message objects - **stream** (boolean) - Optional - Enable streaming (default false) - **max_tokens** (number) - Optional - Max output tokens - **temperature** (number) - Optional - 0–2, default 1 - **top_p** (number) - Optional - Nucleus sampling, 0–1 - **stop** (array) - Optional - Sequences where generation stops - **seed** (number) - Optional - Deterministic sampling (model dependent) - **frequency_penalty** (number) - Optional - -2–2, penalizes repeated tokens - **presence_penalty** (number) - Optional - -2–2, penalizes new topic tokens - **response_format** (object) - Optional - `{"type":"json_object"}` or `{"type":"json_schema",...}` - **tools** (array) - Optional - Tool definitions (see Tool calling) - **tool_choice** (string|object) - Optional - Tool choice configuration - **parallel_tool_calls** (boolean) - Optional - Allow multiple tool calls per turn - **reasoning_effort** (string) - Optional - `low` / `medium` / `high` on reasoning models ### Parameter Pass-Through Any parameter not listed above is forwarded to the model provider verbatim. If a sampling parameter is absent from the request, it is omitted upstream rather than substituting a default, so the model applies its own. ### Request Example ```json { "model": "glm-5.2", "messages": [ { "role": "user", "content": "Hello!" } ] } ``` ### Response #### Success Response (200) - **id** (string) - Unique identifier for the completion - **object** (string) - Object type, e.g., `chat.completion` - **created** (number) - Unix timestamp of creation - **model** (string) - Model used - **choices** (array) - List of completion choices - **usage** (object) - Token usage details #### Response Example ```json { "id": "chatcmpl-123", "object": "chat.completion", "created": 1677652288, "model": "glm-5.2", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Hello! How can I help you?" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 9, "completion_tokens": 12, "total_tokens": 21 } } ``` ``` -------------------------------- ### Vision request with image URL Source: https://ruvicode.com/docs/chat-completions Shows how to pass an image by URL using the OpenAI content-block format. The content array contains a text block and an image_url block. ```json { "model": "kimi-k3", "messages": [{ "role": "user", "content": [ {"type": "text", "text": "What's in this image?"}, {"type": "image_url", "image_url": {"url": "https://example.com/photo.png"}} ] }], "max_tokens": 200 } ``` -------------------------------- ### curl request to Chat Completions API Source: https://ruvicode.com/docs/chat-completions Sends a chat completion request to the Ruvicode API using the glm-5.2 model. Requires an API key (rvcd_...) and includes a system and user message. ```bash curl https://api.ruvicode.com/v1/chat/completions \ -H "Authorization: Bearer rvcd_..." \ -H "Content-Type: application/json" \ -d '{ "model": "glm-5.2", "messages": [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is 2+2?"} ], "max_tokens": 100 }' ``` -------------------------------- ### Rate limit response headers Source: https://ruvicode.com/docs/error-handling Response headers that include rate limit information: X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After. ```http X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 Retry-After: 60 ``` -------------------------------- ### Tool-specific vision config with modalities Source: https://ruvicode.com/docs/chat-completions Shows the modalities declaration to add to vision model entries in tools like OpenCode and OpenClaw to allow image attachments. Models without the vision tag don't need it. ```json "modalities": { "input": ["text", "image"], "output": ["text"] } ``` -------------------------------- ### Retry with exponential backoff Source: https://ruvicode.com/docs/error-handling Python function to retry a call with exponential backoff for 429 and 503 errors. Sleeps 1s, 2s, 4s between attempts. ```python import time def retry_with_backoff(fn, max_retries=3): for attempt in range(max_retries): try: return fn() except Exception as e: if attempt == max_retries - 1: raise time.sleep(2 ** attempt) # 1s, 2s, 4s ``` -------------------------------- ### Chat Completions Endpoint URL Source: https://ruvicode.com/docs/chat-completions The endpoint for sending chat completion requests. It is OpenAI-compatible and accepts a list of messages. ```http POST https://api.ruvicode.com/v1/chat/completions ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.