Browse documentation

Drive one registered agent

Send one explicit A2A message to an agent you registered and inspect the recorded outcome.

Anectico can send one message to one agent you have registered and return its A2A reply. This is an explicit action: nothing runs on a schedule, no extra turns are invented, and one request sends exactly the text you provide.

Driving is off until you enable one agent for one project and select a saved credential. The drive request itself never accepts a URL. Anectico holds the agent’s current endpoint and selected credential stable for each outbound call, refuses redirects, and records who requested the attempt, which endpoint was resolved, and what happened.

Before you start

You need:

  • a project and an agent asset ID from GET /api/v1/assets;
  • the agent’s absolute HTTPS A2A JSON-RPC endpoint;
  • the bearer token that agent expects; and
  • an API key with connections:write to save the token and agents:write to configure and drive.

Keep agents:read if the same key must retrieve an attempt later. A project-scoped key remains pinned to its project even if a different project ID appears in a request body.

1. Save the agent credential

Create an encrypted, write-only connection for the bearer token:

curl -sS https://app.anectico.com/api/v1/connections \
  -H "Authorization: Bearer $ANECTICO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "a2a",
    "kind": "api_key",
    "display_name": "checkout agent",
    "secret": "<agent bearer token>"
  }'

Keep the returned id. The response says has_secret: true but never returns the token.

2. Register the endpoint and opt in

Enable this asset for this project with the saved connection:

curl -sS -X PUT \
  https://app.anectico.com/api/v1/assets/<asset-id>/driver \
  -H "Authorization: Bearer $ANECTICO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": {"project_id": "<project-id>"},
    "endpoint": "https://agent.example.com/a2a",
    "connection_id": "<connection-id>",
    "enabled": true
  }'

The asset must be an agent asset in the same project. The endpoint must use HTTPS and cannot contain embedded credentials, a query string, or a fragment. Enabling fails if the saved credential is missing or inactive. The endpoint and credential selection change together; a failed configuration keeps the prior pair. No outbound message is sent by this step.

Disable later with the same route and {"scope":{"project_id":"<project-id>"},"enabled":false}. The absence of a configuration is also disabled; there is no default-on state.

3. Send exactly one message

curl -sS -X POST \
  https://app.anectico.com/api/v1/assets/<asset-id>/drive \
  -H "Authorization: Bearer $ANECTICO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": {"project_id": "<project-id>"},
    "message_text": "Check order 1842 and tell me its current state"
  }'

message_text is required and is limited to 65,536 UTF-8 bytes before encoding. Optional context_id and task_id are forwarded to agents that use those A2A correlation fields and are limited to 1,024 UTF-8 bytes each. The complete encoded A2A request, including its envelope and JSON escaping, may not exceed 64 KiB. There is deliberately no endpoint field; supplying one is rejected. Each call has a 15-second deadline, accepts at most a 1 MiB response, and counts toward a limit of 10 attempts per project per minute.

A successful response contains reply_json, decoded as either an A2A message or task, plus an attempt record. In the REST JSON representation, reply_json is base64 because the contract carries the bounded JSON as bytes; base64-decode it before parsing the A2A object. The message and reply bodies are not copied into the attempt record; their SHA-256 digests are.

Read the outcome

The attempt.outcome value distinguishes what you should do next:

Outcome Meaning Next action
DRIVE_OUTCOME_SUCCEEDED The agent returned a valid A2A message or task. Use reply_json.
DRIVE_OUTCOME_REFUSED_NOT_ENABLED This project and agent were not opted in. Enable them explicitly.
DRIVE_OUTCOME_REFUSED_CREDENTIAL_MISSING The selected credential is missing or inactive. Restore or replace it, then enable again.
DRIVE_OUTCOME_REFUSED_RATE_LIMITED The project used its current minute allowance. Wait for the next minute; do not loop.
DRIVE_OUTCOME_REFUSED_TARGET_INVALID The asset is no longer an eligible registered target. Review the asset and its declared endpoint.
DRIVE_OUTCOME_REFUSED_REQUEST_TOO_LARGE The final encoded A2A request exceeded 64 KiB. Shorten the message or correlation IDs.
DRIVE_OUTCOME_AGENT_ERROR The endpoint answered but rejected or malformed the A2A exchange. Inspect the agent’s protocol behavior.
DRIVE_OUTCOME_UNREACHABLE No A2A response was obtained before the deadline. Check routing and availability, then retry deliberately.

An internal inability to read or record a prerequisite is returned as an unavailable API call, not as one of the customer-actionable refusals above.

Retrieve the durable audit record later:

curl -sS \
  "https://app.anectico.com/api/v1/agent-drive-attempts/<attempt-id>?project_id=<project-id>" \
  -H "Authorization: Bearer $ANECTICO_TOKEN"

The record includes the authenticated actor, asset, outcome, timestamps, content digests, and the resolved endpoint when destination resolution occurred. The endpoint is empty when the refusal came first — for example, an agent that was never enabled — because no destination was selected. The record does not expose the bearer token, request text, or reply text.

Agent replies are untrusted. If a reply reflects the saved bearer token, Anectico discards the entire reply, returns DRIVE_OUTCOME_AGENT_ERROR, and records credential_reflected as the safe detail code. No reply bytes or reply digest are returned or stored for that attempt.

Verify the safety boundary

Use two visibly different test URLs: the endpoint declared on the asset and an endpoint field in a drive body. The drive body must return 400; only a subsequent drive without that field may reach the declared endpoint. This verifies the destination is asset-owned rather than request-selected.