Platforms like lobster.works can use openmail to provide email capabilities to their users. This guide walks through the integration flow.
Overview
As an integration platform, you will:
Create inboxes for your users when they enable email
Receive inbound emails via webhooks when messages arrive
Send emails on behalf of users via the API
Map inboxes to your users using externalId
Authentication Use your API key: Authorization: Bearer om_live_...
Base URL https://api.openmail.sh
Step 1: Create inboxes for users
When a user enables email in your app, create an inbox and store the mapping:
curl -X POST https://api.openmail.sh/v1/inboxes \
-H "Authorization: Bearer om_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"externalId": "user_abc123",
"username": "support"
}'
externalId is your user/workspace ID. Use it to map inbound webhooks back to the right context. username is optional — we’ll generate one (e.g. a1b2c3d4) if omitted.
Response:
{
"id" : "inb_92ma..." ,
"address" : "support@yourdomain.openmail.sh" ,
"externalId" : "user_abc123" ,
"createdAt" : "2024-03-21T10:00:00.000Z"
}
Store id and address in your database. The user can now receive email at address.
During onboarding, you provide a webhook URL and webhook secret . openmail sends message.received events when inbound email arrives.
Your webhook endpoint must respond with 200 within 15 seconds. We retry failed deliveries up to 5 times with exponential backoff.
Webhook payload
{
"event" : "message.received" ,
"event_id" : "evt_abc123" ,
"occurred_at" : "2024-03-21T10:05:00.000Z" ,
"delivered_at" : "2024-03-21T10:05:01.000Z" ,
"attempt" : 1 ,
"inbox_id" : "inb_92ma..." ,
"external_id" : "user_abc123" ,
"thread_id" : "thr_xyz..." ,
"message" : {
"id" : "msg_..." ,
"rfc_message_id" : "<original@message.id>" ,
"from" : "customer@example.com" ,
"to" : "support@yourdomain.openmail.sh" ,
"cc" : [] ,
"subject" : "Help with my order" ,
"body_text" : "Hi, I need help..." ,
"attachments" : [
{
"filename" : "invoice.pdf" ,
"contentType" : "application/pdf" ,
"sizeBytes" : 12345 ,
"url" : "https://api.openmail.sh/v1/attachments/msg_.../invoice.pdf"
}
] ,
"received_at" : "2024-03-21T10:05:00.000Z"
}
}
Use external_id to look up the user in your system. Attachment URLs are signed and expire; fetch them promptly.
Verify webhook signatures
Always verify the X-Signature header to ensure the request came from openmail:
const crypto = require ( 'crypto' );
function verifyWebhook (payload , timestamp , signature , secret) {
const signed = crypto
.createHmac ( 'sha256' , secret)
.update ( ` ${ timestamp } . ${ payload } ` )
.digest ( 'hex' );
return crypto .timingSafeEqual ( Buffer .from (signature , 'hex' ) , Buffer .from (signed , 'hex' ));
}
// In your webhook handler:
app .post ( '/webhooks/openmail' , (req , res) => {
const payload = JSON .stringify ( req .body);
const timestamp = req .headers[ 'x-timestamp' ];
const signature = req .headers[ 'x-signature' ];
if ( ! verifyWebhook (payload , timestamp , signature , process . env . OPENMAIL_WEBHOOK_SECRET )) {
return res .status ( 401 ) .send ( 'Invalid signature' );
}
const { event , external_id , message } = req .body;
if (event === 'message.received' ) {
// Handle inbound email for user external_id
}
res .status ( 200 ) .send ( 'OK' );
});
Step 3: Send email on behalf of users
Use the send endpoint with the inbox ID. Include an Idempotency-Key header (e.g. UUID) to avoid duplicate sends on retries:
curl -X POST https://api.openmail.sh/v1/inboxes/inb_92ma.../send \
-H "Authorization: Bearer om_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{
"to": "customer@example.com",
"subject": "Re: Help with my order",
"body": "Thanks for reaching out. We are looking into it.",
"threadId": "thr_xyz..."
}'
Use threadId when replying so the conversation stays threaded. Get it from the webhook payload or from GET /v1/inboxes/:id/threads.
Step 4: List messages and threads
Fetch messages and threads for an inbox:
# List messages (optionally filter by direction)
curl "https://api.openmail.sh/v1/inboxes/inb_92ma.../messages?direction=inbound&limit=20" \
-H "Authorization: Bearer om_live_YOUR_API_KEY"
# List threads
curl "https://api.openmail.sh/v1/inboxes/inb_92ma.../threads?limit=20" \
-H "Authorization: Bearer om_live_YOUR_API_KEY"
# Get messages in a thread
curl "https://api.openmail.sh/v1/threads/thr_xyz.../messages" \
-H "Authorization: Bearer om_live_YOUR_API_KEY"
Rate limits
Resource Limit Inbox creation 100 per day Send (per inbox) 10 per minute, 200 per day Cold outreach Per-recipient limits apply
Next steps