Courriel
Envoi et envois groupés
POST /v1/emails envoie un courriel, et un envoi groupé en envoie jusqu’à 100 d’un coup. Les noms de champs sont ceux de Resend : la plupart des requêtes existantes fonctionnent telles quelles.
Envoyer un courriel
POST /v1/emails envoie un courriel. Les noms de champs sont ceux de Resend : la plupart des requêtes existantes fonctionnent telles quelles.
| Champ | Signification |
|---|---|
| from | Expéditeur, avec un nom au besoin. Son domaine doit être un domaine d’envoi vérifié de votre compte. |
| to, cc, bcc | Une chaîne ou un tableau ; au plus 50 destinataires entre to, cc et bcc. |
| reply_to | Une chaîne ou un tableau. |
| subject, html, text | Objet de 998 caractères au plus, et au moins html ou text. Omettez les trois pour envoyer un modèle. |
| variables | Valeurs à substituer dans subject, html et text. Ignoré quand template est présent ; les variables propres à un modèle vont dans template.variables. |
| template | Envoie un modèle enregistré par identifiant ou alias, avec ses variables. |
| attachments | filename et l’un de content (base64), content_base64 ou path (une URL HTTPS). content_id intègre le fichier dans le corps. Au plus 10 fichiers et 25 Mo au total. Les 2 premiers Mo par destinataire sont inclus ; chaque Mo entamé au-delà coûte 0,002 $ par destinataire (email_attachment_price_millicents_per_mb dans GET /v1/pricing). Les exécutables et les scripts (.exe, .js, .bat, .jar et similaires) sont refusés. |
| tags | Jusqu’à 10 paires name et value, chaque partie de 1 à 256 lettres, chiffres, traits de soulignement ou traits d’union. Les noms commençant par honkio_ sont réservés. Filtrez avec GET /v1/emails?tag=name:value. Les tags sont conservés aussi longtemps que le courriel, même après la purge de l’objet et du corps; n’y mettez aucun renseignement personnel. Le champ body_purged_at d’un courriel récupéré est nul tant que ce n’est pas fait. |
| headers | En-têtes de courriel supplémentaires, envoyés tels quels. |
| scheduled_at | Une date et heure ISO 8601, de 1 minute à 30 jours à l’avance. |
| is_commercial | False par défaut. True désigne un message commercial au sens de la LCAP ; voir plus bas. |
| tracking | Ouvertures et clics pour ce courriel, qui priment sur le réglage du domaine. |
const { data, error } = await honkio.emails.send({
from: 'Acme Receipts <receipts@mail.acme.ca>',
to: ['ada@example.com'],
replyTo: 'help@acme.ca',
subject: 'Your receipt for order 1042',
html: '<img src="cid:logo"><p>Thanks for your order.</p>',
text: 'Thanks for your order.',
tags: [{ name: 'kind', value: 'receipt' }],
attachments: [
{ filename: 'receipt.pdf', path: 'https://files.acme.ca/r/1042.pdf' },
{ filename: 'logo.png', content: 'iVBORw0KGgo...', contentId: 'logo' },
],
scheduledAt: '2026-10-01T13:00:00-04:00',
}, { idempotencyKey: 'order-1042-receipt' })
if (error) throw new Error(error.message)
console.log(data.id, data.status, data.scheduled_at)curl -X POST https://api.honkio.ca/v1/emails \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Idempotency-Key: order-1042-receipt" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme Receipts <receipts@mail.acme.ca>",
"to": ["ada@example.com"],
"reply_to": "help@acme.ca",
"subject": "Your receipt for order 1042",
"html": "<img src=\"cid:logo\"><p>Thanks for your order.</p>",
"text": "Thanks for your order.",
"tags": [{ "name": "kind", "value": "receipt" }],
"attachments": [
{ "filename": "receipt.pdf", "path": "https://files.acme.ca/r/1042.pdf" },
{ "filename": "logo.png", "content": "iVBORw0KGgo...", "content_id": "logo" }
],
"scheduled_at": "2026-10-01T13:00:00-04:00"
}'// Move it, or cancel it (refunded), while it is still scheduled:
const moved = await honkio.emails.update('EMAIL_ID', { scheduledAt: '2026-10-02T09:00:00-04:00' })
if (moved.error) throw new Error(moved.error.message)
const cancelled = await honkio.emails.cancel('EMAIL_ID')
if (cancelled.error) throw new Error(cancelled.error.message)# Move it, or cancel it (refunded), while it is still scheduled:
curl -X PATCH https://api.honkio.ca/v1/emails/EMAIL_ID -H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" -d '{ "scheduled_at": "2026-10-02T09:00:00-04:00" }'
curl -X DELETE https://api.honkio.ca/v1/emails/EMAIL_ID -H "Authorization: Bearer mk_live_YOUR_KEY"Une pièce jointe path est récupérée une seule fois à l’envoi, en HTTPS seulement, depuis une adresse publique, en 10 secondes au plus. Si elle est inaccessible, l’envoi est refusé avec EMAIL_ATTACHMENT_FETCH_FAILED et rien n’est facturé. Les pièces jointes ne sont conservées que jusqu’à l’envoi du courriel.
Un courriel programmé peut être déplacé avec PATCH ou annulé avec DELETE tant qu’il est encore programmé ; l’annulation rembourse les frais. Les pièces jointes fonctionnent aussi pour les envois programmés.
Envoyez un en-tête Idempotency-Key pour tout ce qui peut être relancé. La même clé renvoie la réponse d’origine au lieu d’envoyer, et de facturer, deux fois.
Une relance qui arrive pendant que la première requête portant cette clé est encore en cours de facturation reçoit 409 EMAIL_IDEMPOTENCY_IN_PROGRESS. Réessayez la même clé sous peu plutôt que d’en changer.
Consultez vos envois avec GET /v1/emails, du plus récent au plus ancien, et GET /v1/emails/:id pour un courriel et ses événements. Filtrez la liste par to (toute adresse de la liste to; cc et bcc ne sont pas cherchés), from, since et until (ISO 8601 avec un décalage), domain_id, status et tag, et paginez avec limit et cursor. Une clé ne lit que les courriels de son propre mode : une clé réelle liste les envois réels, une clé de test les envois de test.
const { data, error } = await honkio.emails.list({ to: 'sam@example.com', since: '2026-09-01T00:00:00Z', limit: 20 })
if (error) throw new Error(error.message)
for (const email of data.data) console.log(email.id, email.to, email.status, email.livemode)
console.log(data.has_more, data.next_cursor)curl "https://api.honkio.ca/v1/emails?to=sam@example.com&since=2026-09-01T00:00:00Z&limit=20" \
-H "Authorization: Bearer mk_live_YOUR_KEY"
# → { "data": [{ "id": "...", "from": "...", "to": ["sam@example.com"], "status": "delivered", "attachments_count": 0, "livemode": true, ... }], "has_more": false, "next_cursor": null }const { data: email, error } = await honkio.emails.get('EMAIL_ID')
if (error) throw new Error(error.message)
console.log(email.status, email.events)curl https://api.honkio.ca/v1/emails/EMAIL_ID -H "Authorization: Bearer mk_live_YOUR_KEY"Envois groupés
Envoyez un tableau JSON d’au plus 100 courriels indépendants. Chaque élément est vérifié avant tout envoi ; un élément invalide fait échouer tout l’appel, tandis qu’un refus de conformité, comme une adresse supprimée, ne rejette que cet élément et est listé avec son indice.
const { data, error } = await honkio.batch.send([
{ from: 'noreply@mail.acme.ca', to: 'ada@example.com', subject: 'Your code', text: '123456' },
{ from: 'noreply@mail.acme.ca', to: 'lin@example.com', template: { id: 'welcome', variables: { first_name: 'Lin' } } },
])
if (error) throw new Error(error.message)
console.log(data.data, data.batch_id, data.rejected) // [{ id }, { id }], '...', []curl -X POST https://api.honkio.ca/v1/emails/batch \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '[
{ "from": "noreply@mail.acme.ca", "to": "ada@example.com", "subject": "Your code", "text": "123456" },
{ "from": "noreply@mail.acme.ca", "to": "lin@example.com", "template": { "id": "welcome", "variables": { "first_name": "Lin" } } }
]'
# → 200 { "data": [{ "id": "cm..." }, { "id": "cm..." }], "batch_id": "...", "rejected": [] }data ne liste que les courriels réellement envoyés ; il n’est donc pas aligné avec votre requête par position. Faites correspondre un rejet à son élément d’origine grâce au champ index de rejected.
Ou envoyez un même message à au plus 500 destinataires, sous forme d’objet avec une liste recipients, chacun avec ses propres variables. Les pièces jointes et la programmation par élément ne sont pas offertes en envoi groupé.
const { data, error } = await honkio.batch.send({
from: 'noreply@mail.acme.ca',
template: { id: 'shipping-update' },
recipients: [
{ to: 'ada@example.com', variables: { first_name: 'Ada', tracking: '1Z999' } },
{ to: 'lin@example.com', variables: { first_name: 'Lin', tracking: '1Z998' } },
],
})
if (error) throw new Error(error.message)
console.log(data.batch_id, data.accepted_count, data.rejected)curl -X POST https://api.honkio.ca/v1/emails/batch \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@mail.acme.ca",
"template": { "id": "shipping-update" },
"recipients": [
{ "to": "ada@example.com", "variables": { "first_name": "Ada", "tracking": "1Z999" } },
{ "to": "lin@example.com", "variables": { "first_name": "Lin", "tracking": "1Z998" } }
]
}'
HonkIO