Talk to Your Agent
Send Revnu messages from code, wait for the reply inline or poll, hand over many jobs in a row without interrupting, and keep retries safe with a client request id.
A message through the API does exactly what typing into the dashboard chat does. Revnu reads it, does the work with the same tools and Memory, and replies in one or more bubbles. Anything it wants approved lands in the review queue.
One call, with the reply inline
Pass waitSeconds (up to 120) and the request stays open until the message is done: Revnu has replied or failed and any background research it started has been reported. Replies usually land in well under a minute. Real work, such as researching a list, can take longer.
curl -X POST -H "Authorization: Bearer $REVNU_API_TOKEN" \
-H "content-type: application/json" \
-d '{"text":"Which leads replied this week?","waitSeconds":90,"clientRequestId":"weekly-replies-2026-42"}' \
https://revnu.com/api/v1/agent/messagesA 200 carries the finished message with its replies. If the wait runs out you get 202 with the last observed state and a requestId to keep polling.
Or post and poll
Without waitSeconds the POST returns 202 immediately. Poll GET /agent/messages/{requestId} every few seconds. status moves queued → running → replied, or ends failed with a failure message.
Progress bubbles can arrive in replies while it is still running. replied means the turn is over. Long research can keep running after it as a background task, listed in backgroundTasks; done turns true once that result is reported too. The poll returns the newest bubbles.
Note
Polling spends the agent-message limit, 30 calls a minute per token. Poll every 5 to 10 seconds rather than every second, or let waitSeconds do the waiting in one call.
Safe retries
Pass clientRequestId (up to 128 characters of A-Za-z0-9_.:-). A retried POST with the same id returns the original requestId with deduplicated: true instead of sending a second message. Make the id from the job itself, such as import-eu-fintech-2026-10-15, so a crash and restart sends the same id.
A failed message should be re-sent with a new id. Reusing the old one returns the failed request.
Interrupts
A new message stops whatever Revnu is still doing for this token and starts on the new one. That's right when you mean "stop, do this instead". It's wrong when a script fires jobs one after another. Two fields change it:
| Field | What happens while this token's last message is still queued or running |
|---|---|
| none (default) | The new message is sent and the running work stops. The old message is marked interrupted: true. |
"interrupt": false |
Nothing is sent. The response names the unfinished request with notSent: true. |
"queue": true |
The new message is sent and waits; Revnu starts it once the current work is done. |
queue and interrupt can't be combined. The MCP tool ask_revnu defaults to interrupt: false, so an assistant can't stop work by accident. The CLI's revnu agent message sends with the default, and takes --queue.
Many jobs in a row
To hand over several jobs, such as one list of companies per market, send each with queue: true and its own clientRequestId:
const jobs = [
{ id: "markets-2026-10-15-uk", text: "Find 20 UK fintechs with 50 to 200 staff that sell to SMBs." },
{ id: "markets-2026-10-15-de", text: "Find 20 German fintechs with 50 to 200 staff that sell to SMBs." },
];
for (const job of jobs) {
const res = await fetch("https://revnu.com/api/v1/agent/messages", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.REVNU_API_TOKEN}`, "content-type": "application/json" },
body: JSON.stringify({ text: job.text, clientRequestId: job.id, queue: true }),
});
const { requestId } = await res.json();
saveRequestId(job.id, requestId); // poll each later
}Each job runs to the end before the next starts. A queued message waits up to six hours behind earlier work, then counts as failed, so don't queue a day's worth at once.
Tip
Put a whole list in one message where you can. A single message holds up to 4,000 characters.
A worked rate example
Say you have 40 jobs. The agent-message limit is 30 calls a minute per token, and sending a message, polling a message and reading the thread all spend it. GET /agent/status is a read and spends the separate read limit of 300 a minute.
Send the jobs at 20 a minute
The 40 jobs go out over two minutes. That leaves 10 message calls a minute spare.
Watch the account status
While they run, poll
GET /agent/statusevery 10 seconds. That's 6 reads a minute and touches nothing in the message budget.Check each job
Read
GET /agent/messages/{requestId}for each job every minute or so, oldest first. Stop polling a job oncedoneistrue.
The jobs run one after another, so the batch takes as long as all 40 together. If each takes about five minutes, the last starts more than three hours after the first. Anything still waiting after six hours fails, so split a bigger batch across the day, or put several markets in one message.
Keep research jobs from sending anything
A message can't promise "research only". Whether Revnu's work goes out depends on What Needs Your Approval in Settings > Agent.
To be sure a batch of research jobs only produces leads and drafts, set Start Sequences, One-Off Emails, Connection Requests and Messages to Ask Me First before you send the batch. Drafts then wait as cards in the review queue until someone approves them.
Warning
These settings don't recall a sequence that is already live: its later steps keep sending. To stop that too, see Pause or Stop Everything.
To check whether Revnu is busy with anything on the account, including chat, Slack and scheduled work, read GET /agent/status: running is true while a turn is in progress.
Each token is its own conversation
Your dashboard and Slack threads are not visible through the API, and API messages do not appear in them. GET /agent/thread returns this token's conversation, newest first. Revnu sees each message as coming from API token "<label>", so give a bot or coding agent its own token and Revnu can tell it apart from you.
Status questions without side effects
A message is a request for work. Telling Revnu "status only, don't change anything" is an instruction it follows, not a permission it can't break. For a status bot, read the numbers directly, with a token that holds only read scopes:
| Question | Read |
|---|---|
| Is LinkedIn paused, and until when? | GET /results: linkedin.data.health.pausedUntil and pauseReason |
| Did a blog post fail? | GET /results: seo.data.postsFailed |
| What is waiting for approval? | GET /review |
| Is Revnu working right now? | GET /agent/status |
| What did a workflow run do? | GET /workflows/{id}/runs |
Some answers only Revnu can give. There is no endpoint for how a sending inbox's warm-up is going or when it will start sending, and none for why a post failed. Ask Revnu with a message, which needs agent:message:
curl -X POST -H "Authorization: Bearer $REVNU_QUESTIONS_TOKEN" \
-H "content-type: application/json" \
-d '{"text":"Are my sending inboxes ready to send yet? Which are still warming up?","waitSeconds":90,"interrupt":false}' \
https://revnu.com/api/v1/agent/messagesinterrupt: false means a question never stops a job this token started. If one is still running, nothing is sent and the response says notSent: true. The message is still a request Revnu can act on, so keep it to a question and use a separate token for it. A status bot that can also explain has the full setup.
Frequently Asked Questions
Can Revnu do work from an API message, not just answer?
Yes. It is the same Revnu with the same tools. Ask it to draft outreach and the draft lands in the review queue like any other. Whether it then sends on its own follows your approval settings.
How do I send several jobs without each one stopping the last?
Send each with "queue": true and its own clientRequestId. Revnu starts each one when the one before has finished.
How do I stop an API job from sending emails?
Set the sending kinds of work to Ask Me First in Settings → Agent, under What Needs Your Approval. Words in the message, such as "don't send anything", are an instruction Revnu follows, not a lock. The setting is the lock.
Is POST /agent/messages idempotent?
Yes, with clientRequestId. The same id from the same token returns the original requestId and deduplicated: true, and nothing is sent twice.
Is there an API endpoint for inbox warm-up progress?
Warm-up progress comes through a message. Ask Revnu: > Are my sending inboxes ready to send yet? Then read the reply. In the dashboard, the account menu at the top of Inbox shows Warming up next to inboxes that aren't ready.
How do I know Revnu is even up?
GET /agent/status reports the sandbox state, whether a turn is running, and the next scheduled wake.
Why did my message come back failed?
Read failure for the reason. A queued message also fails after six hours waiting behind other work, and interrupted: true means a later message stopped it. Re-send it with a new clientRequestId.