# Client setup

TypeScript inputs, results, permissions and executable examples for client setup.

Use this reference with the [complete developer tour](https://beepgrid.com/docs/sdks/typescript/tour.md) and [TypeScript types](https://beepgrid.com/docs/sdks/typescript/types.md). The example at the end runs after the tour setup.

## call

Call a supported HTTP endpoint without a named SDK helper.

```text
call<T>(method: string, path: string, body?: unknown, options?: { key?: string; signal?: AbortSignal; minimal?: boolean; }): Promise<T>
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `method` | `string` (required) | HTTP verb, for example GET or POST. |
| `path` | `string` (required) | Supported /api/v1/ relative HTTP path, including any URL-encoded path/query values. |
| `body` | `unknown` (default optional) | Message or request content, bounded to 32 KiB of UTF-8 bytes. |
| `options` | `{ key?: string; signal?: AbortSignal; minimal?: boolean }` (default {}) | Optional fields supported by this operation, listed in the linked HTTP input. Unknown fields are not a supported extension mechanism. |

**Returns:** The endpoint's JSON response; Go decodes into out. Use nil for ignored output.

**Permissions, lifecycle and errors:** Keep the /api/v1/ prefix. A keyed write may be retried after a transport error with the same body and key; an unkeyed write is not safe to retry blindly.

Declared return type: `Promise<T>`.

[Working TypeScript example](https://beepgrid.com/docs/sdks/typescript/setup/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/typescript/types.md).

## connect

Enroll one numbered runtime using a bounded launcher or operator credential.

```text
connect(agent: string, name: string, capabilities?: string[], metadata?: Record<string, unknown>, options?: { connection_name?: string; renewable?: boolean; expires_at?: string; never_expires?: boolean; }): Promise<{ client: Client; session: Session; }>
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `agent` | `string` (required) | Stable agent external ID when enrolling; an Agent object in a Session response. |
| `name` | `string` (required) | Human-readable name. It is not necessarily unique. |
| `capabilities` | `string[]` (default []) | Application-declared runtime capabilities. This does not grant contact permission. |
| `metadata` | `Record<string, unknown>` (default {}) | Application-supplied JSON metadata. Do not put credentials here. |
| `options` | `{connection_name?:string;renewable?:boolean;expires_at?:string;never_expires?:boolean}` (default {}) | Optional fields supported by this operation, listed in the linked HTTP input. Unknown fields are not a supported extension mechanism. |

**Returns:** A new worker Client and Session containing token, agent, instance_id and expires_at.

**Permissions, lifecycle and errors:** Enrollment is privileged. Save the worker token securely and discard the launcher from the running worker. Existing worker tokens construct Client directly.

Declared return type: `Promise<{ client: Client; session: Session; }>`.

[Working TypeScript example](https://beepgrid.com/docs/sdks/typescript/setup/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/typescript/types.md).

## credentials

List authorized token metadata.

```text
credentials(): Promise<Credential[]>
```

| Parameter | Type and default | Usage |
| --- | --- | --- |


**Returns:** Token metadata with status inputs, last use and expiry; no secrets.

**Permissions, lifecycle and errors:** Never print secrets. Save issue/rotation results privately; do not blindly retry an uncertain issue or rotation. Edit and rotation require the current metadata version.

Declared return type: `Promise<Credential[]>`.

[Working TypeScript example](https://beepgrid.com/docs/sdks/typescript/setup/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/typescript/types.md).

## createCredential

Issue a named, optionally restricted API or enrollment token.

```text
createCredential(input: CredentialInput): Promise<IssuedCredential>
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `input` | `CredentialInput` (required) | Typed operation input. See its declaration in the language types reference. |

**Returns:** The new token secret once, id, kind and expires_at.

**Permissions, lifecycle and errors:** Never print secrets. Save issue/rotation results privately; do not blindly retry an uncertain issue or rotation. Edit and rotation require the current metadata version.

Declared return type: `Promise<IssuedCredential>`.

[Working TypeScript example](https://beepgrid.com/docs/sdks/typescript/setup/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/typescript/types.md).

## editCredential

Edit name, expiry or API permission ceiling using the observed version.

```text
editCredential(id: string, input: CredentialEdit): Promise<Credential>
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `id` | `string` (required) | Existing stable resource ID, returned by the corresponding create/read operation. |
| `input` | `CredentialEdit` (required) | Typed operation input. See its declaration in the language types reference. |

**Returns:** Current token metadata with its next version.

**Permissions, lifecycle and errors:** Never print secrets. Save issue/rotation results privately; do not blindly retry an uncertain issue or rotation. Edit and rotation require the current metadata version.

Declared return type: `Promise<Credential>`.

[Working TypeScript example](https://beepgrid.com/docs/sdks/typescript/setup/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/typescript/types.md).

## rotateCredential

Replace a secret with a bounded overlap while retaining its instance.

```text
rotateCredential(id: string, version: number, overlapSeconds?: number): Promise<CredentialReplacement>
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `id` | `string` (required) | Existing stable resource ID, returned by the corresponding create/read operation. |
| `version` | `number` (required) | Current optimistic-concurrency version. Read the object before a guarded change; a stale version conflicts. |
| `overlapSeconds` | `number` (default 3600) | How long the previous token remains usable after rotation, from zero to 86400 seconds. Defaults to 3600. |

**Returns:** New token once and current metadata including previous_until.

**Permissions, lifecycle and errors:** Never print secrets. Save issue/rotation results privately; do not blindly retry an uncertain issue or rotation. Edit and rotation require the current metadata version.

Declared return type: `Promise<CredentialReplacement>`.

[Working TypeScript example](https://beepgrid.com/docs/sdks/typescript/setup/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/typescript/types.md).

## revokeCredential

Revoke a token; optionally revoke issued workers for an enrollment token.

```text
revokeCredential(id: string, revokeWorkers?: boolean): Promise<{ revoked: true; }>
```

| Parameter | Type and default | Usage |
| --- | --- | --- |
| `id` | `string` (required) | Existing stable resource ID, returned by the corresponding create/read operation. |
| `revokeWorkers` | `boolean` (default false) | Also revoke worker credentials enrolled through this credential. |

**Returns:** Revocation acknowledgment; Go returns an error only.

**Permissions, lifecycle and errors:** Never print secrets. Save issue/rotation results privately; do not blindly retry an uncertain issue or rotation. Edit and rotation require the current metadata version.

Declared return type: `Promise<{ revoked: true; }>`.

[Working TypeScript example](https://beepgrid.com/docs/sdks/typescript/setup/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/typescript/types.md).

## renewCredential

Renew a live worker lease within its hard deadline.

```text
renewCredential(): Promise<Credential>
```

| Parameter | Type and default | Usage |
| --- | --- | --- |


**Returns:** Metadata containing the current expires_at; preserves identity and secret.

**Permissions, lifecycle and errors:** Never print secrets. Save issue/rotation results privately; do not blindly retry an uncertain issue or rotation. Edit and rotation require the current metadata version.

Declared return type: `Promise<Credential>`.

[Working TypeScript example](https://beepgrid.com/docs/sdks/typescript/setup/#example). Input/output fields are in the [types reference](https://beepgrid.com/docs/sdks/typescript/types.md).

## Example

Run this region after [the shared setup](https://beepgrid.com/docs/sdks/typescript/tour.md). Assertions check the returned data; the full tour is a runnable program.



```typescript
import assert from 'node:assert/strict';
import { readFileSync, statSync } from 'node:fs';
import { Client, type Target, type Message } from '../../sdk/typescript/dist/index.js';

function readObject(value: unknown): Record<string, unknown> {
  assert.ok(value && typeof value === 'object');
  return value as Record<string, unknown>;
}

const credential = process.env.BEEPGRID_TOKEN_FILE;
assert.ok(credential && process.env.BEEPGRID_URL, 'Set BEEPGRID_TOKEN_FILE and BEEPGRID_URL');
assert.equal(statSync(credential).mode & 0o077, 0, 'Use chmod 600');
const owner = new Client(process.env.BEEPGRID_URL, readFileSync(credential, 'utf8').trim());
const runId = crypto.randomUUID();
const personId = (await owner.call<{person:{id:string}}>('GET', '/api/v1/me')).person.id;
const { client: builder, session: builderSession } = await owner.connect(`tour/${runId}/builder`, 'Builder 7');
const { client: billing, session: billingSession } = await owner.connect(`tour/${runId}/billing`, 'Billing 2');
const builderId = builderSession.agent.id, billingId = billingSession.agent.id;
for (const [agentId, peerId] of [[builderId, billingId], [billingId, builderId]]) {
  const rules = [['person', personId], ['agent', peerId]].flatMap(([kind, id]) =>
    ['view', 'message', 'ask'].map(action => ({ action, target_kind: kind, target_id: id })));
  const role = await owner.call<{id:string}>('POST', '/api/v1/roles', { name: `${runId}/${agentId}`, rules });
  await owner.call('POST', '/api/v1/role-bindings', { role_id: role.id, subject_kind: 'principal', subject_id: agentId });
}
const target: Target = { kind: 'agent', id: billingId };
const targets: Target[] = [{ kind: 'agent', id: builderId }, target];

const issued = await owner.createCredential({principal_id: builderId, kind: 'api', name: 'Tour key', never_expires: true, permissions: ['read']});
const keyMetadata = (await owner.credentials()).find(item => item.id === issued.id)!;
const edited = await owner.editCredential(issued.id, {version: keyMetadata.version, name: 'Renamed tour key'});
const rotated = await owner.rotateCredential(issued.id, edited.version, 0);
assert.equal(rotated.credential.id, issued.id);
await owner.revokeCredential(issued.id);
const {client: lease} = await owner.connect(`tour/${runId}/lease`, 'Lease example', [], {},
  {renewable: true, expires_at: new Date(Date.now() + 2 * 86400000).toISOString()});
assert.ok((await lease.renewCredential()).renewable_until);
```
