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

# Node.js / TypeScript SDK

> Install and use the official Essal Node.js SDK to interact with all six apps from your TypeScript or JavaScript project.

The `@essal/sdk` package provides full access to the Essal API from Node.js. It supports both ESM and CommonJS, includes TypeScript definitions, and works in any Node.js 18+ environment.

## Installation

```bash theme={null}
npm install @essal/sdk
# or
yarn add @essal/sdk
```

## Initialisation

```ts theme={null}
import { EssalClient } from "@essal/sdk";

const client = new EssalClient({
  apiKey: process.env.ESSAL_API_KEY,
  environment: "production", // "production" | "staging" | "sandbox"
});
```

## Usage Examples

### Office

```ts theme={null}
// List documents
const { data: docs } = await client.office.documents.list({ limit: 20 });

// Create a document
const doc = await client.office.documents.create({
  title: "Q4 Planning",
  content: "<h1>Q4 Planning</h1>",
  content_type: "html",
});
```

### Sales

```ts theme={null}
// Create a contact
const contact = await client.sales.contacts.create({
  display_name: "Jane Smith",
  email: "jane@acmecorp.com",
  organization_name: "Acme Corp",
});

// Move a deal to a new stage
await client.sales.deals.update("deal_01HXYZAAA", {
  stage_id: "stg_01HXYZ3333",
});
```

### Project

```ts theme={null}
// Create a task
const task = await client.project.tasks.create("proj_01HXYZ9876", {
  title: "Design review",
  priority: "high",
  assignee_id: "usr_01HXYZ1111",
});
```

## Pagination

Use the built-in async iterator to page through large result sets:

```ts theme={null}
for await (const doc of client.office.documents.list({ limit: 50 })) {
  console.log(doc.title);
}
```

## Webhook Verification

```ts theme={null}
import { verifyWebhookSignature } from "@essal/sdk";

app.post("/webhook", (req, res) => {
  const isValid = verifyWebhookSignature(
    req.rawBody,
    req.headers["x-essal-signature"],
    process.env.ESSAL_WEBHOOK_SECRET
  );
  if (!isValid) return res.status(401).send("Invalid signature");
  // process event...
  res.sendStatus(200);
});
```
