{"components":{"responses":{},"schemas":{},"securitySchemes":{"bearer_auth":{"description":"Router API key obtained from the API Keys admin page. Pass as `Authorization: Bearer <token>`.","scheme":"bearer","type":"http"}}},"info":{"description":"LLM-gateway and Router admin API. Includes the OpenAI-compatible surface (/api/v1/chat/completions, /api/v1/embeddings, /api/v1/models) and the Router admin endpoints for billing, audit logs, and API key management (/api/router/v1/*). All endpoints require a :router-kind Bearer API key.","title":"Router API","version":"0.107.8"},"openapi":"3.0.0","paths":{"/api/router/v1/api_keys":{"get":{"callbacks":{},"description":"Returns all active + revoked keys belonging to your organization. The secret token is never returned.","operationId":"MeridianWeb.Api.V1.ApiKeysController.index","parameters":[],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"properties":{"expires_at":{"format":"date-time","nullable":true,"type":"string"},"id":{"type":"integer"},"inserted_at":{"format":"date-time","type":"string"},"is_active":{"type":"boolean"},"kind":{"enum":["router","meridian"],"type":"string"},"last_used_at":{"format":"date-time","nullable":true,"type":"string"},"name":{"type":"string"},"scope":{"enum":["standard","super_admin"],"type":"string"},"updated_at":{"format":"date-time","type":"string"},"user_id":{"type":"integer"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"API keys"}},"security":[{"bearer_auth":[]}],"summary":"List API keys for the authenticated organization","tags":["Router · API Keys"]},"post":{"callbacks":{},"description":"Creates a new API key attached to the authenticated organization +\nthe user associated with the calling key. Response includes the\n**raw token** in the `key` field — **this is the only time it is\nreturned.** Store it immediately.\n\nA standard-scope calling key cannot create super_admin keys.\n","operationId":"MeridianWeb.Api.V1.ApiKeysController.create","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"expires_at":{"description":"Optional — ISO-8601 expiration date","format":"date-time","type":"string"},"name":{"description":"Human-friendly identifier","example":"production","type":"string"},"scope":{"default":"standard","enum":["standard","super_admin"],"type":"string"}},"required":["name"],"type":"object"}}},"description":"Creation request","required":false},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"expires_at":{"format":"date-time","nullable":true,"type":"string"},"id":{"type":"integer"},"inserted_at":{"format":"date-time","type":"string"},"is_active":{"type":"boolean"},"kind":{"enum":["router","meridian"],"type":"string"},"last_used_at":{"format":"date-time","nullable":true,"type":"string"},"name":{"type":"string"},"scope":{"enum":["standard","super_admin"],"type":"string"},"updated_at":{"format":"date-time","type":"string"},"user_id":{"type":"integer"}},"type":"object"}}},"description":"Created"},"403":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Scope escalation blocked"},"422":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Validation error"}},"security":[{"bearer_auth":[]}],"summary":"Create a new API key","tags":["Router · API Keys"]}},"/api/router/v1/api_keys/{id}":{"delete":{"callbacks":{},"description":"Sets is_active=false on the key. Audit history is preserved; the key can no longer authenticate any request.","operationId":"MeridianWeb.Api.V1.ApiKeysController.delete","parameters":[{"description":"","in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"expires_at":{"format":"date-time","nullable":true,"type":"string"},"id":{"type":"integer"},"inserted_at":{"format":"date-time","type":"string"},"is_active":{"type":"boolean"},"kind":{"enum":["router","meridian"],"type":"string"},"last_used_at":{"format":"date-time","nullable":true,"type":"string"},"name":{"type":"string"},"scope":{"enum":["standard","super_admin"],"type":"string"},"updated_at":{"format":"date-time","type":"string"},"user_id":{"type":"integer"}},"type":"object"}}},"description":"Revoked"},"404":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Not found"}},"security":[{"bearer_auth":[]}],"summary":"Revoke an API key (soft delete)","tags":["Router · API Keys"]},"patch":{"callbacks":{},"description":"Only `name` and `expires_at` are mutable via the API. Scope and user_id are immutable.","operationId":"MeridianWeb.Api.V1.ApiKeysController.update","parameters":[{"description":"","in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"expires_at":{"format":"date-time","type":"string"},"name":{"type":"string"}},"type":"object"}}},"description":"Updatable fields","required":false},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"expires_at":{"format":"date-time","nullable":true,"type":"string"},"id":{"type":"integer"},"inserted_at":{"format":"date-time","type":"string"},"is_active":{"type":"boolean"},"kind":{"enum":["router","meridian"],"type":"string"},"last_used_at":{"format":"date-time","nullable":true,"type":"string"},"name":{"type":"string"},"scope":{"enum":["standard","super_admin"],"type":"string"},"updated_at":{"format":"date-time","type":"string"},"user_id":{"type":"integer"}},"type":"object"}}},"description":"Updated"},"404":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Not found"},"422":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Validation error"}},"security":[{"bearer_auth":[]}],"summary":"Update an API key (name, expires_at only)","tags":["Router · API Keys"]}},"/api/router/v1/audit":{"get":{"callbacks":{},"description":"Returns the most recent Guard audits for the authenticated\norganization, newest first. Supports pagination + filtering.\n\n## Query parameters\n\n  - `limit`        — max rows (default 50, cap 500)\n  - `offset`       — skip N (for pagination)\n  - `halted_only`  — `true` to only return blocked requests\n  - `min_severity` — `critical|high|medium|low`; at least one\n                     detection at or above this level\n  - `from`         — ISO-8601 lower bound on inserted_at (inclusive)\n  - `to`           — ISO-8601 upper bound (exclusive)\n","operationId":"MeridianWeb.Api.V1.GuardAuditController.index","parameters":[{"description":"Default 50, max 500","in":"query","name":"limit","required":false,"schema":{"type":"integer"}},{"description":"","in":"query","name":"offset","required":false,"schema":{"type":"integer"}},{"description":"","in":"query","name":"halted_only","required":false,"schema":{"type":"boolean"}},{"description":"","in":"query","name":"min_severity","required":false,"schema":{"enum":["critical","high","medium","low"],"type":"string"}},{"description":"ISO-8601 datetime","in":"query","name":"from","required":false,"schema":{"type":"string"}},{"description":"ISO-8601 datetime","in":"query","name":"to","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"type":"object"},"type":"array"},"meta":{"properties":{"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"retention_days":{"type":"integer"}},"type":"object"}},"type":"object"}}},"description":"Audit entries"}},"security":[{"bearer_auth":[]}],"summary":"List recent Guard audit entries","tags":["Router · Audit"]}},"/api/router/v1/audit/{request_id}":{"get":{"callbacks":{},"description":"Returns the Guard audit row for a specific Router request. `request_id`\nis the `generation_id` returned in the chat/completions response\n(available at `result.guard.request_id`) or the `stream-...`/`halt-...`\nid generated internally for streaming or halted requests.\n\n404 if not found or if the audit belongs to a different organization.\n","operationId":"MeridianWeb.Api.V1.GuardAuditController.show","parameters":[{"description":"The Router generation_id / audit request_id","in":"path","name":"request_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"detections":{"items":{"properties":{"category":{"enum":["pii","credential","secret","info","other"],"type":"string"},"detector":{"example":"regex:nas","type":"string"},"position_end":{"type":"integer"},"position_start":{"type":"integer"},"redacted_snippet":{"type":"string"},"severity":{"enum":["critical","high","medium","low"],"type":"string"}},"type":"object"},"type":"array"},"detections_count":{"type":"integer"},"halted":{"type":"boolean"},"inserted_at":{"format":"date-time","type":"string"},"policy_id":{"type":"integer"},"request_id":{"type":"string"}},"type":"object"}}},"description":"Audit entry with detections"},"404":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Audit not found"}},"security":[{"bearer_auth":[]}],"summary":"Get a Guard audit entry by request_id","tags":["Router · Audit"]}},"/api/router/v1/billing/balance":{"get":{"callbacks":{},"description":"Returns your organization's prepaid credit balance in CAD cents.","operationId":"MeridianWeb.Api.V1.BillingController.balance","parameters":[],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"balance_cents":{"description":"Balance in CAD cents","type":"integer"},"currency":{"example":"CAD","type":"string"}},"type":"object"}}},"description":"Balance"}},"security":[{"bearer_auth":[]}],"summary":"Current credit balance","tags":["Router · Billing"]}},"/api/router/v1/billing/models":{"get":{"callbacks":{},"description":"Returns every model routable through Router for your organization, with provider and pricing tier. Unrestricted organizations (default) see the whole synced OpenRouter catalog; restricted organizations only see their platform models.","operationId":"MeridianWeb.Api.V1.BillingController.models","parameters":[],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"models":{"items":{"properties":{"id":{"example":"claude-sonnet-4","type":"string"},"name":{"example":"Claude Sonnet 4","type":"string"},"provider":{"example":"anthropic","type":"string"},"tier":{"example":"balanced","type":"string"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"Models"}},"security":[{"bearer_auth":[]}],"summary":"List available models","tags":["Router · Billing"]}},"/api/router/v1/billing/usage":{"get":{"callbacks":{},"description":"Returns aggregated usage and a per-model breakdown for the current organization.","operationId":"MeridianWeb.Api.V1.BillingController.usage","parameters":[],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"by_model":{"description":"One entry per model used","items":{"type":"object"},"type":"array"},"summary":{"description":"Aggregate counts and totals (tokens, requests, cost)","type":"object"}},"type":"object"}}},"description":"Usage"}},"security":[{"bearer_auth":[]}],"summary":"Usage summary","tags":["Router · Billing"]}},"/api/router/v1/logs":{"get":{"callbacks":{},"description":"Returns recent log entries from the in-memory ring buffer. Requires a super admin API key.","operationId":"MeridianWeb.Api.V1.LogController.index","parameters":[{"description":"Filter by log level","in":"query","name":"level","required":false,"schema":{"enum":["debug","info","warning","error"],"type":"string"}},{"description":"Filter by message substring","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"Max entries to return (default 100, max 1000)","in":"query","name":"limit","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"type":"object"},"type":"array"},"meta":{"type":"object"}},"type":"object"}}},"description":"Log entries"}},"security":[{"bearer_auth":[]}],"summary":"Query log entries","tags":["Logs (Super Admin)"]}},"/api/router/v1/logs/stream":{"get":{"callbacks":{},"description":"Server-Sent Events endpoint for real-time log streaming. Requires a super admin API key. Connect with an SSE client (e.g. `curl -H 'Authorization: Bearer <key>' -N /api/router/v1/logs/stream`).","operationId":"MeridianWeb.Api.V1.LogController.stream","parameters":[{"description":"Filter streamed entries by log level","in":"query","name":"level","required":false,"schema":{"enum":["debug","info","warning","error"],"type":"string"}}],"responses":{"200":{"content":{"text/event-stream":{"schema":{"type":"string"}}},"description":"SSE stream"}},"security":[{"bearer_auth":[]}],"summary":"Stream log entries (SSE)","tags":["Logs (Super Admin)"]}},"/api/v1/chat/completions":{"post":{"callbacks":{},"description":"Generate a chat completion. Drop-in replacement for `POST https://api.openai.com/v1/chat/completions`.\n\nRoutes the request through Meridian's Router with Guard anti-exfiltration enabled. Supports `auto` model selection (Router picks the cheapest model meeting your quality bar) or an explicit model id (e.g. `claude-sonnet-4`, `gpt-5`).\n\nSet `stream: true` to receive server-sent events with OpenAI-compatible `chat.completion.chunk` payloads terminated by `data: [DONE]`.\n","operationId":"MeridianWeb.Api.V1.LlmController.create","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"max_tokens":{"example":1024,"type":"integer"},"messages":{"description":"Conversation messages, oldest first. `content` can be a string or an array of parts (vision multimodal).","items":{"properties":{"content":{"description":"String OR array of parts","oneOf":[{"type":"string"},{"items":{"properties":{"image_url":{"properties":{"detail":{"enum":["auto","low","high"],"type":"string"},"url":{"description":"HTTP(S) URL or data:image/... base64","type":"string"}},"type":"object"},"text":{"type":"string"},"type":{"enum":["text","image_url"],"type":"string"}},"type":"object"},"type":"array"}]},"role":{"enum":["system","user","assistant","tool"],"type":"string"},"tool_call_id":{"type":"string"}},"type":"object"},"type":"array"},"model":{"description":"Model id (e.g. `claude-sonnet-4`, `gpt-5`) or `auto`","example":"auto","type":"string"},"no_retention":{"default":false,"description":"When `true`, Router skips prompt persistence (Guard audit) and asks the provider not to retain or train on the request (`provider.data_collection = deny`). Models that cannot guarantee this are rejected with HTTP 400 instead of being served. Same effect via the `X-No-Retention: true` header.","type":"boolean"},"response_format":{"description":"Set `{\"type\": \"json_object\"}` for JSON mode, or `{\"type\": \"json_schema\", \"json_schema\": {\"name\": ..., \"schema\": {...}}}` for structured outputs. `json_schema` is enforced natively on OpenAI/Anthropic models and server-validated (HTTP 422 `schema_validation_failed`) on the others.","properties":{"json_schema":{"description":"Required when `type` is `json_schema`","properties":{"description":{"type":"string"},"name":{"type":"string"},"schema":{"type":"object"},"strict":{"type":"boolean"}},"type":"object"},"type":{"enum":["text","json_object","json_schema"],"type":"string"}},"type":"object"},"stream":{"default":false,"description":"When `true`, the response is streamed as Server-Sent Events with OpenAI-compat chunks","type":"boolean"},"strict":{"default":false,"description":"When `true`, disables Router's automatic model fallback. If the requested model is unavailable, the request fails (HTTP 502) instead of silently falling back to an alternative.","type":"boolean"},"system":{"description":"System prompt (alternative to embedding in messages)","type":"string"},"temperature":{"example":0.7,"maximum":2,"minimum":0,"type":"number"},"tool_choice":{"description":"How the model picks tools: `\"none\"`, `\"auto\"`, `\"required\"`, or `{\"type\": \"function\", \"function\": {\"name\": \"...\"}}`"},"tools":{"description":"Array of tool/function definitions available to the model (OpenAI-compat). `{\"type\": \"web_search\"}` and `{\"type\": \"fetch\"}` are Router server tools: executed by the Router during the conversation, reported in `tool_executions`.","items":{"type":"object"},"type":"array"}},"required":["messages"],"type":"object"}}},"description":"Chat completion request","required":false},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"billing":{"properties":{"cost_cad":{"description":"Exact billed CAD amount (decimal string, 6 places, never rounded to the cent)","type":"string"},"cost_cad_cents":{"type":"integer"},"currency":{"example":"CAD","type":"string"}},"type":"object"},"choices":{"items":{"properties":{"finish_reason":{"enum":["stop","length","tool_calls","content_filter"],"type":"string"},"message":{"properties":{"content":{"type":"string"},"role":{"type":"string"},"tool_calls":{"items":{"type":"object"},"type":"array"}},"type":"object"}},"type":"object"},"type":"array"},"model":{"description":"Model actually used","type":"string"},"usage":{"properties":{"cached_tokens":{"type":"integer"},"completion_tokens":{"type":"integer"},"prompt_tokens":{"type":"integer"},"total_tokens":{"type":"integer"}},"type":"object"}},"type":"object"}}},"description":"Completion result (non-streaming) or SSE stream (streaming)"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Insufficient credits"},"403":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"AI not enabled for organization"},"429":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Rate limited"},"502":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Upstream provider error"}},"security":[{"bearer_auth":[]}],"summary":"Chat completions (OpenAI-compatible)","tags":["Router · Chat"]}},"/api/v1/chat/completions/estimate":{"post":{"callbacks":{},"description":"Returns the expected CAD cost of a chat completion without actually\ncalling the upstream model. Uses a `char_count/4` heuristic for\nprompt tokens and the request's `max_tokens` as the completion\nbudget.\n\nUseful for UI budget checks or for clients that need to price per\nrequest before consenting to the actual call.\n\nPricing reflects the organization's current markup + FX rate.\n","operationId":"MeridianWeb.Api.V1.LlmController.estimate","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"max_tokens":{"default":1000,"type":"integer"},"messages":{"items":{"type":"object"},"type":"array"},"model":{"example":"auto","type":"string"},"system":{"type":"string"}},"required":["messages"],"type":"object"}}},"description":"Estimate request (same shape as chat/completions)","required":false},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"cost_cad_cents":{"type":"integer"},"disclaimer":{"type":"string"},"estimated_prompt_tokens":{"type":"integer"},"max_completion_tokens":{"type":"integer"},"model":{"type":"string"}},"type":"object"}}},"description":"Estimate"}},"security":[{"bearer_auth":[]}],"summary":"Estimate cost of a chat completion (preflight, no upstream call)","tags":["Router · Chat"]}},"/api/v1/classify":{"post":{"callbacks":{},"description":"Deterministic classification with scores. `single` returns probabilities\nsumming to 1; `multi` returns independent 0..1 scores; `binary` answers a\nyes/no question. Billed at the real cost of the underlying scoring call.\n","operationId":"MeridianWeb.Api.V1.ClassifyController.create","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"input":{"example":"QO120","type":"string"},"mode":{"enum":["single","multi","binary"],"type":"string"},"model":{"example":"typesafe/jev-router","type":"string"},"options":{"description":"1..255 entries. Required in single/multi mode.","items":{"properties":{"id":{"type":"string"},"label":{"type":"string"}},"required":["id","label"],"type":"object"},"type":"array"},"question":{"description":"Required in binary mode","type":"string"}},"required":["model","input","mode"],"type":"object"}}},"description":"Classify request","required":false},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"answer":{"type":"boolean"},"billing":{"type":"object"},"id":{"type":"string"},"model":{"type":"string"},"score":{"type":"number"},"scores":{"items":{"type":"object"},"type":"array"},"top":{"type":"string"},"usage":{"type":"object"}},"type":"object"}}},"description":"Classification result"}},"security":[{"bearer_auth":[]}],"summary":"Classify text against labels (typesafe/jev-router)","tags":["Router · Classify"]}},"/api/v1/embeddings":{"post":{"callbacks":{},"description":"Generate vector embeddings for a string or a list of strings.\nDrop-in replacement for `POST https://api.openai.com/v1/embeddings`.\n\nDefault model is `openai/text-embedding-3-small`. Specify `model`\nexplicitly to use another embeddings model (e.g.\n`openai/text-embedding-3-large`, `cohere/embed-multilingual-v3.0`).\n","operationId":"MeridianWeb.Api.V1.EmbeddingsController.create","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"input":{"description":"String or array of strings to embed","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]},"model":{"description":"Embeddings model id","example":"openai/text-embedding-3-small","type":"string"}},"required":["input"],"type":"object"}}},"description":"Embeddings request","required":false},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"billing":{"properties":{"cost_cad":{"description":"Exact billed CAD amount (decimal string, 6 places, never rounded to the cent)","type":"string"},"cost_cad_cents":{"type":"integer"},"currency":{"example":"CAD","type":"string"}},"type":"object"},"data":{"items":{"properties":{"embedding":{"items":{"type":"number"},"type":"array"},"index":{"type":"integer"},"object":{"example":"embedding","type":"string"}},"type":"object"},"type":"array"},"model":{"type":"string"},"object":{"example":"list","type":"string"},"usage":{"properties":{"cached_tokens":{"type":"integer"},"completion_tokens":{"type":"integer"},"prompt_tokens":{"type":"integer"},"total_tokens":{"type":"integer"}},"type":"object"}},"type":"object"}}},"description":"Embeddings result"},"402":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Insufficient credits"},"403":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"AI not enabled for organization"},"429":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Rate limited"},"502":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Upstream provider error"}},"security":[{"bearer_auth":[]}],"summary":"Create embeddings (OpenAI-compatible)","tags":["Router · Embeddings"]}},"/api/v1/models":{"get":{"callbacks":{},"description":"Returns the Router model catalog for your organization in OpenAI's list\nformat. Use this endpoint from SDKs that call `client.models.list()`;\nthe richer `/billing/models` endpoint stays available with\nMeridian-specific fields (tier, display_name, etc.).\n\nBy default every synced OpenRouter model is listed. An organization\ncan restrict its Router surface to its platform models\n(`/router/settings/ai`) — restricted orgs only see platform-active\nmodels here.\n\nBeyond the OpenAI fields (`id`, `object`, `created`, `owned_by`),\neach entry carries `context_length` (tokens, `null` when unknown),\n`pricing` (input/output CAD per 1M tokens with your org's markup +\nFX applied, `null` when the model is unpriced) and\n`supported_parameters` (what Router accepts for this model).\n","operationId":"MeridianWeb.Api.V1.ModelsController.index","parameters":[],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"properties":{"context_length":{"description":"Context window in tokens (null when unknown)","type":"integer"},"created":{"type":"integer"},"id":{"example":"claude-sonnet-4","type":"string"},"object":{"example":"model","type":"string"},"owned_by":{"example":"anthropic","type":"string"},"pricing":{"description":"Input/output CAD per 1M tokens (null when unpriced)","type":"object"},"supported_parameters":{"description":"Router capability flags for this model","type":"object"}},"type":"object"},"type":"array"},"object":{"example":"list","type":"string"}},"type":"object"}}},"description":"Model list"}},"security":[{"bearer_auth":[]}],"summary":"List available models (OpenAI-compatible)","tags":["Router · Models"]}},"/api/v1/tools/fetch":{"post":{"callbacks":{},"description":"Fetches a public `http(s)` URL server-side and returns its integral\nraw text (tags stripped, never summarized — numbers and units kept\nas-is), truncated at `max_chars`. HTML yields `title` + absolute\n`images`; PDFs yield `text` + `pages`. A distant 4xx/5xx returns\n`200` with the distant `status` and `text: \"\"`.\n","operationId":"MeridianWeb.Api.V1.Tools.FetchController.create","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"max_chars":{"default":200000,"description":"Max characters of returned text (default 200000)","minimum":1,"type":"integer"},"render_js":{"default":false,"description":"JS rendering is NOT supported (true → 400)","type":"boolean"},"url":{"description":"Public http(s) URL to fetch","example":"https://example.com/taux-hypothecaire","type":"string"}},"required":["url"],"type":"object"}}},"description":"Fetch request","required":false},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"billing":{"properties":{"cost_cad":{"example":"0.010000","type":"string"},"cost_cad_cents":{"type":"integer"},"currency":{"example":"CAD","type":"string"}},"type":"object"},"content_type":{"example":"text/html","type":"string"},"fetched_at":{"type":"string"},"final_url":{"type":"string"},"id":{"example":"tool-abc123","type":"string"},"images":{"items":{"properties":{"alt":{"type":"string"},"height":{"type":"integer"},"url":{"type":"string"},"width":{"type":"integer"}},"type":"object"},"type":"array"},"length":{"type":"integer"},"pages":{"type":"integer"},"sha256":{"type":"string"},"status":{"type":"integer"},"text":{"type":"string"},"title":{"type":"string"},"truncated":{"type":"boolean"},"url":{"type":"string"}},"type":"object"}}},"description":"Fetched page"}},"security":[{"bearer_auth":[]}],"summary":"Fetch a URL as raw text (Artemis enrichment)","tags":["Router · Tools"]}},"/api/v1/tools/web_search":{"post":{"callbacks":{},"description":"Runs a server-side web search and returns ranked results\n(`url`, `title`, `snippet`) plus a `billing` cost computed like LLM\nusage (provider USD cost through the org markup + FX).\nThe backend is env-configurable; without a key the stub backend\nreturns zero results.\n","operationId":"MeridianWeb.Api.V1.Tools.WebSearchController.create","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"country":{"default":"ca","description":"Country code hint (default ca)","example":"ca","type":"string"},"lang":{"description":"Optional result language hint","enum":["fr","en"],"type":"string"},"max_results":{"default":8,"description":"Number of results (1..10, default 8)","maximum":10,"minimum":1,"type":"integer"},"query":{"example":"taux hypothécaire Montréal","minLength":1,"type":"string"}},"required":["query"],"type":"object"}}},"description":"Web search request","required":false},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"billing":{"properties":{"cost_cad":{"example":"0.020000","type":"string"},"cost_cad_cents":{"type":"integer"},"currency":{"example":"CAD","type":"string"}},"type":"object"},"id":{"example":"tool-abc123","type":"string"},"results":{"items":{"properties":{"rank":{"type":"integer"},"snippet":{"type":"string"},"title":{"type":"string"},"url":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"Search results"}},"security":[{"bearer_auth":[]}],"summary":"Web search (Artemis enrichment)","tags":["Router · Tools"]}}},"security":[{"bearer_auth":[]}],"servers":[{"description":"Current server","url":"/","variables":{}}],"tags":[]}