Use this guide when a machine caller needs to create, update, or retire subordinate agents instead of only reading secrets.
These routes are available on the machine API today. The gap was documentation, not missing endpoints.
machine.agent.read / machine.agent.writeTENANT_AGENT_MANAGER or an admin bypassmachine.permissions.read / machine.permissions.write as well if the parent runtime also needs to delegate project, vault, or vault-item access| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/machine/agent | GET | List agents in the current tenant and discover a reusable domainTenantId |
/api/v1/machine/agent | POST | Create a subordinate agent and receive its one-time API key |
/api/v1/machine/agent/:id | GET | Read one agent |
/api/v1/machine/agent/:id | PATCH | Update agent metadata such as name, budget, or security groups |
/api/v1/machine/agent/:id/archive | PATCH | Archive an agent |
/api/v1/machine/agent/:id/regenerate-api-key | POST | Rotate the agent API key and receive a new one-time secret |
/api/v1/machine/agent/:id/vault-item | PATCH | Link an agent API key to a vault item |
/api/v1/machine/agent/:id/tenant-roles | GET | Read direct and inherited tenant roles |
/api/v1/machine/agent/:id/tenant-roles | PATCH | Replace direct tenant roles |
/api/v1/machine/tenant-context | GET | Read the active tenant and default domainTenantId |
Use the tenant-context helper or list agents when you need a valid domainTenantId for a new child agent in the same tenant.
curl "https://r4.dev/api/v1/machine/tenant-context" \
-H "X-API-Key: YOUR_MACHINE_KEY"The response includes domainTenantId. Use that value as the domainTenantId
in create-agent requests.
curl "https://r4.dev/api/v1/machine/agent?page=1&limit=25" \
-H "X-API-Key: YOUR_MACHINE_KEY"The response includes each agent's domainTenantId, security groups, whether the runtime public key is already registered, and optional pagination metadata when page is supplied.
POST /api/v1/machine/agent| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Agent display name |
domainTenantId | string | Yes | Domain-tenant target for the new agent |
publicKey | string | Yes | PEM-encoded RSA public key generated locally by the child runtime. Keep the matching private key local. |
securityGroupIds | string[] | Yes | Initial tenant security groups |
budgetId | string | No | Existing budget to attach |
vaultId | string | No | Optional initial vault reference |
newBudget | object | No | Inline budget creation payload |
permissions | string[] | No | Machine permission grants for the new API key |
curl -X POST "https://r4.dev/api/v1/machine/agent" \
-H "X-API-Key: YOUR_MACHINE_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Steward Agent",
"domainTenantId": "507f1f77bcf86cd799439051",
"publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqh...\n-----END PUBLIC KEY-----",
"securityGroupIds": [],
"permissions": [
"machine.agent.all",
"machine.permissions.all",
"machine.project.read"
]
}'The response returns id, name, accessKey, accessSecret, and optional vaultItemId. accessSecret is shown only once.
Save the id from this response and use it directly in later /api/v1/machine/agent/:id/tenant-roles requests. You do not need shell pipes or jq to recover it.
PATCH /api/v1/machine/agent/:idUse this route to rename the agent or replace its budget / security-group assignments.
curl -X PATCH "https://r4.dev/api/v1/machine/agent/AGENT_ID" \
-H "X-API-Key: YOUR_MACHINE_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Steward Agent v2",
"securityGroupIds": ["507f1f77bcf86cd799439061"]
}'Read current direct and inherited roles:
curl "https://r4.dev/api/v1/machine/agent/AGENT_ID/tenant-roles" \
-H "X-API-Key: YOUR_MACHINE_KEY"Replace direct roles:
curl -X PATCH "https://r4.dev/api/v1/machine/agent/AGENT_ID/tenant-roles" \
-H "X-API-Key: YOUR_MACHINE_KEY" \
-H "Content-Type: application/json" \
-d '{
"roles": ["TENANT_AGENT_MANAGER"]
}'POST /api/v1/machine/agent/:id/regenerate-api-keycurl -X POST "https://r4.dev/api/v1/machine/agent/AGENT_ID/regenerate-api-key" \
-H "X-API-Key: YOUR_MACHINE_KEY"Like agent creation, this returns a fresh one-time accessKey and accessSecret.
PATCH /api/v1/machine/agent/:id/archivecurl -X PATCH "https://r4.dev/api/v1/machine/agent/AGENT_ID/archive" \
-H "X-API-Key: YOUR_MACHINE_KEY"This route does not take a request body.
PATCH /api/v1/machine/agent/:id/vault-itemcurl -X PATCH "https://r4.dev/api/v1/machine/agent/AGENT_ID/vault-item" \
-H "X-API-Key: YOUR_MACHINE_KEY" \
-H "Content-Type: application/json" \
-d '{
"vaultItemId": "507f1f77bcf86cd799439071"
}'Creating an agent does not automatically give it project or vault access.
For delegated access: