Skip to main content

Agent Jobs - How Connector APIs Work

Every vME connector is driven the same way: vME creates a job, an agent installed on the target host picks it up, runs one phase of the workflow locally, and reports progress and results back. The vME web console does exactly this behind the scenes, so anything the console can do, an API client can do too.

This page covers the parts that are identical for all connectors - the job envelope, the job lifecycle, timeouts, error handling, and how to monitor a job to completion. What differs per connector is the set of phases and the config fields inside each phase; those live with the connector:

ConnectorPhase and config reference
iSCSI (SQL Server on Windows)iSCSI API reference

For the full request and response schemas of each endpoint, see the Agent API section of the vME API reference. This page explains how to put those endpoints together.

Admin only

All of the endpoints below require an administrator account. Authenticate with the username and api-key headers, as elsewhere in the vME API.


The Model

  1. An administrator mints a one-time enrollment token (POST /agent-token) and gives it to whoever installs the agent on the host.
  2. The agent enrolls itself with that token, receives a long-lived agent key, and runs as a background service.
  3. The agent polls vME over outbound HTTPS (port 443). No inbound ports are opened on the host.
  4. An administrator creates a job (POST /agent-job) naming the agent, the phase, and the phase's config.
  5. The agent claims the job, runs the phase, streams progress events back, and finishes as completed or failed.

Enrollment, claiming, and progress reporting are performed by the agent using its own credentials (x-agent-id / x-agent-key). Those routes are part of the agent protocol and are never called by hand.

Because the agent polls, the agent must be online for a job to run. A job created for an offline agent stays queued until the agent comes back or the job is cancelled.


The Job Envelope

Every connector uses the same request shape:

{
"agent_id" : "agt-...",
"phase" : "SourcePrep",
"config" : { },
"secrets" : { },
"workflow_id" : "wf-..."
}
FieldRequiredPurpose
agent_idYesWhich agent runs the job. Get IDs from GET /agent. The agent must be online.
phaseYesWhich unit of work to run. The valid values are connector-specific - see the connector's API reference.
configPer phaseNon-secret settings for the phase. This is the only part of the envelope that changes shape between connectors.
secretsNoSecret values (for example CHAP credentials). Stored encrypted, redacted from logs, and never returned by GET /agent-job.
workflow_idNoAssociates the job with an onboarding workflow so the console can track it as part of a larger sequence. Omit for standalone jobs.

config and secrets are merged

The agent merges secrets over config into a single settings object before running the phase. A field can therefore be supplied in either block, and the only difference is how it is stored and logged. Put every credential in secrets so it stays out of job listings and log files.

Config is validated up front

The agent validates the config against the phase's required fields before it touches the host. If anything mandatory is missing, the job fails immediately with a message naming the missing keys, using dotted paths for nested blocks:

Missing required config for phase CloneMount: attach.dbSelection, targetSelection

Nothing on the host is modified when validation fails, so a rejected job is always safe to correct and resubmit. Which fields are mandatory depends on the phase and sometimes on which other fields you supplied - the connector's API reference lists the rules.


Job Lifecycle

StateMeaning
queuedCreated in vME, waiting for the agent to pick it up on its next poll.
claimedThe agent has taken the job and is about to run it.
runningThe agent is executing the phase on the host.
completedThe phase finished successfully.
failedThe phase errored, or config validation rejected it. The agent has returned to idle.
cancelledThe job was cancelled before it finished.
timed_outvME stopped hearing from the agent for longer than the staleness window. Not terminal - see below.

completed, failed, and cancelled are terminal. Re-running work means creating a new job.

timed_out is not an outcome

vME marks a job timed_out when the host's agent stops reporting - a service restart or a network blip is enough. The work on the host is not stopped by this and is often still running; only the reporting lapsed.

An agent that comes back can move the job on to completed or failed. A client polling for a terminal state must therefore treat timed_out as still in progress, not as a failure. It is separate from the job_timeout_seconds budget below, and raising that budget does not prevent it.

Creating a job

curl -X POST \
-H "Content-Type: application/json" \
-H "username: xxxxx" -H "api-key: xxxxx" \
-d '{"agent_id": "agt-abc123", "phase": "DiscoverHost", "config": {}}' \
"$BASE_URL/agent-job"

The response contains the created job, including its job_id.

Polling a job

curl -X GET -H "username: xxxxx" -H "api-key: xxxxx" \
"$BASE_URL/agent-job?job_id=job-abc123&include_events=1"

include_events=1 adds the job's progress events, which are the same lines the console timeline shows. Poll every few seconds until state is terminal - keep polling through timed_out, which is not. GET /agent-job also accepts filters (agent_id, state, workflow_id, job_type, role, limit) for listing jobs rather than fetching one.

Cancelling a job

curl -X PATCH \
-H "Content-Type: application/json" \
-H "username: xxxxx" -H "api-key: xxxxx" \
-d '{"job_id": "job-abc123", "action": "cancel"}' \
"$BASE_URL/agent-job"

Cancelling a queued job stops it from ever running. Cancelling a running job stops the agent's work on the host, but any change already made on the host stays made - there is no automatic rollback. Check the host state before retrying.


Timeouts

Long phases need a longer budget than the default. Set job_timeout_seconds in config on the job:

{
"agent_id" : "agt-abc123",
"phase" : "SourceMigrateOnly",
"config" : {
"job_timeout_seconds": 86400,
"migrate": { }
}
}
BehaviourValue
Default when not set3600 seconds (1 hour), unless the phase has a longer built-in default
Minimum accepted60 seconds
Maximum accepted604800 seconds (7 days)

Values outside the range are clamped rather than rejected. Some phases carry a longer built-in default because they are expected to run for hours - the connector's API reference lists them. When the timeout is reached, the agent terminates the phase and its whole child process tree, and the job fails with Workflow timed out after <n> seconds.

Set the timeout generously. A phase killed part way through leaves partial work on the host exactly as a cancellation does.


Results

Some phases report structured values back to vME on success - for example the SQL instance a phase actually resolved and used. These land on the job result and, when the job belongs to a workflow, are persisted onto the workflow so later jobs in the same sequence can reuse them. Which keys a phase returns is documented with the phase.

You do not need to parse agent logs to get these values; read them from GET /agent-job.


If the Agent Goes Offline Mid-Job

What happens depends on whether the phase itself stopped or only the reporting did.

Reporting lapsed, work continued. A network blip, or the agent service restarting while the phase's own process survives, stops the heartbeat without stopping the work. vME marks the job timed_out, and the returning agent moves it on to completed or failed. Nothing to do but keep polling.

The phase stopped. If the phase itself was killed - the host rebooted, or the service went down and took the process tree with it - the job is not resumed when the agent comes back. To recover:

  1. Review the agent's logs on the host to see how far the phase progressed. Log locations are documented per connector.
  2. Assess any partial work manually. There is no automatic rollback.
  3. Correct the host state and create a new job.

A job sitting in timed_out does not tell you which of the two happened. The agent's log on the host does - check whether the phase's output continued past the point where reporting stopped.


Managing Agents

TaskEndpoint
Mint an enrollment tokenPOST /agent-token
List or revoke tokensGET /agent-token, DELETE /agent-token
List agents (filter by environment, status, enabled, version)GET /agent
Enable, disable, rotate key, or refresh last-seenPATCH /agent with action
Delete an agentDELETE /agent

Full schemas for each are in the Agent API reference. Installing and enrolling an agent is covered in the connector's own guide, since the installer and its prerequisites are platform-specific.


Ready-to-Run Examples

The vME Postman collection includes an Onboarding (API) folder that runs the full connector workflow as ordered, chained requests, with the job IDs carried between steps automatically. It is the fastest way to see a working sequence before writing your own client.