Agents
What agents are
An agent is a browser automation you describe in plain language instead of scripting. You give it a mission and a starting URL; it opens a real cloud browser, works through the site (navigating, filling forms, clicking, reading, downloading) and returns data that matches the output schema you defined.
The difference from a scraper is maintenance. A scraper is a list of CSS selectors that breaks when the site is redesigned. An agent reads the page it is on and works out what to do, so a moved button or a renamed field does not require a code change.
Use a flow when the data is in a document you received. Use an agent when the data lives on a website, or when something has to be done on a website with data you already have.
Agents are enabled per organization, on request. If the section is not in your sidebar, contact support to have it turned on for your organization.
Create an agent
Agents live under Agents in the sidebar. You can start from a blank agent or build one from an existing flow, so the flow's output fields arrive already set up as input variables.
| Button | What you get |
|---|---|
| Create Agent | A blank agent with just a name. You configure everything on the next screen. |
| New from flow | Pick a flow and click Build Agent. The new agent gets one input variable per output field of the flow, each set to read that field from the flow run. |
- 1Click Create Agent (or New from flow) and give the agent a name.
- 2On the agent's Configuration tab, write the Mission and the Starting URL.
- 3Add the Variables the mission needs and the Captures you want back.
- 4Click Save, then Test run and watch the run live.
- 5When the result is right, set up Delivery and switch the agent to active in the top bar.
A new agent starts as a draft. The active switch in the top bar controls whether it runs on its schedule. Duplicating an agent copies its configuration, but not its secret values or its schedule, so a copy never starts firing on its own.
Anatomy of an agent
An agent is five pieces of configuration: what to do, where to start, what it knows going in, what it must bring back, and where that goes.
| Part | What it is | Example |
|---|---|---|
| Mission | A plain-language instruction. Write it as you would brief a colleague, including how to handle the awkward cases. | “Log in with the provided credentials, open Orders, and record the current unit price for each part number.” |
| Start point | The URL the agent opens first. Web is the only start point type today; Desktop is shown as coming soon. | https://portal.acme-supply.com/login |
| Variables | Values the mission can refer to: fixed values, secrets, or fields pulled from a flow run. | part_number |
| Captures | The typed schema of what you want back. The agent's answer is validated against it, so the output is always structured. | unit_price |
| Delivery | Where the captured output goes when the run finishes. You can turn on several at once. | Email, webhook, Bucket, Subject |
Nearly every disappointing agent run traces back to a vague mission. Name the exact buttons and page titles, say what to do when a lookup returns nothing, and say when to stop. A mission that reads like a runbook works; one that reads like a wish does not.
Variables and secrets
Each variable has a name, a type (text, number, boolean, date, object, list or file) and a source. The mission refers to variables by name.
| Source | Where the value comes from |
|---|---|
| Static | A fixed value stored on the agent: a portal username, a warehouse code. API calls can override static values per run. |
| From flow run | A field of the triggering flow run's output. If the flow has a Cleaner, the value is taken from the cleaned output, so conversions and computed columns are already applied. These variables only get a value when a flow (or a pipeline) triggers the agent. |
| From bucket | Rows of a Bucket, read when the run starts (not when it is triggered), so a run that waited in line sees what the previous run wrote. Pick the columns, filters, order and a limit (default 2,000 rows, at most 5,000): one column gives its distinct values, several give one object per row. Paired with a Bucket delivery, it is the agent's memory between runs: “skip the leads whose id is in known_leads”. The agent reads the values as data, never as instructions, and API calls can't override them. |
File variables. A variable of type file hands the agent a flow run's original document so it can upload it to the site (an invoice to a customs portal, for example). Set it to Triggering run's document to get the document of the flow run that started the agent, or give it a run ID; a Test run or an API call can send another run ID for each run. The run must belong to your organization; otherwise the run fails before a browser opens, with nothing billed.
Secret variables. A static text variable can be flagged Secret, for a portal password for example. Its value is stored encrypted and never appears in the agent configuration, run inputs, outputs or step log.
- Only Owners and Admins, who are the only ones who can edit an agent, can set or clear a secret
- Secrets must be at least 6 characters; once saved, the field shows that a value exists without showing it
- The agent types the secret into the page by name, without ever seeing the value
- A secret can only be typed on the starting URL's site (the same host or one of its subdomains)
- If a secret value shows up in the page text, it is masked as *** in the steps and output
The live view and the session replay show whatever the page renders. Only password-type inputs are masked by the browser, so a secret typed into an ordinary text field can be visible there.
Output captures: the schema the agent must fill
Captures declare the shape of the result. Each one has a name, a type and an optional description, and nested structures are supported, so an agent can return a list of objects rather than a blob of text you have to parse afterwards.
| Capture type | Returns | Use it for |
|---|---|---|
| text | A string | Names, statuses, reference numbers, free text |
| number | A number | Prices, quantities, rates |
| boolean | True or false | In stock, approved, exists |
| date | A date as text | Delivery dates, expiry dates |
| object | A nested group of fields | One record with several attributes |
| list | A repeating structure | A table of results, one entry per row |
| file | A downloaded file | Invoices, statements or reports the agent has to fetch |
Every capture is optional. If the agent finds four of five values, the run returns the four it found rather than failing outright, so you keep the partial result and can see exactly what is missing.
Downloading files
Give an agent a file-typed capture and it can fetch documents as well as read them: a statement behind a login, an invoice PDF from a portal. It can download a file from a link, or click a download button and keep whatever file the site sends back.
| Limit | Value |
|---|---|
| Largest single file | 25 MB |
| Total files per run | 100 MB |
| Where files are kept | Stored with the run; download them from the run page under Captured files |
| Links in deliveries | Email and webhook payloads carry a link to each file, valid for 7 days |
Exceeding a limit does not stop the run: the agent is told the file was too large and carries on with the rest of the mission. If a site answers a download with a web page instead of a file (a login screen, for instance), the agent is told so rather than saving the page as if it were the document.
Mailbox: codes sent by email
Some portals email a one-time login code or a confirmation link. Connect a mailbox and the agent can wait for that email, read the code or link, and carry on. It is set up under Settings → Mailbox.
| Setting | What it does |
|---|---|
| Connect a mailbox | Turns the feature on for this agent. |
| Sender to wait for | Required. The address (or name) the code comes from. Mail from anyone else is ignored. |
| Subject contains (optional) | Narrows the match further, for example code. |
| Mailbox address — from variable | The input variable that holds the mailbox address. |
| App password — from variable | The input variable that holds the mailbox's app password. |
| IMAP host / IMAP port | Defaults to imap.gmail.com and 993. Change them for other providers. |
- The mailbox is read over IMAP in read-only mode; nothing is marked as read or changed
- Only a message that arrives after the run started counts, the newest match wins, and each message is used at most once
- The agent waits up to 5 minutes for the email, checking every 10 seconds
- If nothing arrives, the agent is told so, and your mission decides what happens next (resend the code, or stop)
- For Gmail or Google Workspace, turn on 2-step verification and create an app password
Say it in the mission, too: “After submitting the login form, wait for the verification email and enter the code.”
Chaining a flow to an agent
The strongest setup is extract, then act. A flow pulls fields out of a document, and the agent uses those fields as its inputs, so the document you received drives what happens on someone else's website with no copying by hand.
- 1On the agent, add variables with the source From flow run and pick the flow field each one reads (or use New from flow to create them all at once).
- 2Open the flow and select the Agent panel in its sidebar.
- 3Click Link Agent and choose the agent.
- 4Run the flow. When the run completes, the agent starts automatically with the flow's output as its input.
- The agent receives the cleaned output when the flow has a Cleaner
- If the flow uses Human in the Loop, the agent runs only after a reviewer approves, with the approved data; a rejected run never reaches the agent
- Deliveries and webhooks of an agent run started by a flow carry that flow run's ID
- In a pipeline, an Agent node does the same thing on a canvas, fed by a flow node
Worked example. A purchase order arrives by email. The flow extracts the supplier and the part numbers, and a Cleaner normalises them. The linked agent logs into the supplier portal, looks up the parts, captures the live unit price and lead time, and writes the results into a Bucket next to what the PO said, so the discrepancy is visible before anyone approves the order.
Where results go
An agent can deliver each completed run to several places at once. Turn on as many deliveries as you need on the Delivery tab; they run independently, so one failing never stops the others. With none turned on, results stay on the run page to view or download.
| Delivery | What arrives |
|---|---|
| The captured output as formatted JSON, to the recipients you list. | |
| Webhook | A POST to your URL with the captured output and the run's input variables. See webhooks. |
| Bucket | One row per run in a Bucket, with captures mapped onto columns (Map captures → bucket columns). |
| Subject | Files the captured documents into cases of a Subject: pick the list capture with one row per case (or the whole output as one case), the field that names the case, and a document type for each file capture. Re-running the agent never creates a duplicate case; by default it only adds the documents a case is still missing. |
Email and Bucket deliveries have an Include input variables in the delivered payload option, which makes a Bucket row self-describing: what was asked, and what came back. The webhook always includes them.
The webhook payload carries bot_id, bot_run_id, status, inputs (the run's resolved input variables, secrets excluded), output (the captures, with a link for each file) and, when a flow run triggered the agent, flow_run_id, so your system can attach the result to the document it came from.
{
"bot_id": "3f2a...",
"bot_run_id": "9c41...",
"status": "completed",
"flow_run_id": "b7e0...",
"inputs": { "part_number": "AX-2210" },
"output": { "unit_price": 18.4, "lead_time": "3 weeks" }
}If a delivery fails, the run is marked Completed with warnings and the run page lists the Delivery errors. The agent's creator also gets an in-app notification.
Running an agent
An agent can be started six ways. However it starts, it goes through the same limits, concurrency and deliveries.
| Trigger | How |
|---|---|
| Test run | The Test run button on the agent (or Run on the agents list). A form asks for each variable, prefilled with the static values; you can also fill it from a completed run of a flow. |
| Schedule | Settings → Schedule, described below. |
| Linked flow | Every completed run of a flow with this agent linked, as above. |
| Pipeline | An Agent node in a pipeline. |
| API | A POST from your own system, by the agent's ID or its name, described below. |
| Bucket trigger | One run per Bucket row that matches a condition, described below. |
Schedule. Turn on Run on a schedule and pick a frequency: Every hour, Every day, Weekdays (Mon–Fri), Every week or Custom cron (five fields: minute, hour, day of month, month, day of week, for example 30 8 * * 1-5). Times are in your organization's timezone, and the settings panel shows the next run.
- Scheduled runs use the static variables and secrets saved on the agent
- The schedule only fires while the agent is active
- Runs start within about a minute of the scheduled time, later if all workers are busy
- A missed window is not replayed: after a delay the agent fires once, not once per missed slot
- A scheduled run that can't start (the previous run is still going, or your organization can't start new work right now) appears as a failed run that says why
- Failures of scheduled and API runs send the agent's creator an in-app notification, since nobody is watching the run page
Bucket trigger. Under Settings → Bucket trigger, turn on Run once per matching bucket row to start one run for every row of a Bucket that passes your filters, for example one run per lead whose status is not yet complete. Pick the Row key that identifies a row and which columns fill which input variables.
- The bucket is checked about every 30 seconds; a row whose run is still in progress never gets a second one
- Each row gets a limited number of attempts per 24 hours (1 to 10, default 3), at least 10 minutes apart
- The pace is the agent's concurrency limit: N runs work while N more wait, and the trigger keeps the limit on
- Close the loop with a Bucket delivery that updates the same row (status = complete), so a processed row stops matching
- If the bucket is gone or credits run out, the trigger pauses and a failed run says why
Concurrency: limit overlapping runs
By default, overlapping triggers run in parallel. Many portals don't like two sessions for the same user at once, and some sites should not be hammered, so an agent can be limited to one run at a time, or up to ten, under Settings → Concurrency.
| Setting | Effect |
|---|---|
| Limit concurrent runs | While the limit is reached, new triggers (manual, API, schedule, linked flow, pipeline, bucket trigger) wait their turn and start as soon as a slot frees up, oldest first. |
| Runs at the same time | 1 to 10. 1 means one run at a time. |
| Minimum time between runs (minutes) | 0 to 1440, applies with Limit concurrent runs. Counted from the end of one run to the start of the next. It is a minimum: the next run also waits for a free worker. |
- A run waiting for its turn shows the status Waiting; it holds no worker and is not billed
- Up to 20 runs can wait per agent; beyond that, new triggers are refused (the API answers 429)
- A run that waits more than 24 hours is marked failed
- Only one scheduled run waits at a time, so a slow agent on a fast schedule can't pile up
Watching a run
Every run streams its steps as they happen, and you can open a live view of the browser session to watch it work. Finished runs keep a replay, so you can see exactly what the agent did rather than inferring it from the output.
| Status | Meaning |
|---|---|
| Waiting | Waiting for a free slot of an agent that limits its concurrent runs. |
| Queued | Accepted and waiting for a worker. |
| Running | The browser session is open. With human help on, the agent may be waiting for a person here, with the browser still open. |
| Waiting for a person | Paused: the agent asked for help, nobody came in time, and the run was saved where it was. Resume it from the run page. |
| Completed | Finished and delivered. Completed with warnings means a delivery failed. |
| Failed | The run hit an error or a limit; the run page says which. |
| Cancelled | Someone stopped the run. |
- Steps: a log of what the agent did, in order
- Captured output and Captured files, with downloads
- Summary: duration, LLM calls and tokens
- Watch live session while it runs, View session replay afterwards
- Browser sessions: one entry per browser session when the run paused for a person and was resumed
- Identifiers (run ID and session ID) for support requests
Cancel run stops a waiting, queued, running or paused run. The browser session ends within a few seconds and nothing is delivered.
When an agent returns the wrong value, the replay usually shows why in seconds: it logged into the wrong tenant, or the search returned no results and it guessed. Fix the mission, not the schema.
Human help: when only a person can continue
Some steps only a person can do: a captcha, a code sent to the account owner's phone, a login someone has to approve. Turn on Settings → Human help and the agent can stop and ask for help instead of failing, then carry on with the mission.
| Setting | What it does |
|---|---|
| Let the agent ask for help | Gives the agent a way to call on a person, with one sentence saying what it needs. |
| Wait with the browser open (seconds) | 0 to 600. How long the run waits, browser open, for someone to help. Empty uses the default (300); 0 pauses the run at once. |
- 1The agent asks. Whoever started the run (or the agent's creator) gets an in-app notification, Agent needs your help, that opens the run page.
- 2The run stays Running with the browser open. The run page shows The agent needs your help with its request, above the live session.
- 3Do what it asks in the live session, optionally leave a Note for the agent (“I typed the SMS code and logged in”), and press Done — continue. The agent picks it up within a few seconds, in the same browser.
- 4If nobody comes within the wait, the browser is closed and the run is saved where it was, with the status Waiting for a person. Press Resume run when you are ready: a new browser opens on the same page, still signed in, and the agent continues where it left off. If the obstacle is still there it asks again, so stay on the run page.
- The wait counts inside Max runtime and is billed as browser minutes; the agent always keeps about two minutes to finish after a wait
- A paused run holds no browser or worker and costs nothing while it waits; resuming needs the same one-minute minimum balance as a new run
- Resuming continues the same run: steps, captures, duration and credits add up, and Browser sessions lists every session with its replay
- A paused run can be resumed for 72 hours, then it is marked failed; one run can use up to 10 browser sessions
- A paused run can be cancelled; it frees its concurrency slot, but its schedule and its bucket-trigger row still count it as in progress
Say it in the mission too, so the agent knows when to ask: “If a captcha or a verification code appears, ask for help and wait.” For codes sent by email, a Mailbox (above) needs no person at all.
Human in the Loop reviews extracted data before it is delivered. Human help hands the agent's browser to a person in the middle of a run, so the agent can get past something it cannot do itself.
Limits
Runs are bounded so a mission that goes wrong cannot run forever. Two limits apply, both set per agent under Settings → Limits. Leave a field empty to use the default.
| Limit | Default | Range | When it is hit |
|---|---|---|---|
| Max runtime (minutes) | 10 minutes | 1 to 20 minutes | The browser is closed and the run is marked failed. |
| LLM request limit | 25 | 5 to 500 | The agent stops and the run is marked failed. Raise it for missions that cover many pages. |
Triggering from the API
Your own systems can start an agent and poll for the result with your API key, sent as X-API-Key to https://run.tavnit.io/api. Name the agent by its ID, shown on its Agent ID panel, or by its name.
| Request | What it does |
|---|---|
POST /bots/{agent_id}/runs | Starts a run. Optional body {"inputs": {...}} overrides static variables; secrets can't be passed. Returns 202 with bot_run_id and a status of queued or waiting. |
POST /bots/runs | The same trigger with the agent in the body: {"bot_name": "Supplier prices", "inputs": {...}}, or bot_id instead of bot_name. |
GET /bot-runs/{bot_run_id} | Status, timings, inputs and output (with file links). While the agent waits for a person, human_request says what it asked. |
GET /bots/{agent_id}/runs | The agent's runs, newest first, filterable by status. |
POST /bot-runs/{bot_run_id}/cancel | Cancels a waiting, queued, running or paused run. |
POST /bot-runs/{bot_run_id}/human/resolve | Human help: the same as pressing Done on the run page, with an optional note for the agent. |
POST /bot-runs/{bot_run_id}/resume | Human help: resumes a run that is Waiting for a person (awaiting_human). |
By name. bot_name must match the agent's name as shown in the app, ignoring case and extra spaces. Archived namesakes are ignored (a name only an archived agent has answers 409, agent archived). No match answers 404; when several active agents share the name the call answers 409 with their IDs in bot_ids, so rename one or use the ID. Renaming an agent changes what bot_name must say: use bot_id for integrations that must survive a rename.
Every API call starts a new run. A 402 means your organization can't start new work right now; contact the Tavnit team. For the full request and response reference, see the API page. If you would rather not call the agent directly, trigger the linked flow and let the agent follow.
Permissions
Only Owners and Admins can create, edit, duplicate or delete an agent, which includes setting secrets. Members can run agents, read their runs, help a run that asks for a person and resume a paused one. HITL Only members have no access to agents.
See user roles and permissions for the full matrix.
Troubleshooting
| Symptom | Likely cause and fix |
|---|---|
| The run failed with a runtime message | It hit Max runtime. Check the replay for where it got stuck; tighten the mission, or raise the limit if the task is genuinely long. |
| The run stopped halfway through a long list | The LLM request limit (default 25) ran out. Raise it under Settings → Limits. |
| A From flow run variable is empty | The run was not started by a flow, or the field name doesn't exist in the flow's (cleaned) output. |
| A secret was not typed | The page was on a different site from the starting URL, or the secret was never saved (it shows Not set). |
| The agent never received the email code | Check the sender, the optional subject filter, and the app password; the email must arrive after the run started. |
| Completed with warnings | A delivery failed (a bad webhook URL, a missing bucket). The run page lists the delivery errors. |
| The status stays Waiting | The agent limits its concurrent runs and every slot is taken, or the minimum gap has not passed yet. |
| The status is Waiting for a person | The agent asked for help and nobody pressed Done within the wait. Open the run, read what it asked and press Resume run; raise the wait under Settings → Human help if people need longer. |
| Triggering by bot_name answers 404 or 409 | 404: no active agent has that name (was it renamed?). 409: several active agents share it; the response lists their bot_ids. Rename one, or trigger by bot_id. |
| A scheduled run shows as failed without running | The previous run was still in progress, or your organization couldn't start new work at the time. The run's message says which. |
