{"openapi":"3.1.0","info":{"title":"Synero API","version":"1.0.0","description":"Collective AI Intelligence API. Query a council of 4 AI models simultaneously and receive a synthesized answer via server-sent events.","contact":{"url":"https://synero.ai/developers"}},"servers":[{"url":"https://synero.ai","description":"Production"}],"security":[{"bearerAuth":[]}],"paths":{"/api/query":{"post":{"operationId":"queryCouncil","summary":"Query the AI Council","description":"Send a prompt to 4 AI advisors simultaneously. Each advisor responds with their unique perspective, then a synthesizer produces a unified answer. Responses are streamed as server-sent events (SSE).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryRequest"},"example":{"prompt":"What are the trade-offs between microservices and monoliths?"}}}},"responses":{"200":{"description":"SSE stream of council responses","content":{"text/event-stream":{"schema":{"type":"string","description":"Server-sent events stream. Each event has a type (event:) and JSON data (data:). Event types: advisor, advisor-complete, advisor-error, synthesis, synthesis-complete, complete, error."}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missingPrompt":{"value":{"error":"Prompt is required"}},"tooLong":{"value":{"error":"Prompt too long (max 10,000 characters)"}},"invalidModel":{"value":{"error":"Invalid model \"foo\" for slot \"architect\""}}}}}},"401":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Invalid API key"}}}},"402":{"description":"Payment required, subscription or credits needed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingError"},"example":{"error":"Insufficient credits. Please purchase more at /app/billing.","code":"no_credits"}}}},"429":{"description":"Rate limit exceeded (60 requests/min per API key)","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until rate limit resets"},"X-RateLimit-Limit":{"schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"schema":{"type":"integer","example":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Rate limit exceeded. Try again later."}}}},"503":{"description":"Billing service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Billing service temporarily unavailable. Please try again."}}}}}}},"/api/keys":{"post":{"operationId":"createApiKey","summary":"Create an API key","description":"Create a new API key. Requires browser session authentication (cannot create keys with an API key). The raw key is returned once and never stored, save it securely.","security":[{"cookieAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Display name for this key","default":"Default"}}}}}},"responses":{"200":{"description":"API key created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"operationId":"listApiKeys","summary":"List API keys","description":"List all active (non-revoked) API keys for the authenticated user. Requires browser session.","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"List of API keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}}}}},"/api/keys/{id}":{"delete":{"operationId":"revokeApiKey","summary":"Revoke an API key","description":"Permanently revoke an API key. The key will immediately stop working.","security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Key revoked","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key authentication. Keys start with \"sk_live_\" and are 48 characters long. Get yours at https://synero.ai/app/api-keys"},"cookieAuth":{"type":"apiKey","in":"cookie","name":"sb-access-token","description":"Browser session cookie (for dashboard operations only)"}},"schemas":{"QueryRequest":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","maxLength":10000,"description":"The question or prompt to send to the AI council"},"config":{"$ref":"#/components/schemas/CouncilConfig"},"threadId":{"type":"string","format":"uuid","description":"Thread ID for multi-turn conversations"},"parentQueryId":{"type":"string","format":"uuid","description":"ID of the previous query in a conversation thread"},"threadHistory":{"type":"array","items":{"$ref":"#/components/schemas/ThreadEntry"},"description":"Previous Q&A pairs for conversation context"},"context":{"type":"array","description":"Attach documents or text as context for the council. Supports .md, .txt, .csv, .json content. Max 50k chars per item, 100k total.","items":{"$ref":"#/components/schemas/ContextItem"}},"format":{"type":"string","enum":["json","stream"],"description":"Response format. 'json' returns structured JSON (ideal for agents). Default 'stream' returns SSE."}}},"ContextItem":{"type":"object","required":["name","content"],"properties":{"name":{"type":"string","description":"Label for this context (e.g. filename)","example":"research-notes.md"},"content":{"type":"string","description":"The text content to provide as context","maxLength":50000},"type":{"type":"string","enum":["file","text"],"description":"How the context was attached","default":"text"}}},"CouncilConfig":{"type":"object","description":"Optional configuration to customize which AI model powers each advisor slot and the synthesizer","properties":{"advisorModels":{"type":"object","description":"Map of advisor slot to model ID","properties":{"architect":{"$ref":"#/components/schemas/ModelId"},"philosopher":{"$ref":"#/components/schemas/ModelId"},"explorer":{"$ref":"#/components/schemas/ModelId"},"maverick":{"$ref":"#/components/schemas/ModelId"}}},"synthesizerModel":{"$ref":"#/components/schemas/ModelId"},"enabledAdvisors":{"type":"object","description":"Map of advisor slot to enabled state. Omit or set to true to enable. Set to false to disable. At least 1 advisor must be enabled. When only 1 advisor responds, synthesis is automatically skipped.","properties":{"architect":{"type":"boolean","default":true},"philosopher":{"type":"boolean","default":true},"explorer":{"type":"boolean","default":true},"maverick":{"type":"boolean","default":true}}},"councilTier":{"type":"string","enum":["low","medium","high","custom"],"description":"Council tier this config maps to. low=fast & cheap, medium=balanced (default), high=flagship models from each provider, custom=hand-picked models. When sent on /api/query, the field is recorded for analytics. Programmatic clients can use it as a per-query override without affecting the user's persisted preference."}}},"ModelId":{"type":"string","enum":["gpt-5.5","gpt-5.4","gpt-5.2","gpt-4.1","gpt-4.1-mini","o4-mini","claude-opus-4-7","claude-opus-4-6","claude-sonnet-4-6","claude-haiku-4-5","gemini-3.1-pro-preview","gemini-3-flash-preview","gemini-2.5-pro","gemini-2.5-flash","grok-4.3","grok-4.20-reasoning","grok-4.20-non-reasoning","grok-4","grok-4-1-fast-reasoning","grok-3-mini"],"description":"Available AI model identifiers"},"AdvisorSlotId":{"type":"string","enum":["architect","philosopher","explorer","maverick"],"description":"The four advisor personas. Architect: structured/analytical. Philosopher: nuanced/thorough. Explorer: creative/curious. Maverick: bold/unconventional."},"ThreadEntry":{"type":"object","required":["prompt","synthesis"],"properties":{"prompt":{"type":"string"},"synthesis":{"type":"string"}}},"SSEEvents":{"type":"object","description":"Server-sent event types streamed in the response. Note: synthesis events (synthesis-start, synthesis, synthesis-complete) are only emitted when 2+ advisors are enabled. With a single advisor, the stream goes directly from advisor-complete to complete.","properties":{"advisor":{"type":"object","description":"Token from an advisor (streamed incrementally)","properties":{"id":{"$ref":"#/components/schemas/AdvisorSlotId"},"token":{"type":"string"},"status":{"type":"string","enum":["streaming"]}}},"advisor-complete":{"type":"object","description":"An advisor has finished responding","properties":{"id":{"$ref":"#/components/schemas/AdvisorSlotId"},"modelId":{"type":"string"},"inputTokens":{"type":"integer"},"outputTokens":{"type":"integer"},"latencyMs":{"type":"integer"}}},"advisor-error":{"type":"object","description":"An advisor encountered an error","properties":{"id":{"$ref":"#/components/schemas/AdvisorSlotId"},"error":{"type":"string"}}},"synthesis":{"type":"object","description":"Token from the synthesizer (streamed after all advisors complete)","properties":{"token":{"type":"string"},"status":{"type":"string","enum":["streaming"]}}},"synthesis-complete":{"type":"object","description":"Synthesis has finished","properties":{"inputTokens":{"type":"integer"},"outputTokens":{"type":"integer"}}},"complete":{"type":"object","description":"The entire council query is done","properties":{"queryId":{"type":"string","format":"uuid"}}},"error":{"type":"object","description":"A fatal error occurred during processing","properties":{"message":{"type":"string"}}}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"keyPrefix":{"type":"string","description":"First 12 characters of the key (e.g. \"sk_live_a1b2\")"},"lastUsedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"ApiKeyCreateResponse":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"},"rawKey":{"type":"string","description":"The full API key. This is shown once and never stored, save it immediately."}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}}},"BillingError":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string","enum":["no_subscription","subscription_inactive","no_credits"]}}}}}}