Quickstart
cortexa.curl https://api.cortexa.sh/v1/chat/completions \
-H "Authorization: Bearer $CORTEXA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "cortexa",
"messages": [
{
"role": "user",
"content": "Summarize the evidence for GLP-1 agonists in neuroinflammation. Cite sources."
}
]
}'from openai import OpenAI
client = OpenAI(
api_key="sk-cortexa-live-...",
base_url="https://api.cortexa.sh/v1",
)
response = client.chat.completions.create(
model="cortexa",
messages=[
{
"role": "user",
"content": "Find recent clinical evidence for tau PET as an Alzheimer's endpoint.",
}
],
)
print(response.choices[0].message.content)Endpoint reference
/v1/chat/completionschat:completionsOpenAI-compatible chat completion endpoint. Best for existing SDKs and server-side integrations. Text messages only, streaming or not.
/v1/agents/cortexa/runsagents:runsNative streaming endpoint for text deltas, tool events, citations, and rich data cards. The only endpoint that can read an attached Library file.
/v1/runs/{id}agents:runsFetch the completed messages, tool invocations, and stream of an earlier run by ID.
/v1/modelsmodels:listList available Cortexa models. Returns a single entry today; included for OpenAI client compatibility.
/v1/toolstools:listInspect the verified tools the agent can route to per request.
/v1/sourcestools:listBrowse the curated data source catalog the agent can reach.
/mcpMCP endpoint for clients that support streamable HTTP. Any valid key reaches it; see the MCP guide for host setup.
The tag next to each path is the key scope that endpoint requires. See Key scopes.
Streaming
stream: trueon a chat completion to receive server-sent events instead of one JSON body. OpenAI SDKs handle this for you; the raw shape is below if you are reading the stream yourself.curl https://api.cortexa.sh/v1/chat/completions \
-H "Authorization: Bearer $CORTEXA_API_KEY" \
-H "Content-Type: application/json" \
-N \
-d '{
"model": "cortexa",
"messages": [
{
"role": "user",
"content": "Which biomarkers predict response to checkpoint inhibitors?"
}
],
"stream": true
}'data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Tumor mutational"},"finish_reason":null}]}
data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":42,"completion_tokens":188,"total_tokens":230}}
data: [DONE]Reading the stream
choices[0].delta.content. The last content frame carries finish_reason: "stop", followed by one frame with an empty choices array and the token usage for the whole request, then data: [DONE].Failures after the stream opens
error object with code stream_error, then closes with data: [DONE]. Check each frame for an error key rather than relying on the HTTP status alone.Cortexa selects the tools
Do not send a tools array
tools or tool_choice input. Sending one has no effect: unknown fields are accepted and ignored rather than rejected, so the request succeeds and your definitions are never reached. The same goes for sampling fields such as temperature, max_tokens, top_p, and stop. They keep existing SDK calls working and do not change the run.Where you do get an error
unsupported_part_type rather than being dropped, because a silently discarded attachment produces a confident answer about material the agent never saw.Native streaming
curl https://api.cortexa.sh/v1/agents/cortexa/runs \
-H "Authorization: Bearer $CORTEXA_API_KEY" \
-H "Content-Type: application/json" \
-N \
-d '{
"messages": [
{
"role": "user",
"content": "Compare evidence for two candidate targets and cite primary sources."
}
]
}'1.8K+ verified tools behind one model
Attaching files
curl https://api.cortexa.sh/v1/agents/cortexa/runs \
-H "Authorization: Bearer $CORTEXA_API_KEY" \
-H "Content-Type: application/json" \
-N \
-d '{
"messages": [
{
"role": "user",
"parts": [
{ "type": "text", "text": "Summarize the methods section." },
{
"type": "data-library-file-ref",
"data": { "id": "file_9c2f...", "name": "trial-protocol.pdf" }
}
]
}
]
}'What works
data-library-file-refpart alongside your text. Cortexa resolves the id against the key owner's Library and the active workspace, then reads the file the way the app does. A file id the key cannot reach returns HTTP 404 with file_not_found, so you never get an answer written as though the file were included.What does not exist yet
File ids are visible in your Library. See the Library guide for uploading and organizing them.
Authentication
Authorization: Bearer sk-cortexa-live-.... Create and revoke keys from the API Keys dashboard.Key scopes
chat:completionsRun the agent through the OpenAI-compatible chat endpoint, streaming or not.
/v1/chat/completions
agents:runsStart a native agent run and fetch an earlier run back by id.
/v1/agents/cortexa/runs · /v1/runs/{id}
models:listRead the model listing.
/v1/models
tools:listRead the tool and data source catalogs.
/v1/tools · /v1/sources
connections:useLet a run read the private connections the key owner has already been granted.
Calling an endpoint your key is not scoped for
HTTP/1.1 403 Forbidden
{
"error": {
"message": "This API key is missing the 'agents:runs' scope, which this endpoint requires. Create a key that includes it in Settings → API keys.",
"type": "invalid_request_error",
"code": "insufficient_scope",
"param": null
}
}Choosing scopes
connections:use, which you opt into per key. Keys created before scopes existed keep working on the endpoints above and cannot reach private connections. Scopes are fixed when the key is created: to change them, create a new key and revoke the old one.Credit charging & HTTP 402
Model work is charged by actual usage
402 Payment Required