Skip to main content

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.

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 Works on Node 18+, Bun, Deno, and the browser. Zero runtime dependencies — uses native fetch.
pnpm add @notealy/sdk
# or
npm install @notealy/sdk

Hello, world

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

ResourceMethods
notealy.meget()
notealy.peoplelist, get, create, update, delete, addTags, removeTag
notealy.companieslist, get, create, update, delete
notealy.tagslist, create
notealy.emailtemplates, send, sendExternal
notealy.emailCampaignslist, get, send
notealy.messagessend (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).
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:
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:
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 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 if you need either before then.