The R4 machine API is the low-level programmatic interface behind the CLI and the Node SDK.
If your goal is to use R4 as a password manager for an agent runtime, start here:
https://r4.dev/api/v1/machineFor password retrieval, an agent runtime should:
The MCP server, Node SDK, and CLI already implement this flow for agent runtimes. Use the Platform agent wizard to create new agent credentials, then run r4 configure agent --config <path> on the runtime host when you want the CLI and SDK to share the same local profile.
If that brand-new workspace needs prepaid credit, the same AGENT runtime can now create a crypto funding intent and top up the workspace from any wallet that holds USDC on Base. The wallet does not need its own Stripe account.
Optional context-discovery endpoint:
| Endpoint | Method | Why it matters |
|---|---|---|
/me | GET | Learn the current API key scope, tenant binding, resolved policy, and write constraints before attempting other flows |
/tenant-context | GET | Compatibility helper for agent orchestration clients that need the active tenant and default domainTenantId |
Primary retrieval flow:
| Endpoint | Method | Why it matters |
|---|---|---|
/vault/sync | GET | Read the full or delta vault sync payload for continuous runtimes |
/vault | GET | List vaults the API key can access |
/search | POST | Search machine-visible vault, field-label, and eligible license metadata |
/vault/:vaultId/public-keys | GET | Fetch the signer directory used to verify wrapped DEKs and checkpoints |
/vault/:vaultId/wrapped-key | GET | Fetch the wrapped vault DEK for the authenticated agent |
/vault/:vaultId/environment-fields | GET | Fetch only fields marked for environment-variable export |
/vault/:vaultId/items | GET | List vault items plus the signed vault summary checkpoint |
/vault/:vaultId/fields/:fieldId | GET | Fetch one field ciphertext plus the parent signed detail checkpoint |
/vault/:vaultId/items/:itemId | GET | Fetch one item plus its signed detail checkpoint |
/vault/public-key | POST | Rotate or repair the runtime public key when needed |
Re-registering the same public key is safe. Rotating to a different key still requires the current private key and, when wrapped vault access already exists, a full replacement rewrappedVaultKeys batch.
For the common runtime workflow "give me the environment variables for this project", use the CLI or SDK:
r4 project env PROJECT_IDconst r4 = await R4.create({
profile: 'openclaw-agent',
projectId: 'PROJECT_ID',
})
console.log(JSON.stringify(r4.env))The returned JSON is assembled locally from fields marked
isEnvironmentVariable. The machine API does not expose a plaintext env-var
endpoint. Current clients first try the consolidated bundle route
GET /project/:id/environment, which returns the project's vaults with their
wrapped keys, signer directories, and encrypted environment fields in one
response. Where that route is unavailable, clients fall back to
GET /vault?projectId=PROJECT_ID plus per-vault wrapped-key, signer-directory,
and GET /vault/:vaultId/environment-fields reads (or list-items and
item-detail reads on the oldest servers). Either way, decryption happens
locally in the runtime.
The same pattern exists for managed licenses:
GET /licenses/:licenseInstanceId/environment returns the zero-trust bundle
for the vault items linked to a provisioned license. The CLI exposes it as
r4 licenses env LICENSE_INSTANCE_ID [command...], and the SDK as
R4.create({ licenseInstanceId }). Both bundle routes require
machine.vault.secret.read.
Optional project discovery endpoints:
| Endpoint | Method | Description |
|---|---|---|
/project | GET | List projects |
/project/:id | GET | Get project detail, including associated vaults |
/project/:id/environment | GET | Zero-trust env bundle for the project's vaults |
When a machine caller creates projects through POST /project, ORG-scoped keys and tenants with multiple domain bindings should pass domainTenantId explicitly so the project lands under the intended domain tenant.
The machine API now includes a provider-neutral prepaid crypto top-up flow for workspace credit.
Routes:
POST /billing/crypto-funding-intentsGET /billing/crypto-funding-intentsGET /billing/crypto-funding-intents/:idWhat happens:
USDC / Base deposit instructions plus an expiryThis keeps the agent-facing contract wallet-only and provider-neutral even though the v1 backend adapter uses Stripe deposit mode.
When a headless runtime needs to answer "who am I?" first, call:
curl https://r4.dev/api/v1/machine/me -H "X-API-Key: YOUR_MACHINE_KEY"The response includes:
apiKey or accessTokenagent or accountThis is the recommended first call for automation that needs to understand its current tenant context, policy limits, or available write paths.
Vault metadata such as vault names, item names, field labels, and websites is not end-to-end encrypted.
That metadata is protected by encryption in transit and at rest. Read responses can include signed summary/detail checkpoints so zero-trust runtimes can verify metadata snapshots. Only field values, such as encryptedValue on creates and value on reads/updates, are end-to-end encrypted v3 vault envelopes.
AGENT runtimes can do more than read secrets when they also receive:
TENANT_AGENT_MANAGERmachine.agent.all and machine.permissions.allWith that combination, an agent can:
The most practical delegated-orchestration flow is:
GET /agent to reuse an existing domainTenantIdPOST /agent to create a subordinate runtimePATCH /agent/:id/tenant-roles to grant direct tenant roles such as TENANT_AGENT_MANAGERPOST /permissions/PROJECT/:id/set-permissions to delegate project accessThis is intentionally separate from vault and vault-item write permissions. Attachment management, procurement, and outbound machine webhooks now exist on the same headless machine surface, but they still require their own endpoint permissions and, in some cases, additional tenant or org roles.
If the CLI, Node SDK, MCP server, or current raw machine API is missing a capability the agent needs, submit product feedback through:
POST /feedbackThis endpoint is AGENT-only. It stores the feedback, forwards it to the internal feedback inbox, and is intended specifically for "I tried to do X, but R4 does not support it yet" reports.
Do not include secret values, plaintext credentials, or private user data in the feedback body.
Machine API requests accept either an API key or a CLI device access token. For the agent password-manager flow, the runtime also needs its local private key.
X-API-Key: {accessKey}.{secret}Authorization: ApiKey {accessKey}.{secret}Authorization: Bearer <token> with x-r4-session-surface: cli and x-r4-device-installation-idSee Authentication and Keys for the full setup.
Every API-key machine request must pass two checks:
AGENT, USER, TENANT, or ORG)Account access-token requests are user-backed and receive the machine permissions allowed for USER-backed callers, excluding the access-management write families (machine.org_admin.write, machine.tenant_admin.write, machine.user_manager.write, machine.permissions.write). They are useful for personal CLI/SDK automation, but they do not grant AGENT-only capabilities such as machine.agent.public_key.write or machine.feedback.write; admin-write automation needs a scoped API key with an explicit policy. Keys that predate machine policies resolve to their scope's safe default bundle instead of full access — rotate them to pin an explicit policy.
When you create a key, you can choose grouped grants or individual permissions.
| Grant | What it covers |
|---|---|
machine.all | All machine endpoints allowed for that key's scope |
machine.vault.all | Vault metadata reads, secret reads, sync reads, and allowed vault writes |
machine.agent.all | Agent lifecycle reads/writes plus tenant-role assignment endpoints |
machine.feedback.all | AGENT feedback submission for unsupported product capabilities |
machine.search.all | Machine metadata-search endpoints |
machine.project.all | Project read + write endpoints |
machine.permissions.all | Project/vault permission reads + writes |
machine.domain.all | Domain registration, verification, and DNS endpoints |
machine.billing.all | Billing read + write endpoints |
machine.monitoring.all | Scoped monitoring reads plus the global-admin-only infrastructure health endpoints |
machine.wrapped_key.all | Wrapped-key list/store/delete/rekey endpoints |
machine.user_key_pair.all | User-key-pair directory, vault, backup, and revoke endpoints |
machine.integration.all | Integration catalog, instances, auth URLs, and integration requests |
machine.intelligence_provider.all | Intelligence-provider metadata, token-provider runtime bundles, and managed usage endpoints |
machine.user_manager.all | Tenant-user listing, invitations, membership, and role updates |
machine.tenant_admin.all | Tenant API keys, security groups, and tenant-admin management |
machine.org_admin.all | Org tenants, org users, org settings, and org API keys |
machine.license.all | License purchase, vault-handoff, purchase-resume, termination, termination-status, termination-resume, and license-list endpoints |
machine.contract.all | Contract detail, assets, creation, and update flows |
machine.order.all | Order review and approval endpoints |
For an AGENT runtime, the fastest setup is machine.all. A tighter AGENT policy usually includes machine.agent.all, machine.vault.read, machine.vault.secret.read, machine.vault.sync.read, and optionally machine.search.read, machine.project.read, machine.permissions.all, machine.monitoring.read, or machine.feedback.write when the runtime should be able to report unsupported product gaps on its own.
Fine-grained identity discovery uses the atomic permission machine.me.read.
Monitoring routes intentionally split by sensitivity:
GET /monitoring/metric-stats and GET /monitoring/entity-counts are filtered to what the current machine session can already accessGET /monitoring/system-stats and GET /monitoring/session-stats require a global-admin-backed machine key in addition to the monitoring permissionR4 supports multiple API-key scopes, but the password-manager path described on this website is specifically for AGENT runtimes.
Important current constraint:
/attachments/:vaultId/*/licenses/* and /webhook/*See Current Limitations for the exact wording to use.
All machine API errors use a JSON error envelope:
{
"error": {
"code": "error_code",
"message": "Human-readable error message"
}
}Common machine API errors:
| Code | HTTP Status | Meaning |
|---|---|---|
missing_machine_auth | 401 | Missing API key or bearer token |
unauthorized | 401 | Invalid or expired machine credentials |
machine_permission_denied | 403 | The credentials are valid, but do not include the endpoint permission |
forbidden | 403 | Valid key, but the key or scope lacks access |
not_found | 404 | Requested vault, item, project, or domain was not found |
rate_limit_exceeded | 429 | Too many requests |
The machine API also includes:
GET /licenses/:licenseInstanceId/environmentManaged token-provider wrappers now live on the machine surface too: the runtime can fetch a provider-scoped zero-trust bundle, decrypt the secret locally, preflight budget state with R4, call the vendor directly, and then report finalized usage back to R4.
Those capabilities are real, but they are secondary to the agent password-manager flow this site now emphasizes.