Use the official Node SDK when your agent runtime already runs in Node.js or TypeScript.
npm install @r4-sdk/sdkRequires Node.js 18 or newer.
import R4 from '@r4-sdk/sdk'
const r4 = await R4.create({
apiKey: process.env.R4_API_KEY!,
privateKeyPath: './agent-private-key.pem',
})
console.log(r4.env.GITHUB_PRODUCTION_TOKEN)| Option | Required | Description |
|---|---|---|
apiKey | Yes | AGENT API key in {accessKey}.{secret} format |
privateKey | No | PEM-encoded RSA private key kept locally by the runtime |
privateKeyPath | No | Path to the PEM-encoded RSA private key |
projectId | No | Optional project filter |
trustStorePath | No | Optional path to the local trust-store JSON |
baseUrl | No | API base URL, defaults to https://r4.dev |
Provide either privateKey or privateKeyPath.
Create the agent first, then let the runtime complete this setup before operators add the agent to security groups, projects, or direct vault shares. The first public-key registration is what makes wrapped vault keys possible for that runtime.
R4.create() DoesR4.create() is the canonical runtime entry point.
It:
POST /api/v1/machine/vault/public-keyIf R4.create() fails because no wrapped key exists for a vault, check the onboarding order first: the runtime key must be registered before the operator grants the access path that leads to that vault.
const r4 = await R4.create({
apiKey: process.env.R4_API_KEY!,
privateKeyPath: './agent-private-key.pem',
})
const dbPassword = r4.env.PRIMARY_DATABASE_PASSWORDUse refresh() when the runtime is long-lived and needs the latest shared values:
await r4.refresh()Choose the SDK when the runtime:
Choose the CLI when shell commands and scripts are the main integration surface.
If you need a machine endpoint that does not have a dedicated SDK helper yet, use the low-level bridge:
const result = await r4.requestMachine({
method: 'GET',
path: '/webhook',
})You can also use new R4Client(apiKey, baseUrl).requestMachine(...) when you
want authenticated machine access without booting the full zero-trust decrypt
flow.
If the SDK is missing a capability you need and the current CLI, MCP server, or raw machine API also does not cover it, submit product-gap feedback through POST /api/v1/machine/feedback with an AGENT API key. Do not include secrets or private user data in that payload.
The SDK now also supports budget-aware token-provider helpers without giving R4 the plaintext vendor secret.
const provider = await r4.getTokenProviderFields('TOKEN_PROVIDER_ID', {
unsafeExport: true,
})
console.log(provider.providerType)
console.log(provider.fields['API Key'])const result = await r4.callAnthropicWithTokenProvider({
tokenProviderId: 'TOKEN_PROVIDER_ID',
body: {
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Summarize the latest runbook changes.' }],
},
})
console.log(result.response)
console.log(result.usage.actualCostUsd)That path: