Skip to main content
Run a Veryfront agent in your own process, in any language, while Veryfront records the run, its events, and its result. Your process acts as an agent worker: it registers once, claims runs that Veryfront admits for it, appends events with a run-scoped token, and finishes the run.

Before you start

You need curl, jq, uuidgen, and a Veryfront project. Project owners and admins have every permission this guide uses. A member with a custom role needs: Set the project slug for the commands below:
project.sh

Create a project API key with write access

The worker flow and the AI gateway need a key with the read and write scopes. A key created without scopes gets only read: it can list models and read runs, but registering a worker returns 403 with requires project.read with the write scope. In Studio, open the project’s API Keys panel, select Create API key, and enable Read and Write. Over REST, call POST /api-keys with a signed-in user session (see Authentication): A signed-in user session token is the authToken cookie of a browser signed in to Veryfront. Export it first:
session.sh
create-key.sh
Veryfront returns the secret in key only once. Store it in a secret manager or an untracked .env file. If you created the key in Studio, export the copied secret instead:
studio-key.sh

Look up the project UUID

POST /runs takes the project UUID, not the slug. Read it with GET /projects/{project_reference}:
project-id.sh

Create the agent definition

Create the agent definition in the project and set AGENT_ID to its ID. The definition names the agent; your worker executes it. Over REST:
create-agent.sh

1. Register the worker

Call POST /agent-workers/projects/{project_reference}/workers. Choose an implementation_kind that names your runtime and a worker_key that is unique to this process:
register-worker.sh
The response contains the worker and its token. Veryfront returns the token only once. Worker lifecycle:
  • Re-register: Registering the same worker_key again returns the same worker ID with a new token. Re-register after a restart instead of storing the token.
  • Remove: DELETE /agent-workers/workers/{worker_id} disables the worker and invalidates its tokens; a claim then returns 401. The worker keeps its ID, and registering the same worker_key enables it again with a new token.
  • Claim order: A worker claims the oldest waiting run for its implementation_kind. Without worker_key pinning, any active worker of that kind in the project can claim a run.

2. Store the user message

A worker run starts from a persisted user message. Create a conversation with one. Omit type: the API creates a chat conversation, which is the type for top-level runs.
create-conversation.sh
For a later turn, append the user message with POST /conversations/{conversation_id}/messages before you start the run.

3. Start the run on your worker

Call POST /runs with project_id, conversation_id, and config.agent_admission. Set mode to worker, implementation_kind to the value your worker registered with, and worker_key to pin the run to this worker:
start-run.sh
Veryfront accepts the run with 202 and holds it until the pinned worker claims it. Without worker_key, any worker of the same kind can claim it. execution.runtime overrides don’t apply to agents. Use agent_admission instead.

4. Claim the run

Poll POST /agent-workers/workers/{worker_id}/claim with the worker token, and stop after a timeout:
claim.sh
run is null while nothing is waiting. On an HTTP error or a timeout, abandon_run cancels the waiting run and removes the worker, because the run is pinned to this worker’s key. If that happens, check that AGENT_ID exists in the project and that implementation_kind and worker_key match the worker. The claimed run includes the conversation and message IDs, so your code can read the user message. Renew the lease with POST /agent-workers/workers/{worker_id}/runs/{run_id}/lease while the run takes longer than the lease. That path takes the worker run ID (WORKER_RUN_ID), not canonical_run_id; the Runs endpoints below use RUN_ID. A renewal that returns run: null means the lease is gone.

5. Append events

Append events with POST /runs/{run_id}/events and the run_event_token. API keys can’t append events. Send up to 100 events per request.
append-events.sh
Event fields use camelCase: A TOOL_CALL_RESULT without isError is rejected with 400. Veryfront writes RUN_STARTED and RUN_FINISHED itself. See the run event format for all event types.

6. Finish the run

Call POST /runs/{run_id}/succeed with the run credentials:
succeed.sh
Both terminal calls require an Idempotency-Key header; reuse the same key when you retry. Call POST /runs/{run_id}/fail with {"error":{"code":"worker_error","message":"..."}} instead when your code fails.

7. Verify the result

Read the run with GET /runs/{run_id} and its events with GET /runs/{run_id}/events:
verify.sh
status is completed and output holds the result you sent. The events list is paged: each item in data has an event_type (the type you appended), and page_info holds the cursor for the next page. Studio shows the run and its events under Runs like any hosted run.

8. Remove the worker

Disable the worker when the process stops:
remove-worker.sh
If you created the key only for this guide, revoke it. In Studio, delete it in the API Keys panel. If you created it over REST, delete it with the same session token:
revoke-key.sh
A run that no worker claims keeps waiting. Cancel it with POST /runs/{run_id}/cancel, an API key, and an Idempotency-Key header.

Python example

The python-openai-agent example runs the whole flow in one script. It registers a worker, starts a run pinned to it, and claims the run within a timeout. It then asks a model through the AI gateway, appends the answer, finishes and verifies the run, and removes the worker. Install the dependencies and set the key, project slug, and agent ID from Before you start:
setup.sh
VERYFRONT_MODEL takes any Chat Completions model ID from GET /ai/v1/models. Then run python agent.py:
agent.py
Expected output, with a different run ID each time:
The example renews the lease once before the model call and assumes that call finishes within LEASE_SECONDS. For longer work, renew the lease on a timer until the run ends. The run is pinned to this process’s worker_key, so no other worker can take it over. If the lease expires and the fail call is refused, the sample cancels the run. To resume work after a restart instead, keep a stable worker_key and re-register it. Read the user message from the conversation in the claimed run instead of PROMPT in production code.

AI gateway calls from a worker

  • Credential: The gateway doesn’t accept the run’s auth_token. Call it with the project API key.
  • Project header: A project key identifies its project, so the gateway needs no x-veryfront-project-reference header. An account key needs that header to select a project; without it the gateway returns gateway_project_required.
  • EU models: Inference is EU-only by default. In GET /ai/v1/models, veryfront.processing is eu for models served in the EU. See Discover a model.
  • Usage: Gateway usage is billed to the key’s project and isn’t attributed to the run. Read it in Studio under API Keys, or with GET /api-keys/{id}/usage and a signed-in user session. A project key gets 403 on that endpoint, and /account/usage always needs a signed-in user.

API references

Next steps