DocumentaciónHilos y ejecuciones
Tus asistentes
Hilos y ejecuciones
Un hilo guarda una conversación con un asistente. Cada pregunta lanza en él una ejecución, que sigues hasta la respuesta.
En esta página
Un turno de conversación
Abrir un hilo
POST /v1/threadCon el identificador del asistente.Hacer la pregunta
POST /v1/thread/{id}/messagesEl mensaje de la persona.Lanzar la ejecución
POST /v1/thread/{id}/runsEl asistente trabaja en este mensaje. La respuesta incluye el identificador de la ejecución.
# 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.idSeguir la ejecución
Consulta la ejecución hasta que termine. Cuando ha terminado, la respuesta está en output.
| Estado | Qué significa |
|---|---|
queued | A la espera de un worker libre |
in_progress | El asistente está trabajando |
completed | Terminada, la respuesta está lista |
failed | Interrumpida por un error, descrito en error |
canceled | Detenida antes de terminar |
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)Respuesta
{
"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
}También disponible
GET /v1/thread/{id}/messages Los mensajes del hilo, hasta 400 por página.
GET /v1/run/{id}/stream La respuesta como eventos del servidor, mientras se escribe.
POST /v1/runs/{id}/stop Detiene una ejecución.
GET /v1/threads Los hilos de la persona, filtrables por asistente.
Ajustar una ejecución
modelOverridetexto- El modelo solo para esta ejecución: flash o max.
reasoning_efforttexto- El esfuerzo de razonamiento: none, low, medium o high.
maxStepsentero- El número máximo de pasos de la ejecución, de 1 a 500.
Límites
- 20 ejecuciones por minuto y por persona
- 600 solicitudes por minuto para las demás rutas
- El número de ejecuciones por día depende del plan del espacio de trabajo