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.mdComing soon via CLI:
tawa chaac install iec-relayDetails
- Format
- Rule
- Category
- platform
- Version
- 1.0.0
- Tokens
- ~1,100
- Updated
- 2026-02-27
emailsmsrelaysendgridtwiliosdknotifications