API Reference
Chat Completions
Generate medical AI chat responses with source citations.
POST https://api.persly.ai/v1/chat/completionsCreates a chat completion for the given messages. Returns a medical AI response with optional source citations, follow-up question suggestions, and streaming support.
Request Body
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
model | string | Yes | — | Model ID. Either persly-chat-v1 or persly-chat-pro-v1 |
messages | array | Yes | — | Array of messages in the conversation. Must be non-empty. |
messages[].role | string | Yes | — | Role of the message author: user, assistant, or system |
messages[].content | string | Yes | — | Content of the message |
stream | boolean | No | false | If true, response is streamed as Server-Sent Events |
include_sources | boolean | No | true | Include source citations in the response |
include_follow_ups | boolean | No | false | Include follow-up question suggestions |
temperature | number | No | — | Accepted for OpenAI compatibility but has no effect |
max_tokens | integer | No | — | Accepted for OpenAI compatibility but has no effect |
top_p | number | No | — | Accepted for OpenAI compatibility but has no effect |
The system role is accepted for compatibility but messages with this role are silently filtered before processing.
Response Body
| Field | Type | Description |
|---|---|---|
id | string | Unique request ID in chatcmpl_{hex} format |
object | string | Always "chat.completion" |
created | integer | Unix timestamp of when the response was created |
model | string | The model used for the completion |
choices | array | Array containing the response (always 1 item) |
choices[].index | integer | Always 0 |
choices[].message.role | string | Always "assistant" |
choices[].message.content | string | The AI-generated response |
choices[].finish_reason | string | Always "stop" |
sources | array | null | Medical source citations (when include_sources: true) |
sources[].title | string | Source document title |
sources[].url | string | Source URL |
sources[].relevance_score | number | Relevance score (0.0–1.0) |
follow_up_questions | array | null | Suggested follow-up questions (when include_follow_ups: true) |
usage | object | Usage information |
usage.request_count | integer | Number of requests billed (always 1) |
Examples
Basic Request
curl https://api.persly.ai/v1/chat/completions \
-H "Authorization: Bearer $PERSLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "persly-chat-v1",
"messages": [
{"role": "user", "content": "What are the first-line treatments for type 2 diabetes?"}
]
}'import requests
response = requests.post(
"https://api.persly.ai/v1/chat/completions",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"model": "persly-chat-v1",
"messages": [
{"role": "user", "content": "What are the first-line treatments for type 2 diabetes?"}
],
},
)
data = response.json()
print(data["choices"][0]["message"]["content"])
for source in data.get("sources", []):
print(f" Source: {source['title']} ({source['url']})")const response = await fetch("https://api.persly.ai/v1/chat/completions", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "persly-chat-v1",
messages: [
{ role: "user", content: "What are the first-line treatments for type 2 diabetes?" },
],
}),
});
const data = await response.json();
console.log(data.choices[0].message.content);
for (const source of data.sources ?? []) {
console.log(` Source: ${source.title} (${source.url})`);
}Response
{
"id": "chatcmpl_a1b2c3d4e5f6a1b2c3d4e5f6",
"object": "chat.completion",
"created": 1709000000,
"model": "persly-chat-v1",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The first-line treatment for type 2 diabetes is metformin, along with lifestyle modifications including diet and exercise. According to the ADA Standards of Care, metformin remains the preferred initial pharmacologic agent due to its efficacy, safety profile, and low cost..."
},
"finish_reason": "stop"
}
],
"sources": [
{
"title": "ADA Standards of Medical Care in Diabetes",
"url": "https://diabetesjournals.org/care/article/47/Supplement_1/S1/...",
"relevance_score": 0.97
},
{
"title": "Metformin - StatPearls",
"url": "https://www.ncbi.nlm.nih.gov/books/NBK518983/",
"relevance_score": 0.92
}
],
"usage": {
"request_count": 1
}
}Multi-turn Conversation
curl https://api.persly.ai/v1/chat/completions \
-H "Authorization: Bearer $PERSLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "persly-chat-v1",
"messages": [
{"role": "user", "content": "What is metformin used for?"},
{"role": "assistant", "content": "Metformin is primarily used as a first-line treatment for type 2 diabetes..."},
{"role": "user", "content": "What are its common side effects?"}
]
}'With Follow-up Questions
curl https://api.persly.ai/v1/chat/completions \
-H "Authorization: Bearer $PERSLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "persly-chat-v1",
"messages": [{"role": "user", "content": "What is hypertension?"}],
"include_follow_ups": true
}'{
"id": "chatcmpl_...",
"object": "chat.completion",
"created": 1709000000,
"model": "persly-chat-v1",
"choices": [{"index": 0, "message": {"role": "assistant", "content": "Hypertension, or high blood pressure, is a condition..."}, "finish_reason": "stop"}],
"sources": [...],
"follow_up_questions": [
"What are the risk factors for hypertension?",
"How is hypertension diagnosed?",
"What lifestyle changes can help manage hypertension?"
],
"usage": {"request_count": 1}
}Streaming
See the Streaming guide for detailed SSE protocol documentation.
curl https://api.persly.ai/v1/chat/completions \
-H "Authorization: Bearer $PERSLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "persly-chat-v1",
"messages": [{"role": "user", "content": "Explain the pathophysiology of asthma."}],
"stream": true
}'Errors
| Status | Code | Cause |
|---|---|---|
| 400 | model_not_found | Invalid model name |
| 400 | missing_required_field | Empty messages array |
| 400 | invalid_request | Invalid role or only system messages |
| 401 | authentication_error | Invalid API key |
| 429 | quota_exceeded | Free credits exhausted |
| 429 | spending_limit_exceeded | Monthly spending limit reached |