API Reference
Complete API specification for MERU inbound email service including all endpoints, parameters, and response formats.
Prerequisites
- MERU API token
- Basic understanding of REST APIs
API Reference
The MERU API is built on REST principles with predictable resource-oriented URLs, accepts JSON request bodies, returns JSON responses, and uses standard HTTP status codes and authentication.
Base URL
All API requests are made to:
https://api.meruhook.com/v1/
Authentication
All requests require an API token in the Authorization header:
Authorization: Bearer YOUR_API_TOKEN
Addresses
Manage inbound email addresses that forward to your webhooks.
Create Address
Create a new inbound email address.
POST /addresses
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
webhook_url | string | Yes | HTTPS URL to receive webhooks |
is_permanent | boolean | No | Whether address never expires (default: true) |
ttl_hours | integer | No | Hours until expiration (if not permanent) |
description | string | No | Optional description for the address |
Example Request
Choose your language
// Create a new inbound email address
const response = await fetch('https://api.meruhook.com/v1/addresses', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.MERU_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
webhook_url: 'https://yourapp.com/webhook',
is_permanent: true,
description: 'Customer support emails'
})
});
const address = await response.json();
console.log('Created address:', address.address);
Example Response
{
"id": "addr_abc123",
"address": "user123@inbound.meruhook.com",
"webhook_url": "https://yourapp.com/webhook",
"webhook_secret": "whsec_def456ghi789",
"is_enabled": true,
"is_permanent": true,
"expires_at": null,
"email_count": 0,
"description": "Customer support emails",
"created_at": "2025-09-05T10:00:00Z",
"updated_at": "2025-09-05T10:00:00Z"
}
List Addresses
Retrieve all addresses for your account.
GET /addresses
Query Parameters
Parameter | Type | Description |
---|---|---|
limit | integer | Number of results (max 100, default 50) |
offset | integer | Number of results to skip |
is_enabled | boolean | Filter by enabled status |
is_permanent | boolean | Filter by permanent status |
Example Request
Choose your language
// List all addresses
const response = await fetch('https://api.meruhook.com/v1/addresses?limit=10&is_enabled=true', {
headers: {
'Authorization': `Bearer ${process.env.MERU_API_TOKEN}`,
'Content-Type': 'application/json'
}
});
const data = await response.json();
console.log('Addresses:', data.data);
Example Response
{
"data": [
{
"id": "addr_abc123",
"address": "user123@inbound.meruhook.com",
"webhook_url": "https://yourapp.com/webhook",
"is_enabled": true,
"is_permanent": true,
"email_count": 42,
"created_at": "2025-09-05T10:00:00Z"
}
],
"pagination": {
"limit": 10,
"offset": 0,
"total": 1,
"has_more": false
}
}
Get Address
Retrieve a specific address by ID.
GET /addresses/{address_id}
Example Request
Choose your language
// Get a specific address
const addressId = 'addr_abc123';
const response = await fetch(`https://api.meruhook.com/v1/addresses/${addressId}`, {
headers: {
'Authorization': `Bearer ${process.env.MERU_API_TOKEN}`,
'Content-Type': 'application/json'
}
});
const address = await response.json();
console.log('Address:', address);
Example Response
{
"id": "addr_abc123",
"address": "user123@inbound.meruhook.com",
"webhook_url": "https://yourapp.com/webhook",
"webhook_secret": "whsec_def456ghi789",
"is_enabled": true,
"is_permanent": true,
"expires_at": null,
"email_count": 42,
"description": "Customer support emails",
"created_at": "2025-09-05T10:00:00Z",
"updated_at": "2025-09-05T10:00:00Z"
}
Update Address
Update an existing address.
PATCH /addresses/{address_id}
Parameters
Parameter | Type | Description |
---|---|---|
webhook_url | string | New webhook URL |
is_enabled | boolean | Enable or disable the address |
description | string | Update description |
Example Request
Choose your language
// Update an address
const addressId = 'addr_abc123';
const response = await fetch(`https://api.meruhook.com/v1/addresses/${addressId}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.MERU_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
webhook_url: 'https://newapp.com/webhook',
is_enabled: false
})
});
const updatedAddress = await response.json();
console.log('Updated address:', updatedAddress);
Delete Address
Permanently delete an address.
DELETE /addresses/{address_id}
Example Request
Choose your language
// Delete an address
const addressId = 'addr_abc123';
const response = await fetch(`https://api.meruhook.com/v1/addresses/${addressId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.MERU_API_TOKEN}`,
'Content-Type': 'application/json'
}
});
const result = await response.json();
console.log('Delete result:', result);
Example Response
{
"id": "addr_abc123",
"deleted": true
}
Usage
Monitor your inbound email usage and statistics.
Get Usage
Retrieve usage statistics for the current billing period.
GET /usage
Example Request
Choose your language
// Get usage statistics
const response = await fetch('https://api.meruhook.com/v1/usage', {
headers: {
'Authorization': `Bearer ${process.env.MERU_API_TOKEN}`,
'Content-Type': 'application/json'
}
});
const usage = await response.json();
console.log('Usage:', usage);
Example Response
{
"period": {
"start": "2025-09-01T00:00:00Z",
"end": "2025-09-30T23:59:59Z",
"current": true
},
"emails": {
"total": 1250,
"successful": 1200,
"failed": 50,
"today": 45
},
"webhooks": {
"delivered": 1180,
"failed": 70,
"retrying": 0
},
"success_rate": 96.0,
"projected_monthly": 1300,
"updated_at": "2025-09-05T10:00:00Z"
}
Get Usage Events
Retrieve detailed usage events (audit trail).
GET /usage/events
Query Parameters
Parameter | Type | Description |
---|---|---|
limit | integer | Number of events (max 1000, default 100) |
offset | integer | Number of events to skip |
start_date | string | ISO 8601 start date filter |
end_date | string | ISO 8601 end date filter |
event_type | string | Filter by event type |
Example Request
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
"https://api.meruhook.com/v1/usage/events?limit=50"
Example Response
{
"data": [
{
"id": "evt_abc123",
"type": "email.received",
"address_id": "addr_abc123",
"timestamp": "2025-09-05T10:30:00Z",
"data": {
"from": "user@example.com",
"subject": "Support Request",
"size_bytes": 1024,
"webhook_status": "delivered"
}
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 1250,
"has_more": true
}
}
Billing
Access billing information and manage costs.
Get Billing
Retrieve current billing status and costs.
GET /billing
Example Request
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://api.meruhook.com/v1/billing
Example Response
{
"subscription": {
"plan": "pro",
"status": "active",
"current_period_start": "2025-09-01T00:00:00Z",
"current_period_end": "2025-09-30T23:59:59Z",
"trial_end": null
},
"usage": {
"emails_included": 1300,
"emails_used": 1250,
"emails_remaining": 50
},
"costs": {
"base_cost": 10.00,
"overage_cost": 0.00,
"total_cost": 10.00,
"projected_cost": 10.00,
"currency": "USD"
},
"next_billing_date": "2025-10-01T00:00:00Z"
}
Get Billing History
Retrieve billing history and invoices.
GET /billing/history
Query Parameters
Parameter | Type | Description |
---|---|---|
limit | integer | Number of invoices (max 100, default 12) |
offset | integer | Number of invoices to skip |
Example Request
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://api.meruhook.com/v1/billing/history
Example Response
{
"data": [
{
"id": "inv_abc123",
"period_start": "2025-08-01T00:00:00Z",
"period_end": "2025-08-31T23:59:59Z",
"amount_paid": 10.00,
"currency": "USD",
"status": "paid",
"invoice_pdf": "https://billing.meruhook.com/invoices/inv_abc123.pdf",
"paid_at": "2025-09-01T00:00:00Z"
}
],
"pagination": {
"limit": 12,
"offset": 0,
"total": 3,
"has_more": false
}
}
Account
Manage account information and API tokens.
Get Account
Retrieve account information.
GET /account
Example Request
Choose your language
// Get account information
const response = await fetch('https://api.meruhook.com/v1/account', {
headers: {
'Authorization': `Bearer ${process.env.MERU_API_TOKEN}`,
'Content-Type': 'application/json'
}
});
const account = await response.json();
console.log('Account:', account);
Example Response
{
"id": "acc_abc123",
"email": "user@example.com",
"name": "John Doe",
"company": "Example Corp",
"plan": "pro",
"created_at": "2025-01-15T10:00:00Z",
"settings": {
"timezone": "America/New_York",
"webhook_retry_attempts": 3,
"default_ttl_hours": 720
}
}
List API Tokens
Retrieve all API tokens for your account.
GET /account/tokens
Example Request
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://api.meruhook.com/v1/account/tokens
Example Response
{
"data": [
{
"id": "token_abc123",
"name": "Production API",
"prefix": "meru_live_abc123",
"created_at": "2025-01-15T10:00:00Z",
"last_used_at": "2025-09-05T09:30:00Z",
"permissions": ["addresses:read", "addresses:write", "usage:read"]
}
]
}
Create API Token
Create a new API token.
POST /account/tokens
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
name | string | Yes | Descriptive name for the token |
permissions | array | No | List of permissions (default: all) |
Example Request
Choose your language
// Create a new API token
const response = await fetch('https://api.meruhook.com/v1/account/tokens', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.MERU_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Staging API',
permissions: ['addresses:read', 'addresses:write']
})
});
const token = await response.json();
console.log('Created token:', token.token);
Example Response
{
"id": "token_def456",
"name": "Staging API",
"token": "meru_live_def456ghi789...",
"prefix": "meru_live_def456",
"permissions": ["addresses:read", "addresses:write"],
"created_at": "2025-09-05T10:00:00Z"
}
Important: The full token is only shown once during creation. Store it securely.
Delete API Token
Delete an API token.
DELETE /account/tokens/{token_id}
Example Request
curl -X DELETE https://api.meruhook.com/v1/account/tokens/token_def456 \
-H "Authorization: Bearer YOUR_API_TOKEN"
Rate Limiting
The API implements rate limiting to ensure fair usage:
- Rate Limit: 1000 requests per hour per API token
- Burst Limit: 100 requests per minute
Rate limit headers are included in responses:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1693123456
When rate limited, you’ll receive a 429 Too Many Requests
response:
{
"error": "rate_limit_exceeded",
"message": "Too many requests. Try again in 60 seconds.",
"retry_after": 60
}
Pagination
List endpoints support pagination using offset-based parameters:
Parameter | Description |
---|---|
limit | Number of items to return (default varies by endpoint) |
offset | Number of items to skip |
Response includes pagination metadata:
{
"data": [...],
"pagination": {
"limit": 50,
"offset": 0,
"total": 250,
"has_more": true
}
}
Common Response Formats
Success Response
Successful requests return relevant data with 2xx status codes.
Error Response
Failed requests return error details:
{
"error": "validation_failed",
"message": "The webhook_url field is required.",
"details": {
"field": "webhook_url",
"code": "required"
}
}
Timestamps
All timestamps are in ISO 8601 format with UTC timezone:
2025-09-05T10:30:00Z
Next Steps: Learn about webhook configuration and error handling to build robust integrations.
Related Documentation
Last updated: September 5, 2025