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

# SDKs

> Official client libraries that wrap the Notealy public API.

You can call the Notealy public API with plain `fetch` / `curl` — but for
production integrations we recommend reaching for the official SDK. It
handles auth, retries on `429`/`5xx`, error mapping, and typed request
payloads so a server-side change surfaces as a compile error instead of
a runtime surprise.

## TypeScript / JavaScript

[![npm](https://img.shields.io/npm/v/%40notealy%2Fsdk.svg)](https://www.npmjs.com/package/@notealy/sdk)

Works on Node 18+, Bun, Deno, and the browser. Zero runtime
dependencies — uses native `fetch`.

```bash theme={null}
pnpm add @notealy/sdk
# or
npm install @notealy/sdk
```

### Hello, world

```ts theme={null}
import { Notealy } from '@notealy/sdk'

const notealy = new Notealy({
  apiToken: process.env.NOTEALY_TOKEN!,
})

const me = await notealy.me.get()
console.log(`Authenticated as ${me.organization.name}`)
```

### Cover map

| Resource                                       | Methods                                                             |
| ---------------------------------------------- | ------------------------------------------------------------------- |
| `notealy.me`                                   | `get()`                                                             |
| `notealy.people`                               | `list`, `get`, `create`, `update`, `delete`, `addTags`, `removeTag` |
| `notealy.companies`                            | `list`, `get`, `create`, `update`, `delete`                         |
| `notealy.tags`                                 | `list`, `create`                                                    |
| `notealy.email`                                | `templates`, `send`, `sendExternal`                                 |
| `notealy.emailCampaigns`                       | `list`, `get`, `send`                                               |
| `notealy.messages`                             | `send` (WhatsApp / Instagram / Facebook routing)                    |
| `verifyWebhook` (from `@notealy/sdk/webhooks`) | HMAC + typed event union                                            |

### Error handling

Non-2xx responses become `NotealyApiError` with `status`, `code`,
`message`, parsed `body`, and `requestId` (when the server sets the
`X-Request-Id` header).

```ts theme={null}
import { Notealy, NotealyApiError } from '@notealy/sdk'

try {
  await notealy.people.create({ email: 'oops' })
} catch (err) {
  if (err instanceof NotealyApiError) {
    console.error(err.status, err.code, err.message)
  } else {
    throw err // network-level failure (DNS, timeout, abort)
  }
}
```

The client retries `429` (honoring `X-RateLimit-Reset`) and `5xx`
responses automatically. Override the policy or disable it per call:

```ts theme={null}
new Notealy({
  apiToken,
  retry: { maxRetries: 0 }, // disable
})
```

### Webhooks

Verify the signature on every delivery — the SDK ships the same HMAC
formula the API uses to sign:

```ts theme={null}
import { verifyWebhook } from '@notealy/sdk/webhooks'

const event = verifyWebhook({
  rawBody: await req.text(),
  header: req.headers.get('x-notealy-signature') ?? '',
  secret: process.env.NOTEALY_WEBHOOK_SECRET!,
})

switch (event.type) {
  case 'contact.created':
  case 'deal.won':
    // event.data is typed against the event type
    break
}
```

Always pass the **raw** body string — re-stringifying after `JSON.parse`
breaks the signature. See [Webhooks → Signing](/webhooks/signing) for
detail.

## Python and Go

In progress. We're validating the TypeScript surface with the first
integrators; Python (httpx + pydantic) and Go (oapi-codegen + stdlib
http) follow once that's stable. Ping us at
[hello@notealy.com](mailto:hello@notealy.com) if you need either
before then.
