Next.js Quickstart
Send email through the Arawa Mail HTTP API with the
sdp-email-nextjs npm
package. It is a zero-dependency, TypeScript-first client for Next.js server
components, route handlers, and server actions — and any Node.js 18+ app.
Server-side only Your API key must never reach the browser. Use the package in server components, route handlers, server actions, or API routes — never in client components.
Before You Begin
- Add and verify your sending domain in Arawa Mail.
- Enable outbound sending for the domain.
- Create an API key with the
sendingscope.
The from address must use that enabled domain. A domain-restricted API key
must also allow the sender's domain.
1. Install the Package
npm install sdp-email-nextjs
2. Configure the API Key
Add your Arawa Mail API key to .env.local:
SDP_EMAIL_KEY=your_api_key
3. Send an Email
import { SdpEmail } from 'sdp-email-nextjs';
const sdp = new SdpEmail(); // reads SDP_EMAIL_KEY from the environment
const { data, error } = await sdp.emails.send({
from: 'Acme <[email protected]>',
to: '[email protected]',
subject: 'Hello from Next.js',
html: '<p>Sent through Arawa Mail.</p>',
});
if (error) {
console.error(error.name, error.message);
} else {
console.log('Sent:', data.id);
}
In a Server Action
'use server';
import { SdpEmail } from 'sdp-email-nextjs';
const sdp = new SdpEmail();
export async function sendContactMessage(formData: FormData) {
const { error } = await sdp.emails.send({
from: 'Website <[email protected]>',
to: '[email protected]',
reply_to: String(formData.get('email')),
subject: 'New contact message',
text: String(formData.get('message')),
});
return { ok: !error };
}
In a Route Handler
// app/api/send/route.ts
import { NextResponse } from 'next/server';
import { SdpEmail } from 'sdp-email-nextjs';
const sdp = new SdpEmail();
export async function POST(request: Request) {
const body = await request.json();
const { data, error } = await sdp.emails.send({
from: 'Acme <[email protected]>',
to: body.to,
subject: body.subject,
html: body.html,
});
if (error) {
return NextResponse.json(error, { status: error.statusCode || 500 });
}
return NextResponse.json(data);
}
Attachments
Attachment contents are base64-encoded:
import { readFile } from 'node:fs/promises';
await sdp.emails.send({
from: 'Acme <[email protected]>',
to: '[email protected]',
subject: 'Your invoice',
text: 'Invoice attached.',
attachments: [
{
filename: 'invoice.pdf',
content: (await readFile('invoice.pdf')).toString('base64'),
content_type: 'application/pdf',
},
],
});
Error Handling
Methods never throw on API errors. They return { data, error }:
const { data, error } = await sdp.emails.send(payload);
if (error) {
// { statusCode: 401, message: 'Invalid API key', name: 'invalid_api_key' }
}
Network failures and timeouts return an error with statusCode: 0 and
name: 'application_error'.
Optional Connection Settings
The package uses the production endpoint and a 10-second timeout by default:
const sdp = new SdpEmail('your_api_key', {
baseUrl: 'https://app.arawamail.com', // or SDP_EMAIL_ENDPOINT env var
timeout: 10_000, // milliseconds
});
Troubleshooting
Sending is rejected when the sender's domain is not registered, outbound
sending is inactive, the API key lacks the sending scope, or a restricted key
does not allow the sender's domain.