Docs/Agent management
Docs/Agent management

Ingestion API

The ingestion API is how your systems tell the agent that something happened. Post an event, and every flow attached to it runs.

Everything the agent does starts here. Your systems post an event to the ingestion API, and the agent schedules and runs every published flow attached to that event.

This is the only part of the agent your applications talk to. Flow definitions arrive from the platform, and results go back to the platform, but the trigger comes from you.

Base URL

http://<agent-host>:5002/api/v1

Ingestion listens on port 5002. How you reach it depends on your deployment:

  • Docker: the host and mapped port, for example http://agent.internal:5002/api/v1.
  • Kubernetes, in-cluster: http://vaurd-agent-ingestion.vaurd.svc.cluster.local:5002/api/v1.
  • Kubernetes, from outside: through the ingress you configured, for example https://agent.example.com/api/v1.

Two other paths are available on the same server. GET /api/v1/healthcheck reports whether ingestion is up, which is useful as a readiness probe. GET /api/v1/swagger/ serves the generated API browser.

Before you can post an event

The event has to exist. Create it in the web application first, under Events, and make sure it has synced to this agent. The agent rejects an event type it does not recognise.

See Events for creating one, and What an event contains for how its parameters are declared.

Post an event

POST /api/v1/ingest
Content-Type: application/json

Tells the agent that something happened. The agent records the event, queues it, and returns immediately. Flows run afterwards, in the background, so this call does not wait for them.

Request body

FieldTypeRequiredWhat it does
typestringYesThe technical name of the event, exactly as created in the platform. This is what the agent matches flows against.
idstringYesYour own identifier for this event, used to correlate it in the agent's logs.
dataobjectConditionalThe event payload. Required when the event declares parameters.
sourcestringNoWhere the event came from. Recorded alongside the event.
specversionstringNoCloudEvents spec version. Recorded alongside the event.
timestringNoAccepted but not used. The agent stamps its own receive time.

`type` is the important one. It has to match the event's technical name character for character. If no event with that name is registered on the agent, the request is rejected.

`data` is validated against the event's parameters. For each parameter the event declares, the agent checks that a required one is present and that its value has the declared type. Extra fields you send that the event does not declare are accepted and passed through untouched. If the event declares no parameters, data can be omitted.

`id` is documented as optional but should always be sent. The agent uses it when logging a successfully queued event.

`time` is ignored. Whatever you send is replaced with the moment the agent received the event, so events are ordered by arrival rather than by a clock you control.

JSON
{
  "id": "6f1c2a5e-3d7b-4a19-9c2e-88f0a1b4d5e2",
  "type": "order_placed",
  "source": "checkout-service",
  "specversion": "1.0",
  "data": {
    "order_id": "A-1001",
    "total": 249.99,
    "currency": "USD"
  }
}
BASH
curl -X POST http://agent.internal:5002/api/v1/ingest \
  -H 'Content-Type: application/json' \
  -d '{
    "id": "6f1c2a5e-3d7b-4a19-9c2e-88f0a1b4d5e2",
    "type": "order_placed",
    "source": "checkout-service",
    "data": { "order_id": "A-1001", "total": 249.99 }
  }'

Successful response

JSON
{
  "id": "0199c8ef-5d88-7895-a52c-40b092b508de",
  "status": "QUEUED"
}

The id here is not the one you sent. It is the execution event id the agent assigned, and it is what you use to check status later. Store it if you want to follow the run.

When the agent is not ready

If the agent is registered but not currently allowed to process work, the event is still accepted and recorded. It simply waits.

JSON
{
  "id": "0199c8ef-5d88-7895-a52c-40b092b508de",
  "code": "AGENT_NOT_OPERATIONAL",
  "status": "QUEUED",
  "message": "Agent is blocked currently. Event was ingested but will not be processed until the agent is operational."
}

This comes back as 503 Service Unavailable. Treat it as accepted rather than failed. Retrying would create a duplicate, because the first one was already stored. The event is processed once the agent returns to connected.

Errors

StatusWhen
400The body could not be parsed, type is missing, or data failed validation against the event's parameters.
404No event with that type is registered on this agent.
500The agent could not store or queue the event.

Errors share one shape:

JSON
{
  "statusCode": 400,
  "message": "event data validation failed: required field 'order_id' is missing",
  "reason": "Bad Request",
  "requestId": "..."
}

Check an event's status

GET /api/v1/ingest/{id}

Returns what happened to an event, including every flow it triggered. The {id} is the execution event id returned by the POST, not the id you sent.

BASH
curl http://agent.internal:5002/api/v1/ingest/0199c8ef-5d88-7895-a52c-40b092b508de
JSON
{
  "id": "0199c8ef-5d88-7895-a52c-40b092b508de",
  "eventId": "01a027ab-8000-7cee-86fe-f9a0e178f439",
  "name": "order_placed",
  "status": "FLOWS_SCHEDULED",
  "data": { "order_id": "A-1001", "total": 249.99 },
  "executions": [
    {
      "id": "01a027b1-1111-7000-9000-aaaabbbbcccc",
      "flowId": "01a027b2-2222-7000-9000-aaaabbbbcccc",
      "versionId": "01a027b3-3333-7000-9000-aaaabbbbcccc",
      "flowName": "Order total check",
      "versionName": "v3",
      "status": "SUCCESS",
      "retryCount": 0,
      "rootExecutionId": "01a027b1-1111-7000-9000-aaaabbbbcccc",
      "createdAt": "2026-09-15T09:12:04Z"
    }
  ],
  "createdAt": "2026-09-15T09:12:03Z",
  "updatedAt": "2026-09-15T09:12:05Z"
}

Event status values

StatusWhat it means
CREATEDThe agent recorded the event but has not queued it yet.
QUEUEDThe event is on the queue, waiting to be matched to flows.
FLOWS_SCHEDULEDOne or more flows were matched and scheduled.
NO_FLOWS_SCHEDULEDThe event was valid, but no published flow is attached to it.

NO_FLOWS_SCHEDULED is worth watching for. It is not an error, and nothing went wrong with your request, but nothing ran either. It usually means the flow you expected has not been published to this agent.

Execution status values

Each entry in executions is one flow run.

StatusWhat it means
NEWCreated but not scheduled yet.
SCHEDULEDWaiting for a worker, or waiting out a configured delay.
IN_PROGRESSA worker is running the flow now.
SUCCESSThe flow finished.
FAILEDThe flow stopped on an error.

The three retry fields describe re-runs scheduled by a rule node. On a first run, retryCount is 0, rootExecutionId equals the execution's own id, and retryNodeId is absent. On a retry, retryCount increments, rootExecutionId still points at the original run, and retryNodeId names the rule that scheduled it. That lets you group an original and all its retries together.

Errors

StatusWhen
400The id in the path is not a valid identifier.
404No execution event with that id exists on this agent.
500The agent could not read the record.

Using the API well

Post and move on. The call returns as soon as the event is stored and queued, and flow execution is asynchronous. Do not hold a user-facing request open waiting for a result.

Keep your own id. The agent's execution event id is what you need for the status endpoint, so store it against your own record when the POST returns.

Treat 503 as accepted. The event is already stored. Retrying duplicates it.

Poll sparingly, if at all. The status endpoint is there for debugging and reconciliation. For ongoing visibility, the agent's analytics in the web application are the better place to look.