DocumentationFils et exécutions
Vos assistants
Fils et exécutions
Un fil garde une conversation avec un assistant. Chaque question y lance une exécution, que vous suivez jusqu’à la réponse.
Un tour de conversation
Ouvrir un fil
POST /v1/threadAvec l’identifiant de l’assistant.Poser la question
POST /v1/thread/{id}/messagesLe message de la personne.Lancer l’exécution
POST /v1/thread/{id}/runsL’assistant travaille sur ce message. La réponse porte l’identifiant de l’exécution.
# Open a thread with the assistant.
curl https://api.learnya.ai/v1/thread \
-H "Authorization: Bearer $LEARNYA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"assistantId": "ASSISTANT_ID", "title": "Ticket 42"}'
# Post the question.
curl https://api.learnya.ai/v1/thread/THREAD_ID/messages \
-H "Authorization: Bearer $LEARNYA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content": "Where is my invoice?"}'
# Start the run on it. The answer carries the run id.
curl https://api.learnya.ai/v1/thread/THREAD_ID/runs \
-H "Authorization: Bearer $LEARNYA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"triggerMessageId": "MESSAGE_ID"}'def post(path, body):
reply = requests.post(
f"{API}{path}", headers=HEADERS, json=body
)
reply.raise_for_status()
return reply.json()
thread = post("/thread", {"assistantId": assistant["id"]})
question = post(
f"/thread/{thread['id']}/messages",
{"content": "Where is my invoice?"},
)
run = post(
f"/thread/{thread['id']}/runs",
{"triggerMessageId": question["id"]},
)
run_id = run["id"]async function post(path, body) {
const r = await fetch(`${API}${path}`, {
method: "POST",
headers,
body: JSON.stringify(body),
})
if (!r.ok) throw new Error(`${r.status} on ${path}`)
return r.json()
}
const thread = await post("/thread", {
assistantId: assistant.id,
})
const question = await post(`/thread/${thread.id}/messages`, {
content: "Where is my invoice?",
})
const run = await post(`/thread/${thread.id}/runs`, {
triggerMessageId: question.id,
})
const runId = run.idasync function post<T>(path: string, body: unknown) {
const r = await fetch(`${API}${path}`, {
method: "POST",
headers,
body: JSON.stringify(body),
})
if (!r.ok) throw new Error(`${r.status} on ${path}`)
return (await r.json()) as T
}
const thread = await post<{ id: string }>("/thread", {
assistantId: assistant.id,
})
const question = await post<{ id: string }>(
`/thread/${thread.id}/messages`,
{ content: "Where is my invoice?" },
)
const run = await post<{ id: string; status: string }>(
`/thread/${thread.id}/runs`,
{ triggerMessageId: question.id },
)
const runId = run.idSuivre l’exécution
Interrogez l’exécution jusqu’à sa fin. Quand elle est terminée, la réponse est dans output.
| Statut | Ce qu’il veut dire |
|---|---|
queued | En attente d’un poste de travail |
in_progress | L’assistant travaille |
completed | Terminée, la réponse est prête |
failed | Interrompue par une erreur, décrite dans error |
canceled | Arrêtée avant la fin |
import time
while True:
reply = requests.get(f"{API}/run/{run_id}", headers=HEADERS)
run = reply.json()
if run["status"] in ("completed", "failed", "canceled"):
break
time.sleep(1)
if run["status"] == "completed":
print(run["output"][0]["text"])
else:
print(run["status"], run.get("error"))const DONE = ["completed", "failed", "canceled"]
let run
do {
await new Promise((done) => setTimeout(done, 1000))
run = await fetch(`${API}/run/${runId}`, { headers }).then(
(r) => r.json(),
)
} while (!DONE.includes(run.status))
const done = run.status === "completed"
console.log(done ? run.output[0].text : run.error)type RunStatus =
| "queued"
| "in_progress"
| "completed"
| "failed"
| "canceled"
interface Run {
id: string
status: RunStatus
output?: { type: "text"; text: string }[] | null
error?: string | null
}
const DONE: RunStatus[] = ["completed", "failed", "canceled"]
let run: Run
do {
await new Promise((done) => setTimeout(done, 1000))
const r = await fetch(`${API}/run/${runId}`, { headers })
run = (await r.json()) as Run
} while (!DONE.includes(run.status))
const done = run.status === "completed"
console.log(done ? run.output?.[0].text : run.error)Réponse
{
"id": "c2a7e9d4-1b3f-4e6a-8c5d-9f0b2e4a6d18",
"threadId": "8e4b1d6f-2c9a-4f7e-b3d5-0a6c8e2f4b91",
"assistantId": "6f1c2b0e-3a4d-4c8e-9b7a-2d5e8f1a0c34",
"status": "completed",
"output": [
{ "type": "text", "text": "Your invoice 2026-114 was sent on 2 October." }
],
"modelUsed": "learnya-flash",
"error": null
}Aussi disponible
GET /v1/thread/{id}/messages Les messages du fil, jusqu’à 400 par page.
GET /v1/run/{id}/stream La réponse en événements serveur, pendant qu’elle s’écrit.
POST /v1/runs/{id}/stop Arrête une exécution.
GET /v1/threads Les fils de la personne, filtrables par assistant.
Régler une exécution
modelOverridetexte- Le modèle de cette exécution seulement : flash ou max.
reasoning_efforttexte- L’effort de raisonnement : none, low, medium ou high.
maxStepsentier- Le nombre maximal d’étapes de l’exécution, de 1 à 500.
Limites
- 20 exécutions par minute et par personne
- 600 requêtes par minute pour les autres routes
- Le nombre d’exécutions par jour suit l’offre de l’espace de travail