> ## Documentation Index
> Fetch the complete documentation index at: https://docs.airctrl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK example catalog

> TypeScript examples for every public AirctrlClient method.

The snippets use an initialized `airctrl` client and IDs loaded from your application configuration. Methods return the API's typed snake\_case data unless noted otherwise.

## Prepare the examples

The catalog uses these shared values. Validate required environment variables when the process starts;
do not let `undefined` reach a credential or resource field.

```ts theme={}
import { AirctrlError, createClient } from '@airctrl/sdk'

function required(name: string): string {
  const value = process.env[name]
  if (!value) throw new Error(`Missing ${name}`)
  return value
}

const airctrl = createClient({
  baseUrl: required('AIRCTRL_API_URL'),
  auth: required('AIRCTRL_TOKEN'),
})

const accountId = required('AIRCTRL_ACCOUNT_ID')
const projectId = required('AIRCTRL_PROJECT_ID')
const recordId = required('AIRCTRL_RECORD_ID')
const gatewayId = required('AIRCTRL_GATEWAY_ID')
const vaultPassword = required('AIRCTRL_VAULT_PASSPHRASE')
```

Other names such as `credentialId`, `tokenId`, `userId` and `groupId` are IDs returned by earlier reads
or creates. Values such as `sourcePassword` and `replacementPassword` must come from a trusted local
source. Never replace them with a literal production secret in source code.

Each section shows the smallest useful call. [SDK methods](/sdk/methods) contains the full signature,
identity boundary, input rules, result rules and common error handling.

## Accounts and projects

### List accessible accounts

<div className="section-help">
  Returns accounts available to the human PAT.
</div>

```ts theme={}
const accounts = await airctrl.listAccounts()
```

<div className="technical-reference">
  **SDK method:** `listAccounts()`
</div>

### List projects

```ts theme={}
const projects = await airctrl.listProjects({ accountId, includeArchived: false })
```

<div className="technical-reference">
  **SDK method:** `listProjects()`
</div>

### View a project

```ts theme={}
const project = await airctrl.getProject(projectId, { accountId })
if (!project) throw new Error('Project not found')
```

<div className="technical-reference">
  **SDK method:** `getProject()`
</div>

### Create a project

<div className="section-help">
  The result contains `project_id`.
</div>

```ts theme={}
const project = await airctrl.createProject({ accountId, name: 'Payments', description: 'Payment service credentials' })
```

<div className="technical-reference">
  **SDK method:** `createProject()`
</div>

### Update a project

<div className="section-help">
  This replaces the editable project values.
</div>

```ts theme={}
await airctrl.updateProject(projectId, { name: 'Payments production', description: 'Production credentials', isActive: true }, { accountId })
```

<div className="technical-reference">
  **SDK method:** `updateProject()`
</div>

### Archive or restore a project

<div className="section-help">
  The first call archives; the second restores.
</div>

```ts theme={}
await airctrl.setProjectArchiveState(projectId, true, { accountId })
await airctrl.setProjectArchiveState(projectId, false, { accountId })
```

<div className="technical-reference">
  **SDK method:** `setProjectArchiveState()`
</div>

## Record reading and creation

### List accessible record metadata

<div className="section-help">
  Returns safe metadata across accessible scope.
</div>

```ts theme={}
const page = await airctrl.listRecords({ accountId, includeArchived: false, limit: 50, offset: 0 })
```

<div className="technical-reference">
  **SDK method:** `listRecords()`
</div>

### List records in one project

```ts theme={}
const records = await airctrl.listProjectRecords(projectId, { includeArchived: false, limit: 50, offset: 0 })
```

<div className="technical-reference">
  **SDK method:** `listProjectRecords()`
</div>

### Read a complete record

<div className="section-help">
  `secret.fields` contains locally decrypted fields. Do not log it.
</div>

```ts theme={}
const secret = await airctrl.getSecret({ recordId, vaultPassword: process.env.AIRCTRL_VAULT_PASSPHRASE, audit: true })
```

<div className="technical-reference">
  **SDK method:** `getSecret()`
</div>

### Read selected record fields

<div className="section-help">
  Returns only the requested sections.
</div>

```ts theme={}
const selected = await airctrl.readRecord({ recordId, scope: ['username', 'password'], environment: 'production', vaultPassword })
```

<div className="technical-reference">
  **SDK method:** `readRecord()`
</div>

### Load all project records

<div className="section-help">
  Use this only when the process needs every accessible project record.
</div>

```ts theme={}
const secrets = await airctrl.getAll({ projectId, vaultPassword, audit: true })
```

<div className="technical-reference">
  **SDK method:** `getAll()`
</div>

### Create an encrypted record

<div className="section-help">
  Returns `{ recordId }`.
</div>

```ts theme={}
const created = await airctrl.createSecret({ projectId, name: 'Database login', secretFormat: 'password', fieldValues: { username: 'app_user', password: sourcePassword }, tags: ['production'], vaultPassword })
```

<div className="technical-reference">
  **SDK method:** `createSecret()`
</div>

### Create a generated record

<div className="section-help">
  Generation and encryption happen locally.
</div>

```ts theme={}
const created = await airctrl.createGeneratedRecord({ projectId, name: 'Generated database password', secretFormat: 'password', options: { length: 32 }, extraFields: { username: 'app_user' }, vaultPassword })
```

<div className="technical-reference">
  **SDK method:** `createGeneratedRecord()`
</div>

### Create or replace record fields

<div className="section-help">
  Returns `updated: true` for an existing record. Human mode can also upsert by `projectId`, `name` and `secretFormat`.
</div>

```ts theme={}
const result = await airctrl.setSecret({ recordId, fieldValues: { username: 'app_user', password: replacementPassword }, changedFields: ['password'], vaultPassword })
```

<div className="technical-reference">
  **SDK method:** `setSecret()`
</div>

## Record lifecycle and sharing

### Update record details

```ts theme={}
await airctrl.updateRecordMetadata(recordId, { tags: ['payments', 'production'], secretDueAt: '2026-12-01T00:00:00Z', rotationIntervalDays: 90 })
```

<div className="technical-reference">
  **SDK method:** `updateRecordMetadata()`
</div>

### Archive or restore a record

<div className="section-help">
  Pass `false` to restore.
</div>

```ts theme={}
await airctrl.setRecordArchiveState(recordId, true)
```

<div className="technical-reference">
  **SDK method:** `setRecordArchiveState()`
</div>

### Transfer record ownership

<div className="section-help">
  Confirm both IDs before transferring.
</div>

```ts theme={}
await airctrl.transferRecordOwnership(recordId, newOwnerUserId)
```

<div className="technical-reference">
  **SDK method:** `transferRecordOwnership()`
</div>

### View record version history

```ts theme={}
const versions = await airctrl.getRecordVersions(recordId)
```

<div className="technical-reference">
  **SDK method:** `getRecordVersions()`
</div>

### Review one record's audit history

```ts theme={}
const events = await airctrl.getRecordAudit(recordId, 25)
```

<div className="technical-reference">
  **SDK method:** `getRecordAudit()`
</div>

### Restore a previous record version

<div className="section-help">
  The selected version becomes a new current version.
</div>

```ts theme={}
await airctrl.rollbackRecordToVersion(recordId, targetVersionId)
```

<div className="technical-reference">
  **SDK method:** `rollbackRecordToVersion()`
</div>

### Rotate a record

<div className="section-help">
  The SDK rotates the record data key and ciphertext locally.
</div>

```ts theme={}
await airctrl.rotateRecord({ recordId, vaultPassword })
```

<div className="technical-reference">
  **SDK method:** `rotateRecord()`
</div>

### Share a record with a user

```ts theme={}
await airctrl.shareRecordWithUser({ recordId, granteeUserId: userId, permission: 'read', vaultPassword })
```

<div className="technical-reference">
  **SDK method:** `shareRecordWithUser()`
</div>

### Share a record with a Service Account

```ts theme={}
await airctrl.shareRecordWithServiceAccount({ accountId, recordId, serviceAccountId, vaultPassword })
```

<div className="technical-reference">
  **SDK method:** `shareRecordWithServiceAccount()`
</div>

### Share a record with a group

```ts theme={}
await airctrl.shareRecordWithGroup({ recordId, groupId, vaultPassword })
```

<div className="technical-reference">
  **SDK method:** `shareRecordWithGroup()`
</div>

### Remove a user's record access

```ts theme={}
await airctrl.revokeRecordFromUser(recordId, userId)
```

<div className="technical-reference">
  **SDK method:** `revokeRecordFromUser()`
</div>

### Remove a Service Account's record access

```ts theme={}
await airctrl.revokeRecordFromServiceAccount(recordId, serviceAccountId)
```

<div className="technical-reference">
  **SDK method:** `revokeRecordFromServiceAccount()`
</div>

### Remove a group's record access

<div className="section-help">
  Each revoke removes only the selected grant.
</div>

```ts theme={}
await airctrl.revokeRecordFromGroup(recordId, groupId)
```

<div className="technical-reference">
  **SDK method:** `revokeRecordFromGroup()`
</div>

## Record audit feeds

### Find unusual record activity

```ts theme={}
const anomalies = await airctrl.listRecordAnomalies({ accountId, scopeType: 'project', scopeId: projectId })
```

<div className="technical-reference">
  **SDK method:** `listRecordAnomalies()`
</div>

### Review daily record activity

<div className="section-help">
  The day uses UTC `YYYY-MM-DD`.
</div>

```ts theme={}
const activity = await airctrl.listRecordActivity('2026-09-10', { accountId, scopeType: 'project', scopeId: projectId })
```

<div className="technical-reference">
  **SDK method:** `listRecordActivity()`
</div>

### Review record alerts

```ts theme={}
const alerts = await airctrl.listRecordAlerts({ accountId, scopeType: 'project', scopeId: projectId, limit: 25, offset: 0 })
```

<div className="technical-reference">
  **SDK method:** `listRecordAlerts()`
</div>

### Review secret access events

```ts theme={}
const access = await airctrl.listRecordAccess({ accountId, scopeType: 'project', scopeId: projectId, actions: ['record.secret_access'], limit: 25, offset: 0 })
```

<div className="technical-reference">
  **SDK method:** `listRecordAccess()`
</div>

## Providers and gateways

### List supported AI providers

```ts theme={}
const providers = await airctrl.listProviders()
```

<div className="technical-reference">
  **SDK method:** `listProviders()`
</div>

### List provider credentials

<div className="section-help">
  The result contains metadata, never provider secret values.
</div>

```ts theme={}
const credentials = await airctrl.listProviderCredentials(accountId)
```

<div className="technical-reference">
  **SDK method:** `listProviderCredentials()`
</div>

### Add a provider credential

```ts theme={}
const credential = await airctrl.createProviderCredential({ accountId, providerId, label: 'Production OpenAI', apiKey: process.env.OPENAI_PRODUCTION_KEY!, credentialKind: 'api_key' })
```

<div className="technical-reference">
  **SDK method:** `createProviderCredential()`
</div>

### List models for a credential

Each result includes the provider capabilities, the subset AIRCTRL supports, and `airctrlSupport` as `supported`, `partial`, or `unsupported`. Unsupported entries remain visible for discovery but cannot be bound to a gateway.

```ts theme={}
const models = await airctrl.listProviderCredentialModels(credentialId, { accountId })
```

<div className="technical-reference">
  **SDK method:** `listProviderCredentialModels()`
</div>

### Replace a provider key

```ts theme={}
await airctrl.rotateProviderCredential(credentialId, process.env.OPENAI_REPLACEMENT_KEY!, { accountId })
```

<div className="technical-reference">
  **SDK method:** `rotateProviderCredential()`
</div>

### Rename a provider credential

```ts theme={}
await airctrl.updateProviderCredentialLabel(credentialId, 'Primary OpenAI', { accountId })
```

<div className="technical-reference">
  **SDK method:** `updateProviderCredentialLabel()`
</div>

### Revoke a provider credential

<div className="section-help">
  Check dependent gateways before revocation.
</div>

```ts theme={}
await airctrl.revokeProviderCredential(credentialId, { accountId })
```

<div className="technical-reference">
  **SDK method:** `revokeProviderCredential()`
</div>

### List gateways

```ts theme={}
const gateways = await airctrl.listGateways(projectId)
```

<div className="technical-reference">
  **SDK method:** `listGateways()`
</div>

### View a gateway

```ts theme={}
const gateway = await airctrl.getGateway(gatewayId)
```

<div className="technical-reference">
  **SDK method:** `getGateway()`
</div>

### Create a gateway

```ts theme={}
const gateway = await airctrl.createGateway({
  accountId,
  projectId,
  name: 'Payments AI',
  defaultProviderId: providerId,
  defaultModel: 'gpt-5',
  credentialBindings: [{ credentialId, modelId: 'gpt-5' }],
})
```

<div className="technical-reference">
  **SDK method:** `createGateway()`
</div>

### Update a gateway

```ts theme={}
await airctrl.updateGateway(gatewayId, { name: 'Payments AI production', defaultModel: 'gpt-5', isActive: true }, { accountId })
```

<div className="technical-reference">
  **SDK method:** `updateGateway()`
</div>

### Delete a gateway

<div className="section-help">
  Deletion disables the gateway and revokes its tokens.
</div>

```ts theme={}
await airctrl.deleteGateway(gatewayId, { accountId })
```

<div className="technical-reference">
  **SDK method:** `deleteGateway()`
</div>

### Attach a provider credential

```ts theme={}
await airctrl.attachGatewayCredential(gatewayId, credentialId, 'gpt-5', { accountId })
```

<div className="technical-reference">
  **SDK method:** `attachGatewayCredential()`
</div>

### Detach a provider credential

<div className="section-help">
  Detach does not revoke the provider credential.
</div>

```ts theme={}
await airctrl.detachGatewayCredential(gatewayId, credentialId, { accountId })
```

<div className="technical-reference">
  **SDK method:** `detachGatewayCredential()`
</div>

### Change gateway limits and behavior

```ts theme={}
await airctrl.updateGatewaySettings(gatewayId, { spendLimit: 100, spendWindow: 'monthly', rateLimitPerMin: 120, loggingEnabled: true, logBodies: false, guardrailMode: 'flag', cacheEnabled: true, cacheTtlSeconds: 300 }, { accountId })
```

<div className="technical-reference">
  **SDK method:** `updateGatewaySettings()`
</div>

## Gateway tokens

### List gateway tokens

```ts theme={}
const tokens = await airctrl.listGatewayTokens(gatewayId)
```

<div className="technical-reference">
  **SDK method:** `listGatewayTokens()`
</div>

### Create a gateway token

<div className="section-help">
  The plaintext appears only in this result.
</div>

```ts theme={}
const token = await airctrl.createGatewayToken(gatewayId, { name: 'Local development', scopes: ['run', 'read_logs'], expiresInDays: 30, allowedModels: ['gpt-5'], rateLimitPerMin: 60 }, { accountId })
await approvedCustody.write(token.plaintext)
```

<div className="technical-reference">
  **SDK method:** `createGatewayToken()`
</div>

### Rename a gateway token

```ts theme={}
await airctrl.renameGatewayToken(gatewayId, tokenId, 'CI production', { accountId })
```

<div className="technical-reference">
  **SDK method:** `renameGatewayToken()`
</div>

### Revoke a gateway token

```ts theme={}
await airctrl.revokeGatewayToken(gatewayId, tokenId, { accountId })
```

<div className="technical-reference">
  **SDK method:** `revokeGatewayToken()`
</div>

### Delete a gateway token

```ts theme={}
await airctrl.deleteGatewayToken(gatewayId, tokenId, { accountId })
```

<div className="technical-reference">
  **SDK method:** `deleteGatewayToken()`
</div>

## Usage and observability

### Review gateway requests

```ts theme={}
const logs = await airctrl.listGatewayLogs(gatewayId, { since: '2026-09-01T00:00:00Z', status: 500, limit: 50, offset: 0 })
```

<div className="technical-reference">
  **SDK method:** `listGatewayLogs()`
</div>

### Inspect one gateway request

<div className="section-help">
  This may contain stored request and response bodies.
</div>

```ts theme={}
const detail = await airctrl.getGatewayLogDetail(gatewayId, logId)
```

<div className="technical-reference">
  **SDK method:** `getGatewayLogDetail()`
</div>

### Review provider-key access

```ts theme={}
const access = await airctrl.listGatewayKeyAccess(gatewayId, { outcome: 'denied', since: '2026-09-01T00:00:00Z', limit: 50, offset: 0 })
```

<div className="technical-reference">
  **SDK method:** `listGatewayKeyAccess()`
</div>

### Review project usage logs

```ts theme={}
const logs = await airctrl.listUsageLogs({ projectId, gatewayId, since: '2026-09-01T00:00:00Z', limit: 50, offset: 0 })
```

<div className="technical-reference">
  **SDK method:** `listUsageLogs()`
</div>

### Inspect one project usage log

```ts theme={}
const detail = await airctrl.getUsageLogDetail(projectId, logId)
```

<div className="technical-reference">
  **SDK method:** `getUsageLogDetail()`
</div>

### Review project spend

```ts theme={}
const spend = await airctrl.getUsageSpend(projectId)
```

<div className="technical-reference">
  **SDK method:** `getUsageSpend()`
</div>

### Review project usage metrics

```ts theme={}
const metrics = await airctrl.getUsageMetrics(projectId, { since: '2026-09-01T00:00:00Z', bucket: 'day' })
```

<div className="technical-reference">
  **SDK method:** `getUsageMetrics()`
</div>

### View OpenTelemetry settings

<div className="section-help">
  Stored header values are never returned.
</div>

```ts theme={}
const otel = await airctrl.getGatewayOtelExport(gatewayId, { accountId })
```

<div className="technical-reference">
  **SDK method:** `getGatewayOtelExport()`
</div>

### Change OpenTelemetry settings

```ts theme={}
const otelHeaders = JSON.parse(process.env.OTEL_EXPORT_HEADERS_JSON!) as Record<string, string>
await airctrl.updateGatewayOtelExport(gatewayId, { enabled: true, endpoint: 'https://otel.example.com/v1/traces', exportMetrics: true, exportTraces: true, headers: otelHeaders }, { accountId })
```

<div className="technical-reference">
  **SDK method:** `updateGatewayOtelExport()`
</div>

## Service Account metadata

### List Service Accounts

```ts theme={}
const serviceAccounts = await airctrl.listServiceAccounts({ accountId })
```

<div className="technical-reference">
  **SDK method:** `listServiceAccounts()`
</div>

### View a Service Account

<div className="section-help">
  These methods expose safe metadata to a human PAT. Service Account lifecycle remains dashboard-only.
</div>

```ts theme={}
const serviceAccount = await airctrl.getServiceAccount(serviceAccountId, { accountId })
if (!serviceAccount) throw new Error('Service Account not found')
```

<div className="technical-reference">
  **SDK method:** `getServiceAccount()`
</div>

## Error handling

Every API-backed method throws `AirctrlError`. Read `status`, `code`, `message` and `details`. Do not retry validation, permission or missing-resource failures unchanged. Reuse the same idempotency key only for the same intended write.
