API Reference

MERU Documentation - API

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

ParameterTypeRequiredDescription
webhook_urlstringYesHTTPS URL to receive webhooks
is_permanentbooleanNoWhether address never expires (default: true)
ttl_hoursintegerNoHours until expiration (if not permanent)
descriptionstringNoOptional 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

ParameterTypeDescription
limitintegerNumber of results (max 100, default 50)
offsetintegerNumber of results to skip
is_enabledbooleanFilter by enabled status
is_permanentbooleanFilter 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

ParameterTypeDescription
webhook_urlstringNew webhook URL
is_enabledbooleanEnable or disable the address
descriptionstringUpdate 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

ParameterTypeDescription
limitintegerNumber of events (max 1000, default 100)
offsetintegerNumber of events to skip
start_datestringISO 8601 start date filter
end_datestringISO 8601 end date filter
event_typestringFilter 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

ParameterTypeDescription
limitintegerNumber of invoices (max 100, default 12)
offsetintegerNumber 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

ParameterTypeRequiredDescription
namestringYesDescriptive name for the token
permissionsarrayNoList 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:

ParameterDescription
limitNumber of items to return (default varies by endpoint)
offsetNumber 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.

Last updated: September 5, 2025