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/emailInizializzazione
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_abc123La 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 completaElenca 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 programmata | DELETE /v1/emails/{id} |
| Riprogrammare un'email | PATCH /v1/emails/{id} |
| Leggere un singolo contatto | GET /v1/contacts/{id} |
| Modificare / eliminare una campagna | PATCH, DELETE /v1/campaigns/{id} |
| Togliere la programmazione a una campagna | POST /v1/campaigns/{id}/unschedule |
| Click sui link di una campagna | GET /v1/campaigns/{id}/links |
| Modificare / eliminare / ricalcolare un'audience | PATCH, DELETE, POST …/refresh su /v1/audiences/{id} |
| Elencare o rimuovere i contatti di un'audience | GET, DELETE su /v1/audiences/{id}/contacts |
| Anteprima di rendering del markdown | POST /v1/templates/render-preview |
| Gestione delle chiavi API | /v1/api-keys |
| Logo del marchio di workspace | PUT, DELETE /v1/workspace/brand/logo |
Mancano dai tipi della 1.1.0 anche alcuni campi di risposta più recenti:
Workspace non ha limits né brand, Contact non ha trackingOptOut,
ListContactsParams non ha q, e CampaignStats non ha skipped,
untracked né variants. L'API li restituisce; i tipi non li descrivono
ancora.
Link
Modifica questa pagina su GitHub
Ultimo aggiornamento