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

# TypeScript SDK

> Use the typed server SDK for tenant resources, participant sessions, results, continuous evaluation, and webhooks.

# TypeScript and Node.js

The server client covers control-plane resources, participant session creation,
results, continuous evaluation, analytics, and webhooks.

<Info>
  `@apart-ai/synapse@0.1.0` currently requires access to the project's GitHub
  Packages registry and Node.js 20 or newer.
</Info>

## Create a client

```typescript theme={null}
import { SynapseClient } from "@apart-ai/synapse";

const synapse = new SynapseClient({
  baseUrl: process.env.SYNAPSE_API_URL!,
  apiKey: process.env.SYNAPSE_ENVIRONMENT_KEY!,
});

// Generate once, persist with the workflow, and reuse after timeouts/restarts.
const requestId = crypto.randomUUID();
const scope = [organizationId, appId, environmentId] as const;

const { subject } = await synapse.subjects.upsert(
  ...scope,
  { externalId: authenticatedUser.id, profile: { locale: "en" } },
  { idempotencyKey: `${requestId}:subject` },
);

await synapse.programs.enroll(
  ...scope,
  { subjectId: subject.id, programId },
  { idempotencyKey: `${requestId}:enrollment` },
);

const session = await synapse.participantSessions.create(
  ...scope,
  { programId, subjectId: subject.id, expiresInSeconds: 3600 },
  { idempotencyKey: `${requestId}:session` },
);

console.log(session.hosted_url, session.expires_at);
```

## Namespaces

| Namespace                             | Use it for                                                        |
| ------------------------------------- | ----------------------------------------------------------------- |
| `organizations / apps / environments` | Tenant control plane and environment keys                         |
| `subjects`                            | Upsert, batch import, export, deletion, and legal holds           |
| `definitions / bundles`               | Governed scoring and presentation versions                        |
| `programs / participantSessions`      | Deploy bundles, enroll subjects, and mint participant tokens      |
| `evaluations / reports`               | Internal results, drift, release decisions, and revocable shares  |
| `continuousEvaluation`                | Host events, due questions, answers, current alignment, and drift |
| `webhooks / analytics / audit`        | Integrations and privacy-safe operational insight                 |

## Builder workflow

Environment keys may create and validate drafts. Publication, activation,
evaluation release, and report-share management require an authenticated
owner/admin session.

```typescript theme={null}
const cloned = await synapse.definitions.cloneTemplate(
  organizationId,
  appId,
  templateId,
  "advisor-alignment",
  { idempotencyKey: requestIds.clone },
);

// Edit and calibrate drafts first.
for (const definition of cloned.definitions) {
  await synapse.definitions.validate(organizationId, appId, definition.id);
  await synapse.definitions.transition(
    organizationId,
    appId,
    definition.id,
    "validated",
    { idempotencyKey: requestIds[definition.id] },
  );
}

const bundle = await synapse.bundles.create(
  organizationId,
  appId,
  {
    name: "Advisor alignment v1",
    experience_version_id: experienceId,
    scorecard_version_id: scorecardId,
    context_version_id: contextId,
    guardrail_version_id: guardrailId,
    adaptive_policy_version_id: adaptivePolicyId,
    report_template_version_id: reportId,
  },
  { idempotencyKey: requestIds.bundle },
);
```

## Errors, retries, and pages

```typescript theme={null}
import { ApiError } from "@apart-ai/synapse";

try {
  await synapse.subjects.upsert(/* ... */);
} catch (error) {
  if (error instanceof ApiError) {
    console.error(
      error.status,
      error.detail,
      error.requestId,
      error.retryAfter,
    );
  }
  throw error;
}
```

* Persist caller-generated idempotency keys across restarts. Automatic keys
  protect only one invocation.
* List methods return `{ items, next_cursor }`. Use the namespace's
  `listAll*` helper when available.
* Respect `retryAfter` for `429`, and retry only transport errors plus
  supported `408`, `425`, `429`, and `5xx` responses.

Continue with [browser and React integration](/sdk/browser) or inspect the
[wire contract](/api/reference).
