Give an agent a job that runs on its own
A run is a job. You give an agent a goal and it works on it outside your request, for as many rounds as it needs, until it declares the job done or something stops it. Nobody has to keep a connection open. Use a run when the work is longer than a conversation: reconciling a statement, filling in a batch, preparing a report.
Create a run
The agent must be active, created through the API or a template (not an internal one of the dashboard) and have the api channel. Your key needs runs:write.
Code
It answers 201 right away with the run in running. Repeat the request with the same Idempotency-Key and you get the run already created, not a second one. ?dryRun=true runs the same checks and shows the run as it would be created, without queueing anything.
| Field | Meaning |
|---|---|
goal | What the agent has to achieve, up to 8,000 characters. The agent reads it as text from a user. |
actor | The person in your system the agent works for. See who the run works for. |
limits | maxRounds and maxMinutes for this run. The defaults are 30 rounds and 30 minutes. Above 60 rounds or 120 minutes it is cut to those maximums. What you leave out takes the default. |
Who the run works for
The run is unattended: the agent uses any action it is granted, including the ones that write, with nobody looking. So the run has to say who it acts for.
There is no signature to compute and no shared secret. Your API key is what vouches for the person. Declare them in actor:
actoris{ id, role, name? }.idis the person in your system,roleisend_user,stafforadmin, andnameis optional: the dashboard shows it as who the run works for. Lelemon does not verify them. It records that your key declared them, and the run carries that to every action and MCP server as the signed actor:actor.id,actor.roleandactor.declaredBy(yourkey_…). A key cannot declare a role above its own: a key of a subaccount tops atstaff, and403 actor_role_above_keyotherwise.- Without
actorthe run works as your key. The id that travels is thekey_…of the key.
The run answers with the actor it kept, so you can audit who an overnight job acted for. Give runs:write only to systems you already run: a key with it decides which person the agent acts as.
If your agent uses an MCP server that needs to know the person, turn on the run identity of the server. Lelemon signs the call to the server with the actor inside; the server verifies Lelemon's signature, not yours.
Follow it
Code
GET /v2/runs lists the runs, newest first, filtered by agentId or status. Read needs runs:read.
status | Meaning |
|---|---|
running | Working, or waiting in the queue (startedAt is null until a worker takes it). |
waiting_for_answer | Paused to ask. question has it. Answer it. |
completed_unverified | The agent says it finished. Nobody has checked it, so do not read it as done: look at result.summary and result.checks. |
stopped | The run was cut before the agent declared the job done. stopReason says why, see how a run ends. result.partial keeps the last thing the agent wrote. |
failed | An error. result.error says what. With stopReason: "abandoned", nobody answered its question in 30 days. |
canceled | You canceled it. |
rounds shows the rounds it has taken so far, against limits.maxRounds.
How a run ends
A run does not end because the agent stops talking. The agent ends it by calling its finish action with a summary and a list of things to check. Only then the run is completed_unverified, and result.summary and result.checks hold what it declared. The finish action is refused until the agent has used at least one tool, so a run cannot end with a summary and no work behind it.
If the agent answers in plain text without calling it, the run tells the agent it has not finished and gives it another round. After four such answers in a row the run stops with stopReason: "no_conclusion". That is what a goal that needs no tools usually ends in: the agent answers, never calls the finish action, and its answer is in result.partial. To get completed_unverified, word the goal so the agent has to do something with its tools, and say that it must finish when done.
When status is stopped or failed, stopReason says why:
stopReason | Status | Meaning |
|---|---|---|
rounds | stopped | It used all the rounds of limits.maxRounds. |
cost | stopped | It reached the spending limit Lelemon sets for every run. |
time | stopped | It lasted all of limits.maxMinutes since it started. |
no_conclusion | stopped | The agent answered four times in a row without calling its finish action. |
loop | stopped | The agent kept repeating the same action. |
abandoned | failed | It asked a question and nobody answered in 30 days. |
rounds, cost and time are limits. no_conclusion and loop are not: the agent had room left and did not use it to finish. In every stopped run result.partial keeps the last thing the agent wrote, so read it before you start the job again. It can be the answer you wanted.
Webhooks
Do not poll. Subscribe an endpoint to run.started, run.waiting_for_answer, run.completed, run.stopped, run.failed and run.canceled. Each one carries the run in data.run, as GET /v2/runs/{id} would answer at that moment. They are sent at least once: a run a worker lost halfway can announce run.started again. A platform account also gets those of its subaccounts, with customerId.
Answer a question
When the agent needs a person it pauses with waiting_for_answer, and run.waiting_for_answer fires.
Code
The run goes back to running with your answer as context of its next round, and the agent sees who answered (actor.id, or your key without actor). A question is answered once: a run that is not paused answers 409 run_not_waiting. Someone from your team can also answer in the dashboard, under the agent, in Activity.
Cancel it
POST /v2/runs/{id}/cancel. If nobody is running it, it ends canceled at once. If a worker is running it, cancelRequested turns true and it ends when its next round starts: the action it was doing finishes. A run that already ended answers 409 run_finished.
What keeps it safe
- Limits. Rounds, minutes and the spending limit Lelemon sets for every run are checked on every round and the server maximums cannot be raised by API. A run that crosses one ends
stoppedwithstopReasonrounds,costortimeand its partial result. - Approvals. An action behind an approval policy does not run inside a run either: it waits for a person. The agent is told the action is in review and keeps working on the rest.
- Subaccounts. With the
Lelemon-Subaccountheader the run belongs to the subaccount and uses its agents, and its actor ceiling isadmin. - No data in the log. The goal, the question and the result are never logged.