Autenticazione e API Key

Gestire le API key e autenticare le richieste

Tutte le richieste API di Tratto richiedono autenticazione tramite bearer token (API key).

Formato della API Key

Le API key di Tratto seguono questo formato:

tratto_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Prefisso: tratto_live_
  • Seguito da 32 caratteri casuali
  • Usato come bearer token nell'header Authorization

Header di Autenticazione

Includi la tua API key in ogni richiesta:

Authorization: Bearer tratto_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Esempio:

curl https://api.tratto.email/v1/emails \
  -H "Authorization: Bearer tratto_live_..."

Senza l'header, riceverai 401 Unauthorized.

Permessi

Ogni chiave porta con sé un insieme di permessi, applicati ad ogni richiesta: una chiave a cui manca il permesso richiesto da un endpoint riceve 403 Forbidden, indipendentemente dal workspace a cui appartiene.

PermessoConsente
emails:sendInviare email, programmare, annullare, riprogrammare
emails:readLeggere il log email e gli eventi di consegna
contacts:read / contacts:writeLeggere / creare, aggiornare, importare contatti e audience
domains:read / domains:writeLeggere / aggiungere, verificare, rimuovere domini di invio
templates:read / templates:writeLeggere / creare e modificare template
campaigns:read / campaigns:writeLeggere / creare e inviare campagne e flow
webhooks:read / webhooks:writeLeggere / registrare, modificare, ruotare endpoint webhook
api-keys:read / api-keys:writeLeggere / creare, modificare, revocare API key
billing:read / billing:writeLeggere piano e consumi / avviare checkout e portale fatturazione
workspace:writeModificare le impostazioni del workspace, mittente predefinito incluso
members:writeInvitare, rimuovere e cambiare ruolo ai membri del workspace
*Accesso completo — tutti i permessi sopra, inclusi quelli futuri

Concedi l'insieme più ristretto che basta allo scopo. Una chiave che invia solo email transazionali ha bisogno di emails:send e nient'altro; se rispecchia anche le iscrizioni nella tua lista contatti serve pure contacts:write.

* viene memorizzato da solo: elencarlo insieme ai permessi granulari è ridondante, dato che li copre già.

Crea una API Key

Genera una nuova API key tramite l'API, oppure da Impostazioni → API key nella dashboard.

name, env e permissions sono tutti obbligatori. Ometterne permissions (o passare un array vuoto) restituisce 422.

cURL

curl -X POST https://api.tratto.email/v1/api-keys \
  -H "Authorization: Bearer tratto_live_CHIAVE_ESISTENTE" \
  -H "Content-Type: application/json" \
  -d '{"name":"production","env":"live","permissions":["emails:send"]}'

Node.js

const response = await fetch('https://api.tratto.email/v1/api-keys', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer tratto_live_CHIAVE_ESISTENTE',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ name: 'production', env: 'live', permissions: ['emails:send'] }),
});
const { data } = await response.json();
console.log('Nuova API Key:', data.key);

Python

import requests

response = requests.post(
  'https://api.tratto.email/v1/api-keys',
  headers={
    'Authorization': 'Bearer tratto_live_CHIAVE_ESISTENTE',
    'Content-Type': 'application/json',
  },
  json={'name': 'production', 'env': 'live', 'permissions': ['emails:send']},
)
api_key = response.json()['data']['key']
print(f"Nuova API Key: {api_key}")

Risposta:

{
  "data": {
    "id": "key_abc123",
    "name": "production",
    "key": "tratto_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "prefix": "tratto_live_xxxx...xxxx",
    "createdAt": "2025-06-30T12:00:00Z",
    "lastUsedAt": null
  }
}

⚠️ Importante: Il campo key è mostrato una sola volta. Salvalo immediatamente: non verrà più visualizzato. Se lo perdi, revoca e crea una nuova chiave.

Elenca le API Key

Recupera tutte le API key per il tuo tenant.

cURL

curl https://api.tratto.email/v1/api-keys \
  -H "Authorization: Bearer tratto_live_..."

Node.js

const response = await fetch('https://api.tratto.email/v1/api-keys', {
  headers: {
    'Authorization': 'Bearer tratto_live_...',
  },
});
const { data } = await response.json();
console.log(data); // Array di oggetti API key

Python

import requests

response = requests.get(
  'https://api.tratto.email/v1/api-keys',
  headers={'Authorization': 'Bearer tratto_live_...'},
)
keys = response.json()['data']
for key in keys:
  print(f"Key: {key['prefix']} (Creata: {key['createdAt']})")

Risposta:

{
  "data": [
    {
      "id": "key_abc123",
      "name": "production",
      "prefix": "tratto_live_xxxx...xxxx",
      "createdAt": "2025-06-30T12:00:00Z",
      "lastUsedAt": "2025-06-30T13:45:00Z"
    },
    {
      "id": "key_def456",
      "name": "development",
      "prefix": "tratto_live_yyyy...yyyy",
      "createdAt": "2025-06-29T10:00:00Z",
      "lastUsedAt": "2025-06-29T15:20:00Z"
    }
  ]
}

Nota: La chiave completa non è mai restituita dopo la creazione, solo il prefisso (primi e ultimi 4 caratteri).

Modifica i permessi di una chiave

Cambia i permessi di una chiave esistente, senza revocarla né ruotare il segreto. Il valore della chiave non cambia, quindi nulla di ciò che la usa va rideployato — i permessi vengono letti ad ogni richiesta e il nuovo insieme vale già dalla successiva.

cURL

curl -X PATCH https://api.tratto.email/v1/api-keys/key_abc123 \
  -H "Authorization: Bearer tratto_live_..." \
  -H "Content-Type: application/json" \
  -d '{"permissions":["emails:send","contacts:write"]}'

Node.js

const response = await fetch('https://api.tratto.email/v1/api-keys/key_abc123', {
  method: 'PATCH',
  headers: {
    'Authorization': 'Bearer tratto_live_...',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ permissions: ['emails:send', 'contacts:write'] }),
});
const { data } = await response.json();
console.log('Permessi:', data.permissions);

Python

import requests

response = requests.patch(
  'https://api.tratto.email/v1/api-keys/key_abc123',
  headers={
    'Authorization': 'Bearer tratto_live_...',
    'Content-Type': 'application/json',
  },
  json={'permissions': ['emails:send', 'contacts:write']},
)
print(f"Permessi: {response.json()['data']['permissions']}")

permissions sostituisce l'insieme precedente, non ci si fonde. Invia la lista completa che vuoi ottenere.

Richiede api-keys:write. Altre risposte:

StatoQuando
409La chiave è revocata — i permessi non sono più modificabili. Creane una nuova.
422Permesso sconosciuto, lista vuota, o tentativo di rimuovere api-keys:write dalla chiave che sta facendo la richiesta.

Non puoi togliere api-keys:write dalla chiave con cui ti stai autenticando: nessun altro endpoint potrebbe restituirtelo, quindi resteresti chiuso fuori dalla gestione delle chiavi. Rimuoverlo da una chiave diversa è consentito — quello è recuperabile.

Revoca una API Key

Revoca immediatamente una API key per impedirne l'uso.

cURL

curl -X DELETE https://api.tratto.email/v1/api-keys/key_abc123 \
  -H "Authorization: Bearer tratto_live_..."

Node.js

const response = await fetch('https://api.tratto.email/v1/api-keys/key_abc123', {
  method: 'DELETE',
  headers: {
    'Authorization': 'Bearer tratto_live_...',
  },
});
const { data } = await response.json();
console.log('Revocata:', data.id);

Python

import requests

response = requests.delete(
  'https://api.tratto.email/v1/api-keys/key_abc123',
  headers={'Authorization': 'Bearer tratto_live_...'},
)
print(f"Revocata: {response.json()['data']['id']}")

Una volta revocata, le richieste con quella chiave restituiranno 401 Unauthorized.

Best Practice di Sicurezza delle Chiavi

1. Non Esporre le Chiavi Client-Side

Le API key concedono accesso completo al workspace. Non includerle mai in:

  • JavaScript frontend (React, Vue, Angular)
  • App mobile (iOS, Android)
  • Codice sorgente pubblicato su GitHub

Invece, chiama la tua API backend, che tiene la chiave al sicuro.

Per indicazioni specifiche per framework vedi React (Server Component e Server Action) e Angular (SSR e AnalogJS/Nitro).

Sbagliato:

// ❌ NON FARE QUESTO MAI
const trattoKey = 'tratto_live_...';
const response = await fetch('https://api.tratto.email/v1/emails', {
  headers: { 'Authorization': `Bearer ${trattoKey}` },
});

Corretto:

// ✅ Chiama il tuo backend
const response = await fetch('/api/send-email', {
  method: 'POST',
  body: JSON.stringify({ to, subject, text }),
});

2. Tratta le Chiavi come Password

  • Memorizza in variabili di ambiente (.env.local, non .env)
  • Usa la gestione dei segreti per la produzione (GitHub Secrets, HashiCorp Vault, ecc.)
  • Non commitarle su Git

3. Ruota le Chiavi Regolarmente

  • Crea una nuova chiave
  • Aggiorna i tuoi servizi per usare la nuova chiave
  • Aspetta che tutti i deployment finiscano
  • Revoca la vecchia chiave

4. Usa Chiavi Specifiche per gli Ambienti

Crea chiavi separate per:

  • production: Usata solo in produzione
  • staging: Usata solo in staging
  • development: Usata solo nello sviluppo locale

In questo modo, una chiave di sviluppo compromessa non compromette la produzione.

5. Monitora l'Uso delle Chiavi

Controlla lastUsedAt nelle risposte di elenco per identificare chiavi non utilizzate. Revoca periodicamente le chiavi vecchie non utilizzate.

Risposte di Errore

401 Unauthorized

Causa: Mancante o invalida API key.

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Missing or invalid Authorization header",
    "docs": "https://docs.tratto.email/it/authentication"
  }
}

Fix:

  • Assicurati che l'header Authorization: Bearer tratto_live_... sia presente
  • Controlla per errori di digitazione nella API key
  • Verifica che la chiave non sia stata revocata

403 Forbidden

Causa: La API key è valida ma non ha permesso per questa operazione.

{
  "error": {
    "code": "FORBIDDEN",
    "message": "Your API key does not have permission to perform this action",
    "docs": "https://docs.tratto.email/it/authentication"
  }
}

La risposta nomina il permesso mancante, così sai quale aggiungere:

{
  "error": {
    "code": "FORBIDDEN",
    "message": "Missing required permission: contacts:write",
    "suggestion": "Create a new API key with the 'contacts:write' permission."
  }
}

Si risolve concedendo quel permesso alla chiave — vedi Modifica i permessi di una chiave — oppure usando una chiave che lo ha già. Controlla i permessi correnti con GET /v1/api-keys.

Header di Idempotenza

L'header Idempotency-Key previene richieste duplicate su determinati endpoint (operazioni POST che modificano lo stato).

Uso:

POST /v1/emails
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

Regole:

  • Il valore dovrebbe essere un UUID v4 (RFC 4122)
  • Tratto mette in cache la risposta per 24 ore
  • Se riprovi con la stessa chiave, ottieni la stessa risposta senza un'azione duplicata
  • La risposta in cache viene restituita per ogni retry con quella chiave; il corpo non viene confrontato, quindi riusa una chiave solo per l'operazione che l'ha creata

Esempio:

import { v4 as uuidv4 } from 'uuid';

const idempotencyKey = uuidv4();
const response = await fetch('https://api.tratto.email/v1/emails', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer tratto_live_...',
    'Idempotency-Key': idempotencyKey,
  },
  body: JSON.stringify({
    from: '[email protected]',
    to: '[email protected]',
    subject: 'Ciao',
    text: 'Mondo',
  }),
});

Vedi Idempotenza per ulteriori dettagli.


Prossimi Passi


Modifica questa pagina su GitHub

Ultimo aggiornamento