Node.js SDK
Connect customer records, events, and prepared campaigns from your Node.js or TypeScript service. The client exposes the Public API through resource methods, typed errors, and pagination helpers.
The npm maxclicks package is currently a placeholder. These examples
describe the client in
maxclicks-ai/maxclicks-node.
Use that source or the HTTP quickstart until a client release
is available.
Current API coverage
This guide documents the existing source client interface. The current REST API also exposes event readiness, event identity changes, record deletion status, and workflow history cursors that this client does not yet wrap. Event receipts and deletion results have changed; older static models may omit fields or expect the former { id, deleted } shape.
Use direct HTTP for those operations and verify the current coverage table before adopting a wrapper. Auto-pagination still stops at the API's traversal cap; an iterator or method named all does not guarantee a full workspace export.
Install
Nothing to install yet. The reference below documents the shape of the client for when the release ships.
Authenticate
Pass an API key to new Maxclicks(...), or set MAXCLICKS_API_KEY and call new Maxclicks().
import { Maxclicks } from 'maxclicks'
const mc = new Maxclicks('max_...')
const me = await mc.me()
console.log(me.space?.name)
CommonJS works too:
const { Maxclicks } = require('maxclicks')
Configuration
- Name
apiKey- Type
- string
- Description
Your API key. Defaults to the
MAXCLICKS_API_KEYenvironment variable.
- Name
baseUrl- Type
- string
- Description
API base URL. Defaults to
https://api.maxclicks.ai/v1.
- Name
timeoutMs- Type
- number
- Description
Per-request timeout. Defaults to
60000.
- Name
maxRetries- Type
- number
- Description
Extra attempts on
429, plus5xxand transport errors for reads and calls that carry an idempotency key. Defaults to2.
- Name
onWarning- Type
- function
- Description
Callback for non-fatal API warnings.
const mc = new Maxclicks({
apiKey: process.env.MAXCLICKS_API_KEY,
baseUrl: 'https://api.maxclicks.ai/v1',
timeoutMs: 60000,
maxRetries: 2,
onWarning: (warnings) => console.warn(warnings),
})
Send and upsert
schema is a schema id or slug. Records are flat: base fields plus your custom attribute values at the top level.
// Upsert a contact by identity (id, userId, email, or phone).
const contact = await mc.records.upsert('students', {
email: '[email protected]',
firstName: 'Ada',
tags: ['beta'],
})
// Send a template to a contact resolved by email.
await mc.templates.send(templateId, {
data: { contact: { email: '[email protected]', firstName: 'Ada' } },
})
// Fire an event.
await mc.events.fire('purchase-completed', { eventId: 'ord_123', amount: 42 })
records.create is a strict create and returns 409 if the identity exists. records.upsert creates or updates by identity. See Contacts for the identity cascade.
Pagination
Every offset-paginated list returns a Page. A Page is both a single page and an async iterable over every item across all pages. It auto-fetches subsequent pages as you iterate. events.list is the exception: it is cursor-paginated and returns a plain EventPage with data, pagination and warnings, which you page by passing pagination.nextCursor back as cursor.
// One page.
const page = await mc.records.list('students', { limit: 100 })
console.log(page.data, page.pagination.totalCount, page.pagination.hasMore)
// Every record, auto-fetching subsequent pages.
for await (const record of await mc.records.list('students')) {
console.log(record.id)
}
// Or collect them all.
const all = await (await mc.records.list('students')).all()
Errors
Every failure throws a typed subclass of MaxclicksError. The happy path returns data directly.
import {
MaxclicksError,
MaxclicksNotFoundError,
MaxclicksRateLimitError,
} from 'maxclicks'
try {
const record = await mc.records.get('students', 'missing-id')
} catch (error) {
if (error instanceof MaxclicksNotFoundError) {
// 404
} else if (error instanceof MaxclicksRateLimitError) {
console.log('retry after', error.retryAfterMs)
} else if (error instanceof MaxclicksError) {
console.error(error.status, error.code, error.type, error.message)
}
}
| Error | When |
|---|---|
MaxclicksBadRequestError | 400 validation failure |
MaxclicksAuthenticationError | 401 missing or invalid API key |
MaxclicksPermissionError | 403 insufficient permission or space out of scope |
MaxclicksNotFoundError | 404 resource not found |
MaxclicksConflictError | 409 identifier or uniqueness conflict |
MaxclicksUnprocessableEntityError | 422 (for example a batch abort) |
MaxclicksRateLimitError | 429 rate limited (carries retryAfterMs) |
MaxclicksServerError | 5xx server error |
MaxclicksConnectionError / MaxclicksTimeoutError | transport failure or timeout |
MaxclicksConfigurationError | client misconfiguration (for example no API key) |
The SDK retries reads on 429, 5xx, and transport errors with jittered
exponential backoff, honoring the Retry-After header. A write is only
retried on 5xx and transport errors when you pass idempotencyKey, so your
code can inspect an uncertain outcome. Every request is still retried on
429. Tune the attempt count with maxRetries.
Retry outcomes
A repeated write can return a recorded result, including an error. If the API reports idempotency_outcome_unknown, inspect the affected resource or run history before creating a new operation. Keep the original key and payload while you reconcile. See the idempotency guide for supported operations and retention.