Node.js / TypeScript SDK

SDK ufficiale Node.js per Tratto Email API

SDK ufficiale per Node.js e TypeScript: @tratto/email

Ogni esempio di questa pagina è scritto sulla release pubblicata 1.1.0 e compila contro di essa.

Installazione

npm install @tratto/email

Inizializzazione

La classe esportata è Tratto, e la chiave API è un argomento posizionale, non un oggetto di opzioni:

import { Tratto } from '@tratto/email';

const tratto = new Tratto(process.env.TRATTO_API_KEY!);

Un secondo argomento facoltativo sovrascrive la base URL:

const tratto = new Tratto(process.env.TRATTO_API_KEY!, {
  baseUrl: 'https://api.tratto.email',
});

Invia Email

emails.send risolve a { id }, nient'altro. Per leggere lo status, rileggi l'email.

const { id } = await tratto.emails.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Ciao!',
  text: 'Benvenuto a Tratto',
  html: '<h1>Benvenuto!</h1>',
});

console.log(id); // email_abc123

La chiave di idempotenza è il secondo argomento:

await tratto.emails.send(
  { from: '[email protected]', to: '[email protected]', subject: 'Ciao', text: 'Ciao' },
  'ordine-4711-conferma',
);

Invia con Template

const { id } = await tratto.emails.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Benvenuta, Alice!',
  templateId: 'tmpl_abc123',
  variables: {
    firstName: 'Alice',
    code: 'SECRET123',
  },
});

subject è obbligatorio su ogni invio, con o senza template. Un template non ha un oggetto proprio — vedi Template.

Invia con Markdown

Invia Markdown e lascia che il server renderizzi HTML responsive per email — markdown è mutuamente esclusivo con html:

const { id } = await tratto.emails.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Benvenuto!',
  markdown: '# Benvenuto, {{firstName}}!',
  variables: { firstName: 'Alice' },
});

Anche templates.create e templates.update accettano markdown, e il tipo di risposta Template espone format, source e renderWarnings.

Programma un'Email

const { id } = await tratto.emails.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Promemoria',
  text: 'Ci vediamo domani!',
  scheduledAt: new Date('2026-10-01T09:00:00Z'),
});

Annullare o riprogrammare un'email programmata si fa via HTTP: non esiste ancora un metodo SDK — vedi Cosa la 1.1.0 non copre.

Leggi lo Status di un'Email

const email = await tratto.emails.get('email_abc123');
console.log(email.status); // 'delivered'
console.log(email.events); // timeline completa

Elenca le Email

const emails = await tratto.emails.list({
  limit: 50,
  after: 'cursor_value', // per la paginazione
});

emails.data.forEach((email) => {
  console.log(`${email.id}: ${email.status}`);
});

Aggiungi un Dominio

Il metodo è add e prende il dominio come stringa:

const domain = await tratto.domains.add('hello.tuodominio.it');

// `records` è un array di record DNS, non un oggetto con una chiave per tipo
for (const record of domain.records) {
  console.log(`${record.type} ${record.host} → ${record.value}`);
}

Verifica un Dominio

const verified = await tratto.domains.verify('dom_abc123');
console.log(verified.status); // 'pending' | 'verified' | 'failed'

Crea un Contatto

Le proprietà personalizzate stanno in customFields. Il campo metadata non esiste:

const { id } = await tratto.contacts.create({
  email: '[email protected]',
  firstName: 'Alice',
  lastName: 'Smith',
  tags: ['vip', 'newsletter'],
  customFields: { plan: 'pro' },
});

Crea una Campagna

CreateCampaignParams nella 1.1.0 richiede templateId, audienceId, fromName, fromEmail e subjectA. create risolve a { id }:

const { id } = await tratto.campaigns.create({
  name: 'Saldi Q3',
  templateId: 'tmpl_abc123',
  audienceId: 'aud_abc123',
  fromName: 'Acme',
  fromEmail: '[email protected]',
  subjectA: 'I saldi estivi iniziano oggi',
  subjectB: 'Saldi estivi: 30% di sconto, solo oggi', // oggetto A/B, facoltativo
});

const campaign = await tratto.campaigns.get(id);
console.log(campaign.status); // 'draft'

L'API è più permissiva dei tipi della 1.1.0: accetta html inline al posto di un templateId, e interpreta un audienceId omesso come «tutti i contatti del workspace». Nessuna delle due cose è esprimibile con l'SDK: per quelle usa HTTP.

Invia una Campagna

const sent = await tratto.campaigns.send('camp_xyz789');
console.log(sent.status); // 'sending'

Per programmarla, passa una data:

await tratto.campaigns.send('camp_xyz789', {
  scheduledAt: new Date('2026-10-01T09:00:00Z'),
});

Statistiche di una Campagna

Il metodo è getStats. I tassi sono percentuali: 50 significa 50%, non 0.5 — la stessa scala di Analytics.

const stats = await tratto.campaigns.getStats('camp_xyz789');

console.log(stats.stats.delivered);   // 4950
console.log(stats.rates.openRate);    // 50 → 50%
console.log(stats.rates.deliveryRate) // 99 → 99%

Un alert scritto come rates.deliveryRate < 0.95 non scatterà mai. Il confronto giusto è < 95.

Registra un Webhook

const webhook = await tratto.webhooks.create({
  url: 'https://tuoapi.com/webhooks/tratto',
  events: ['sent', 'delivered', 'opened', 'clicked', 'bounced'],
});

console.log(webhook.secret); // whsec_xyz789...

Analytics

AnalyticsPeriod nella 1.1.0 è '7d' | '30d' | '90d':

const summary = await tratto.analytics.getSummary('30d');
console.log(summary.delivered);

L'API accetta anche 180d e 1y, che però non sono ancora nel tipo dell'SDK: per quelli usa HTTP.

Gestione degli Errori

TrattoError espone code, statusCode e docs:

import { Tratto, TrattoError } from '@tratto/email';

const tratto = new Tratto(process.env.TRATTO_API_KEY!);

try {
  await tratto.emails.send({
    from: '[email protected]', // non verificato
    to: '[email protected]',
    subject: 'Ciao',
    text: 'Test',
  });
} catch (error) {
  if (error instanceof TrattoError) {
    // Il messaggio nomina il dominio non verificato.
    console.error(error.code, error.statusCode, error.message);
  }
}

Vedi Codici di Errore per l'elenco completo.

Cosa la 1.1.0 non copre ancora

Questi endpoint esistono nell'API e non hanno un metodo SDK nella 1.1.0. Chiamali via HTTP finché l'SDK non li recupera:

FunzionalitàHTTP
Annullare un'email programmataDELETE /v1/emails/{id}
Riprogrammare un'emailPATCH /v1/emails/{id}
Leggere un singolo contattoGET /v1/contacts/{id}
Modificare / eliminare una campagnaPATCH, DELETE /v1/campaigns/{id}
Togliere la programmazione a una campagnaPOST /v1/campaigns/{id}/unschedule
Click sui link di una campagnaGET /v1/campaigns/{id}/links
Modificare / eliminare / ricalcolare un'audiencePATCH, DELETE, POST …/refresh su /v1/audiences/{id}
Elencare o rimuovere i contatti di un'audienceGET, DELETE su /v1/audiences/{id}/contacts
Anteprima di rendering del markdownPOST /v1/templates/render-preview
Gestione delle chiavi API/v1/api-keys
Logo del marchio di workspacePUT, DELETE /v1/workspace/brand/logo

Mancano dai tipi della 1.1.0 anche alcuni campi di risposta più recenti: Workspace non ha limitsbrand, Contact non ha trackingOptOut, ListContactsParams non ha q, e CampaignStats non ha skipped, untrackedvariants. L'API li restituisce; i tipi non li descrivono ancora.



Modifica questa pagina su GitHub

Ultimo aggiornamento