Bearer token

Include your API key as a Bearer token in every request's Authorization header.

Authorization: Bearer YOUR_API_KEY

Requests without a valid token receive 401 Unauthorized. The /api/health endpoint is public and does not require authentication.

Your first call

A minimal request with three providers and the default synthesizer:

# Ask five models, get a synthesized answer with consensus annotation
curl -X POST https://nonpareil.onrender.com/api/ask \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What are the key risks of deploying LLMs in production?",
    "providers": ["gemini", "openrouter", "cohere"]
  }'

To use all five providers:

-d '{
  "question": "...",
  "providers": ["gemini", "groq", "openrouter", "cohere", "cerebras"]
}'

Available routes

POST /api/ask Multi-provider Q&A with synthesis

Request body

FieldTypeDescription
questionrequired string The question to send to all providers.
providersrequired string[] Provider keys to query. See Providers below. At least one required.
synthesizeroptional string Provider key to use as synthesizer. Defaults to a provider not in the panel. Must differ from all queried providers.
modeloptional string Override the default model for all providers.
optimize_promptoptional boolean Rewrite the question before fan-out for clarity and specificity. Default: false.
optimizer_modeloptional string Provider key to use for prompt optimization when optimize_prompt is true.

Response

FieldTypeDescription
question string Original question as submitted.
optimized_question string | null Rewritten question, if optimize_prompt was true and succeeded.
answers object[] One entry per provider. Each has label, model, text (the raw answer), and error (null on success).
consensus_available boolean True if two or more providers responded successfully.
provider_count integer Number of providers that returned a successful answer.
final_answer string Synthesized answer combining the strongest, most corroborated content from all providers.
synthesizer string Provider label that performed the synthesis step.
source_count integer Number of provider answers the synthesizer used as sources.
notes string Synthesizer commentary on agreement level and notable divergences.
init_errors object Map of provider key → error message for any providers that failed to initialize.
conversation_id integer | null Persisted conversation ID for history and rating.
consensus_sentences object[] Per-sentence breakdown of the final_answer. Each entry: text (sentence) and corroborated_by (count of raw answers that contain similar content).

Example response

{
  "question": "What are the key risks of deploying LLMs in production?",
  "optimized_question": null,
  "answers": [
    { "label": "gemini", "model": "gemini-2.5-flash", "text": "...", "error": null },
    { "label": "openrouter", "model": "openai/gpt-oss-120b:free", "text": "...", "error": null },
    { "label": "cohere", "model": "command-a-03-2025", "text": "...", "error": null }
  ],
  "consensus_available": true,
  "provider_count": 3,
  "final_answer": "Deploying LLMs in production carries several key risks...",
  "synthesizer": "gemini",
  "source_count": 3,
  "notes": "All three providers agreed on the core risk categories...",
  "init_errors": {},
  "conversation_id": 42,
  "consensus_sentences": [
    { "text": "Deploying LLMs in production carries several key risks.", "corroborated_by": 3 },
    { "text": "Hallucination is the most cited failure mode.", "corroborated_by": 2 }
  ]
}
POST /api/conversations/{id}/rating Rate a past answer

Thumbs up or down on a past call. Use the conversation_id from any /api/ask response.

curl -X POST https://nonpareil.onrender.com/api/conversations/42/rating \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"rating": 1}'  # 1 = thumbs up, -1 = thumbs down
GET /api/conversations Conversation history

Returns up to 50 past questions and their synthesis summaries, plus aggregate stats.

curl https://nonpareil.onrender.com/api/conversations \
  -H "Authorization: Bearer YOUR_API_KEY"
GET /api/health Health check (no auth required)
curl https://nonpareil.onrender.com/api/health
# → {"status": "ok"}

Available provider keys

Pass any combination of these keys in the providers array. Each runs independently against its default model.

gemini gemini-2.5-flash
groq llama-3.3-70b-versatile
openrouter gpt-oss-120b:free
cohere command-a-03-2025
cerebras gpt-oss-120b
huggingface gpt-oss-120b
Synthesizer selection: The synthesizer must be a different provider than those in your panel. If you don't specify one, Arei picks the best available option automatically.

How corroboration scores work

Each sentence in final_answer appears in consensus_sentences with a corroborated_by count. A count of 3 means three independent raw provider answers contained semantically similar content — the higher the count, the more confident you can be that sentence reflects genuine model consensus rather than a single model's opinion.

Sentences with corroborated_by: 1 are worth extra scrutiny — only one model said it, and it may reflect that model's individual bias or a hallucination the others didn't share.

Transparency guarantee: Raw per-provider answers are always returned in answers[], even when synthesis fails. You can always read exactly what each model said, independent of Arei's synthesis layer.

HTTP status codes

CodeMeaning
200OK Successful call. Check init_errors for any providers that failed to initialize within a successful overall request.
400Bad request No providers could be initialized, or invalid request body.
401Unauthorized Missing or invalid Authorization header.
502Bad gateway The synthesizer call failed or returned a malformed response. Raw per-provider answers are still included in the response body.