Skip to content

How the API executes a prompt

Updated
Reading time
4 min
Level
beginner

Your request is written to a durable queue, dispatched to an idle agent in Revoye Desk on one of your own paired machines, and answered by one of your own AI accounts. Every design decision below follows from one fact: the answer comes from a computer you own, which is slower and less reliable than a data centre, and is sometimes asleep.

Understanding this is what stops you designing an integration that fights the system.

The path

your application
  → POST /v1/completions
  → your queue                    durable; survives restarts and offline devices
  → is one of your devices online?
  → Revoye Desk on your machine   your paired computer
  → an idle agent                 one of your AI accounts
  → the agent answers
  → back the same way to your waiting request, or to your callback_url

1. Accepted means durable

Revoye writes the job down before it does anything else. From that moment:

  • A dropped connection does not lose it. Fetch it at GET /v1/completions/{id}.
  • A Revoye deploy does not lose it.
  • Your machine being offline does not lose it.

This is the single most useful property to design around. Your integration's job is to record the id, not to hold a connection.

2. The device check comes before the dispatch

Nothing is dispatched until the router knows one of your devices is connected. If none is:

Your request saidWhat happens
wait: trueThe request waits. The job queues, and runs when a device returns
wait: false with a callback_urlAccepted and queued. The webhook fires when it runs
wait: false, no callback_url503 NO_DEVICE_ONLINE immediately — there would be nobody to tell

For anything unattended, the second row is the one you want.

3. Agent selection is a filter, then a strategy

A candidate agent must clear all of:

  • enabled in your dashboard, and enabled in Revoye Desk
  • currently idle
  • its provider is enabled
  • its device is connected
  • it has not already failed this job
  • under its own hourly limit, its provider's hourly limit, and your global hourly limit
  • permitted by your time-window policy, if you use one
  • matching the provider you asked for, if you asked for one

An agent already answering another prompt is not idle, and the router skips it rather than interrupting it. If your traffic outgrows your agents, the fix is more agents — several per account if you want more answers at once.

Whatever survives, your rotation strategy chooses from: round robin, least recently used, priority, or time window. You set the strategy in the dashboard; rate limits and capacity covers what happens when the filter empties.

4. The agent waits for a complete answer

The agent puts your prompt to the provider using your own account and waits for the answer to be finished, not for a fixed timer. You get it once it is complete.

This is why run_ms in the response is usually tens of seconds, and why it varies with prompt length, provider load and the model the provider decided to use. It is also why there is no streaming: an answer is delivered whole, so there is no partial output to forward.

5. Timeouts and retries protect the job, not the connection

Two separate clocks:

FieldDefaultRangeCovers
Per attempttimeout_ms180 0005 000–600 000One dispatch to one agent
Whole jobdeadline_ms900 00010 000–3 600 000Every attempt together

When an attempt times out, the job is taken off that agent and offered to the next eligible one — never back to one that already failed it. When the deadline passes, the job stops.

wait: true holds your HTTP connection for at most min(deadline_ms, 600000). If that expires you get 504 JOB_TIMEOUT with the job id, and the job keeps running. The timeout is your patience, not the job's.

6. The result comes back with its history

Every completed job tells you what happened, not just what it produced: provider, agent_id, attempts, queue_ms (how long it waited before the first dispatch, even after retries) and run_ms. When something is slow, those four fields say whether it was your queue, your fleet, or the provider.

What this means for your integration

  1. Store the job id. It is the only thing you cannot recover.
  2. Set a long client timeout, or don't wait at all. A 30-second default will abandon healthy work.
  3. Use Idempotency-Key. Retrying safely.
  4. Treat NO_DEVICE_ONLINE and NO_AGENT_AVAILABLE as capacity, not failure. Back off and retry.
  5. Run more agents for more throughput. One agent is one prompt at a time.