@artatol/artamail-sdk

JavaScript / Node.js SDK

The core ArtaMail SDK for any JavaScript or Node.js environment.

Installation

Terminal
pnpm add @artatol/artamail-sdk

Quick Start

send-email.ts
1import { ArtaMail } from '@artatol/artamail-sdk';
2
3const artamail = new ArtaMail({
4 apiKey: process.env.ARTAMAIL_API_KEY
5});
6
7// Send an email
8const result = await artamail.send({
10 template: 'welcome',
11 data: { name: 'John' }
12});
13
14console.log('Email sent:', result.id);
15console.log('Test mode:', result.testMode);

Configuration

typescript
const artamail = new ArtaMail({
// Required
apiKey: 'am_live_sk_xxx',
// Optional
baseUrl: 'https://artamail.artatol.net', // Custom API URL
timeout: 30000, // Request timeout (ms)
retries: 3 // Retry attempts
});
OptionTypeDefaultDescription
apiKeystringYour ArtaMail API key (required)
baseUrlstringhttps://artamail.artatol.netAPI base URL
timeoutnumber30000Request timeout in milliseconds
retriesnumber3Number of retry attempts

Identity variables (auto-injected)

At send time ArtaMail fills brand, legal_entity, legal_address, and legal_detailsfrom Settings → Brand & compliance. Pass in data only to override.

Legacy: company
The company field and {{company}} template variable are legacy aliases for brand. They still work today but may be removed in a future release.
Multiple products
Use a separate ArtaMail account (API key) per brand. See Multiple Products.

Configure identity in Settings → Brand & compliance. Use {{legal_address}} and {{legal_details}} in template footers for postal address and registration IDs.

Sending Emails

Single Email

typescript
const result = await artamail.send({
template: 'welcome',
data: {
name: 'John',
verifyUrl: 'https://example.com/verify/abc123'
},
// Optional
from: '[email protected]', // Custom sender (must be verified)
fromName: 'My App', // Sender display name
replyTo: '[email protected]', // Reply-to address
priority: 'high', // 'high' | 'normal' | 'low'
subtypeSlug: 'product-updates', // operational subtype — enforces consent
});

Batch Emails

Send up to 1000 emails in a single request:

typescript
const result = await artamail.sendBatch({
emails: [
{ to: '[email protected]', template: 'notification', data: { message: 'Hello' } },
{ to: '[email protected]', template: 'notification', data: { message: 'Hello' } }
]
});
// Result: { queued: 2, failed: 0, results: [...], testMode: false }

Get Email Status

typescript
const email = await artamail.getEmail('email-uuid');
console.log(email.status); // queued | sending | sent | delivered | bounced | failed
console.log(email.deliveredAt);
console.log(email.openedAt);

Contacts

typescript
// Create or update contact
await artamail.upsertContact({
name: 'John Doe',
locale: 'en',
data: { plan: 'premium' },
lists: ['customers'], // segmentation only
optInSubtypeSlugs: ['weekly-digest'],
});
// Get contact
const contact = await artamail.getContact('[email protected]');
// Update contact
await artamail.updateContact('[email protected]', {
name: 'Jane Doe',
data: { plan: 'enterprise' }
});
// Permanent delete — PII, subscriptions, and list memberships removed
await artamail.deleteContact('[email protected]');

deleteContact permanently erases the contact profile, all subscription preferences, and list memberships, and anonymizes stored email content. Cannot be undone — use upsertContactto add them again as a new contact. Org admins can also run erasure from Settings → GDPR & Privacy (POST /api/gdpr/delete), which anonymizes email history even when no contact row exists.

lists are static list slugs (append on upsert). For explicit add/remove with validation errors, use modifyContactLists. Smart-list membership is not returned on contacts — see Contact Lists API.

Contact lists

typescript
const lists = await artamail.listContactLists();
const vip = await artamail.getContactList('vip');
await artamail.createContactList({
name: 'VIP customers',
slug: 'vip',
});
const membership = await artamail.modifyContactLists('[email protected]', {
add: ['vip'],
remove: ['trial'],
});
await artamail.addContactToLists('[email protected]', ['newsletter']);

Subscriptions & Consent

Grant subtype opt-in, handle double opt-in, and read consent state. See the full guide.

typescript
// Opt-in with optional confirm email (when org DOI is enabled)
await artamail.optInContact({
optInSubtypeSlugs: ['weekly-digest'],
sendConfirmEmail: true,
});
// Or handle DOI manually
const contact = await artamail.upsertContact({
optInSubtypeSlugs: ['weekly-digest'],
});
if (contact.confirmUrl) {
await artamail.sendConsentConfirmEmail({
to: contact.email,
confirmUrl: contact.confirmUrl,
name: contact.name,
});
}
// Skip double opt-in (import / admin)
await artamail.upsertContact({
optInSubtypeSlugs: ['weekly-digest'],
doubleOptIn: false,
});
// List subscription types (includes labelI18n per locale on subtypes)
const types = await artamail.listSubscriptionTypes();
// Custom preference UI — fetch resolved copy for contact locale
const res = await fetch(`https://artamail.artatol.net/api/u/${token}/data`);
const data: import('@artatol/artamail-sdk').PreferencePageData = await res.json();
console.log(data.locale, data.copy.title, data.subtypes[0].label);
// Read per-subtype consent
const prefs = await artamail.getContactSubscriptionPreferences('[email protected]');

Preference page strings are configured in the dashboard and resolved from contacts.locale. See Preferences Data API.

Templates

typescript
// List all templates
const templates = await artamail.listTemplates();
for (const template of templates) {
console.log(template.slug, template.name);
console.log('Variables:', template.variables);
}
// Get single template
const template = await artamail.getTemplate('welcome');

Sender Addresses

typescript
const senders = await artamail.listSenderAddresses();
// Find default sender
const defaultSender = senders.find(s => s.isDefault);
// Use custom sender
await artamail.send({
template: 'welcome',
from: senders[0].email,
fromName: senders[0].name
});

Error Handling

typescript
import {
ArtaMailError,
ValidationError,
AuthenticationError,
RateLimitError,
NotFoundError
} from '@artatol/artamail-sdk';
try {
await artamail.send({ ... });
} catch (error) {
if (error instanceof ValidationError) {
console.error('Invalid input:', error.details);
} else if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
console.error('Rate limited, retry after:', error.retryAfter);
} else if (error instanceof NotFoundError) {
console.error('Resource not found');
}
}
Automatic Retries
The SDK automatically retries failed requests (up to 3 times by default) with exponential backoff for transient errors like network issues or 5xx responses.

TypeScript

The SDK is written in TypeScript and provides full type definitions:

typescript
import type {
ArtaMailConfig,
SendEmailOptions,
SendEmailResult,
BatchEmailOptions,
Contact,
Template,
SenderAddress,
SubscriptionType,
ContactSubscriptionPreference,
OptInContactOptions,
SendConsentConfirmEmailOptions
} from '@artatol/artamail-sdk';