Lelemon
  • Get started
  • Use cases
  • Guides
  • API basics
  • Webhooks
  • SDK, CLI and MCP
  • API reference
  • Changelog
  • v1 (legacy)
Configure your account
Talk to people
Run and protect
    Give an agent a jobSchedule a jobTrack usage and cap spendingRun Lelemon for your customersKeep tool data out of storageErase a contact or a messageBest practicesMoving from v1
powered by Zudoku
Run and protect

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.

TerminalCode
curl -X POST "https://api.lelemon.cl/v2/agents/agt_5RvP2aKq9XwLmN3tYbZc01/runs" \ -H "Authorization: Bearer $LELEMON_API_KEY" \ -H "Idempotency-Key: reconcile-2026-08" \ -H "Content-Type: application/json" \ -d '{ "goal": "Reconcile the August bank statement and tell me what is left pending.", "actor": { "id": "user_8841", "role": "staff" }, "limits": { "maxRounds": 20, "maxMinutes": 20 } }'

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.

FieldMeaning
goalWhat the agent has to achieve, up to 8,000 characters. The agent reads it as text from a user.
actorThe person in your system the agent works for. See who the run works for.
limitsmaxRounds 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:

  • actor is { id, role, name? }. id is the person in your system, role is end_user, staff or admin, and name is 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.role and actor.declaredBy (your key_…). A key cannot declare a role above its own: a key of a subaccount tops at staff, and 403 actor_role_above_key otherwise.
  • Without actor the run works as your key. The id that travels is the key_… 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

TerminalCode
curl "https://api.lelemon.cl/v2/runs/run_5RvP2aKq9XwLmN3tYbZc01" \ -H "Authorization: Bearer $LELEMON_API_KEY"

GET /v2/runs lists the runs, newest first, filtered by agentId or status. Read needs runs:read.

statusMeaning
runningWorking, or waiting in the queue (startedAt is null until a worker takes it).
waiting_for_answerPaused to ask. question has it. Answer it.
completed_unverifiedThe agent says it finished. Nobody has checked it, so do not read it as done: look at result.summary and result.checks.
stoppedThe 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.
failedAn error. result.error says what. With stopReason: "abandoned", nobody answered its question in 30 days.
canceledYou 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:

stopReasonStatusMeaning
roundsstoppedIt used all the rounds of limits.maxRounds.
coststoppedIt reached the spending limit Lelemon sets for every run.
timestoppedIt lasted all of limits.maxMinutes since it started.
no_conclusionstoppedThe agent answered four times in a row without calling its finish action.
loopstoppedThe agent kept repeating the same action.
abandonedfailedIt 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.

TerminalCode
curl -X POST "https://api.lelemon.cl/v2/runs/run_5RvP2aKq9XwLmN3tYbZc01/answer" \ -H "Authorization: Bearer $LELEMON_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "answer": "Use the checking account.", "actor": { "id": "user_9020", "role": "staff" } }'

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 stopped with stopReason rounds, cost or time and 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-Subaccount header the run belongs to the subaccount and uses its agents, and its actor ceiling is admin.
  • No data in the log. The goal, the question and the result are never logged.
Show who is onlineSchedule a job
On this page
  • Create a run
  • Who the run works for
  • Follow it
  • How a run ends
  • Webhooks
  • Answer a question
  • Cancel it
  • What keeps it safe