← Back to Skills

InsureRelay — Email & SMS

Send email and SMS with templates, raw content, CC/BCC, and BYOP providers.

Ruleplatform

About

Complete guide to the iec-relay platform service and @insureco/relay SDK. Covers sending transactional emails and SMS, template mode vs raw content mode, CC/BCC recipients (max 50 each), BYOP email providers (SendGrid/Gmail), sandbox mode, fire-and-forget patterns, and common mistakes.

Skill Content

This is the raw markdown that gets installed as a Claude Code rule.

# iec-relay — Email & SMS

## What this skill covers
Sending transactional email and SMS through the iec-relay platform service. Template patterns, sandbox behavior, CC/BCC, BYOP providers, and SDK usage.

## SDK Setup

```typescript
import { RelayClient } from '@insureco/relay'

// In-cluster (recommended): auto-reads BIO_CLIENT_ID + BIO_CLIENT_SECRET
const relay = RelayClient.fromEnv()

// Local dev: set RELAY_DIRECT_URL=http://localhost:4001 in .env.local
```

No explicit `internalDependencies` declaration needed — iec-relay is accessible from all services through Janus automatically.

## Sending Email

```typescript
// With a built-in template
await relay.sendEmail({
  template: 'welcome',
  to: { email: '[email protected]', name: 'Jane Doe' },
  data: { firstName: 'Jane', orgName: 'Acme Corp' },
})

// With custom HTML content
await relay.sendEmail({
  content: {
    subject: 'Your quote is ready',
    html: '<h1>Hello {{name}},</h1><p>Your quote is attached.</p>',
    text: 'Hello {{name}}, your quote is ready.',
  },
  to: { email: '[email protected]', name: 'Jane' },
  data: { name: 'Jane' },
  options: {
    fromName: 'MyProgram',
    cc: ['[email protected]'],
    bcc: '[email protected]',
  },
})
```

## CC and BCC

```typescript
await relay.sendEmail({
  content: { subject: 'Team update', html: '<p>Hi all</p>' },
  to: { email: '[email protected]' },
  options: {
    cc: ['[email protected]', '[email protected]'],  // visible to all
    bcc: '[email protected]',                     // hidden from others
  },
})
```

- Accepts a single email string or an array of emails
- Max 50 recipients per field
- BCC addresses are stored in message logs but NOT included in Septor audit events
- Email channel only — ignored for SMS

## Sending SMS

```typescript
await relay.sendSMS({
  content: { text: 'Your verification code is {{code}}. Expires in 10 minutes.' },
  to: { phone: '+15551234567' },
  data: { code: '123456' },
})
```

## Built-In Templates

| Name | Purpose | Required Data |
|------|---------|---------------|
| `welcome` | New user onboarding | `firstName`, `orgName` |
| `invitation` | Invite user to org | `inviterName`, `orgName`, `inviteUrl` |
| `password-reset` | Password reset link | `firstName`, `resetUrl` |
| `magic-link` | Passwordless login | `firstName`, `magicUrl` |

## Email Providers (BYOP)

By default, relay sends from `[email protected]`. Connect your own SendGrid or Gmail account in Console → Communications → Email Provider.

```typescript
await relay.sendEmail({
  template: 'policy-renewal',
  to: { email: '[email protected]' },
  data: { policyNumber: 'POL-10042' },
  options: {
    fromEmail: '[email protected]',   // use connected SendGrid account
    fromName: 'Claims Team',
  },
})
```

If `fromEmail` is omitted, the first active provider for the org is used. If none is connected, the platform account sends the message.

## Sandbox Mode

When `RELAY_MODE=sandbox` (set automatically in sandbox environments), iec-relay logs messages instead of sending them. No real emails or SMS are delivered.

## Fire-and-Forget Pattern (Recommended)

Email and SMS are not on the critical path. Never block your response waiting for delivery:

```typescript
// CORRECT: fire-and-forget
relay.sendEmail({
  template: 'welcome',
  to: { email: user.email, name: user.name },
  data: { firstName: user.firstName, orgName: user.orgName },
}).catch((err) => logger.warn({ err }, 'Failed to send welcome email'))

// WRONG: blocking your response handler on email
await relay.sendEmail(...)  // never do this in request handlers
```

## Key Facts
- `fromName` sets the display name only — the actual from address is always your org's configured domain or `[email protected]`
- Retries (default: 2) may cause duplicate messages if the network drops after delivery. Set `retries: 0` if duplicates are unacceptable
- Templates use `{{variable}}` Handlebars-style interpolation
- SMS requires E.164 phone format: `+15551234567` (country code required)
- CC/BCC: max 50 recipients each, email only, BCC excluded from audit events

## Common Mistakes
- Awaiting `relay.sendEmail()` in a request handler — use fire-and-forget with `.catch()`
- Using the deprecated `from` field — use `fromName` instead
- Hardcoding credentials — always use `RelayClient.fromEnv()`
- Expecting sandbox to send real emails — the platform prevents this automatically
- Using 6+ digit US phone numbers without country code — always E.164 format

Install

Copy the skill content and save it to:

~/.claude/rules/iec-relay.md
Download .md

Coming soon via CLI:

tawa chaac install iec-relay

Details

Format
Rule
Category
platform
Version
1.0.0
Tokens
~1,100
Updated
2026-02-27
emailsmsrelaysendgridtwiliosdknotifications