# JavaScript and TypeScript

npm install @texadesk/sdk. A dependency-free client for Node, Deno, Bun and edge runtimes.


```bash
npm install @texadesk/sdk
```

No dependencies: Node 20+, Deno, Bun and edge runtimes (Cloudflare Workers, Vercel). Types are
included. The package is [`@texadesk/sdk` on npm](https://www.npmjs.com/package/@texadesk/sdk).
**Keep it on your server**: it holds your key. For a page or an app, use [the widgets](/sdks/widget).

## Use it

```ts
import { TexaClient, parseWebhook } from "@texadesk/sdk";

const texa = new TexaClient({ key: process.env.TEXA_API_KEY! });
const convo = await texa.openConversation({ channel: "web", customer_ref: "user-1842" },
                                          "open-user-1842");
const out = await texa.sendMessage(convo.conversation_id,
                                   { text: "Where is my transfer?", message_id: "msg-551" });
const events = await texa.runActions(convo.conversation_id, out, {
  get_transfer_status: async (inputs) => ({ status: "paid_out" }),
});
```

## Webhooks

```ts
// Express: keep the raw body for the signature
app.post("/texa/webhooks", express.raw({ type: "application/json" }), async (req, res) => {
  const event = await parseWebhook(process.env.TEXA_WEBHOOK_SECRET!, req.headers, req.body);
  res.sendStatus(200);
  queue.push(event);
});
```

`verifyWebhook` checks without parsing; `signWebhook` signs a body, for your tests.

## Widget sessions

```ts
app.post("/texa/session", requireSignIn, async (req, res) => {
  res.json(await texa.widgetSession(`user-${req.user.id}`, {
    first_name: req.user.firstName, email: req.user.email,
  }));
});
```

## Errors

A failed request throws `TexaError` with `status`, `type`, `code`, `message`, `field` and
`requestId` (and `retryAfter` on a 429). See [errors](/api-basics/errors).
