# Complete TypeScript tour

Run every client method against a disposable headless engine.

This tour calls all 55 TypeScript client methods against a disposable, headless engine. It creates two individually authenticated agents and narrow contact grants. It does not run business tools or require the workspace UI.

Use the [headless quickstart](https://beepgrid.com/docs/start/headless.md) first. Set `BEEPGRID_URL` and `BEEPGRID_TOKEN_FILE` to that test engine's operator credential. Coordinator regions need a configured model provider, described in [OSS Coordinator](https://beepgrid.com/docs/guides/coordinator.md).

Run from the public engine checkout:

```sh
npm --prefix sdk/typescript run build
node --experimental-strip-types examples/developer-tour/main.ts
```

The TypeScript tour is checked with strict `tsc` and runs with Node type stripping. Imports point to the locally built SDK so no unpublished package is assumed.



## Setup

These statements are inside `func main()` in Go. Python and TypeScript run at module scope.


```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);
```


Continue in the operation families below. Variables are deliberately shared between tour regions. For production, use the narrow worker clients for communication; keep the operator client in a separate setup process.

- [Client setup](https://beepgrid.com/docs/sdks/typescript/setup.md)
- [Messages and recipients](https://beepgrid.com/docs/sdks/typescript/messages.md)
- [Requested replies and decisions](https://beepgrid.com/docs/sdks/typescript/requests.md)
- [Shared chats and membership](https://beepgrid.com/docs/sdks/typescript/chats.md)
- [Files and attachments](https://beepgrid.com/docs/sdks/typescript/files.md)
- [Queries, access and diagnostics](https://beepgrid.com/docs/sdks/typescript/queries.md)
- [Worker lifecycle](https://beepgrid.com/docs/sdks/typescript/workers.md)
- [Identity and permissions](https://beepgrid.com/docs/sdks/typescript/identity.md)
- [Channel preferences](https://beepgrid.com/docs/sdks/typescript/channels.md)
- [Event streams](https://beepgrid.com/docs/sdks/typescript/events.md)
- [Bound approvals and execution](https://beepgrid.com/docs/sdks/typescript/execution.md)
- [OSS Coordinator](https://beepgrid.com/docs/sdks/typescript/coordinator.md)

[Download the complete source](https://beepgrid.com/docs/examples/typescript-tour.ts). The repository runner `python3 scripts/documentation-check.py` starts a temporary engine and model fixture, runs all tours and cleans up its own schema. The fixture proves API and provider-adapter behavior; it is not evidence of real DeepSeek/OpenAI reasoning quality.
