Media Luna Media Luna Docs

Media Luna API

The Media Luna REST API gives you programmatic access to monitors, incidents, metrics, notification rules, status pages, and more. All API access is over HTTPS and all data is sent and received as JSON.

Base URL
https://api.media-luna.co/api/v1

🔐 Authentication

The Developer API uses API key authentication. Include your API key in the Authorization header as a Bearer token.

Authorization: Bearer sk_live_abc123def456...

API keys can be created from the dashboard under Settings → API Keys. Keys are prefixed with sk_ and are scoped to specific permissions:

Available Scopes
read:monitors
Read access to monitors and their configurations
write:monitors
Create and update monitors
delete:monitors
Delete monitors
read:incidents
Read access to incidents and their timelines
read:metrics
Read access to monitor metrics and time-series data
read:account
Read access to account details and usage
write:account
Update account settings
read:maintenance
Read access to maintenance windows
write:maintenance
Create, update, and delete maintenance windows

⏱️ Rate Limiting

API requests are rate-limited to ensure fair usage. Rate limit information is included in response headers.

Response Headers
X-RateLimit-Limit
Maximum requests allowed per window (varies by plan, see below)
X-RateLimit-Remaining
Remaining requests in the current window
X-RateLimit-Reset
Unix timestamp when the rate limit resets
Limits by Plan
Free
60 requests / minute
Starter
300 requests / minute
Pro
600 requests / minute
Enterprise
Unlimited (contact us)

⚠️ Errors

Media Luna uses conventional HTTP response codes. Codes in the 2xx range indicate success, 4xx indicate client errors, and 5xx indicate server errors.

Error Codes
200
OK — Request succeeded
201
Created — Resource was successfully created
204
No Content — Resource was successfully deleted
400
Bad Request — Invalid request parameters
401
Unauthorized — Invalid or missing API key
403
Forbidden — Insufficient permissions or scope
404
Not Found — Resource does not exist
422
Validation Error — Request body failed validation
429
Rate Limited — Too many requests
500
Internal Server Error — Something went wrong on our side

📄 Pagination

List endpoints support offset-based pagination using skip and limit query parameters. Responses are plain JSON arrays — there is no envelope or metadata wrapper.

Query Parameters
skipinteger
Number of records to skip (default: 0)
limitinteger
Maximum number of records to return (default: 100, max: 1000)

📡 Monitors

Monitors represent the endpoints you want to check. Each monitor has a type (HTTP, TCP, DNS, SMTP, SSH, PING, or PUSH), a target URL or host, check interval, and assigned probe regions. Monitors generate incidents when they detect failures.

GET /v1/monitors

List all monitors

🔑 API Key — read:monitors

Returns a paginated list of monitors for your account. Supports filtering by status, type, tags, and search queries.

Query Parameters
statusstring
Filter by monitor status
updownpausedpending
typestring
Filter by monitor type
HTTPTCPDNSSMTPSSHPINGPUSH
tagstring
Filter by tag name
searchstring
Search by monitor name or URL
skipinteger
Number of records to skip (default: 0)
limitinteger
Maximum number of records to return (default: 100, max: 1000)
Responses
200 Array of monitors
401 Invalid or missing API key
POST /v1/monitors

Create a monitor

🔑 API Key — write:monitors

Creates a new monitor with the given parameters. If no region_ids are specified, the first active region is auto-assigned.

Request Body — application/json
namerequiredstring
Display name for the monitor
typerequiredstring
Monitor type
HTTPHEADTCPDNSSMTPSSHPINGPUSH
urlrequiredstring
URL or hostname to monitor (e.g., https://example.com)
check_intervalinteger
Seconds between checks (default: 300). Minimum depends on your plan: Free=300, Starter=120, Pro=60, Enterprise=30
timeoutinteger
Request timeout in seconds (default: 30, max: 120)
region_idsarray[integer]
IDs of probe regions. Max regions depend on plan: Free=1, Starter=2, Pro=5, Enterprise=unlimited
confirm_from_locationsinteger
Number of probe regions that must confirm failure before incident (default: 1)
expected_status_codesarray[integer]
HTTP status codes considered successful (default: [200-299])
request_headersobject
Custom HTTP headers to send with each check
request_bodystring
HTTP request body (sets method to POST)
http_methodstring
HTTP method
GETPOSTPUTPATCHDELETEHEAD
follow_redirectsboolean
Whether to follow HTTP redirects (default: true)
verify_sslboolean
Verify SSL certificate validity (default: true)
ssl_expiry_reminderinteger
Days before SSL expiry to trigger a notification
portinteger
Port for TCP/SMTP/SSH checks
dns_record_typestring
DNS record type for DNS checks
AAAAACNAMEMXNSTXT
tag_idsarray[integer]
Tags to associate with the monitor
Responses
201 Monitor created successfully
400 Invalid parameters
403 Plan limit reached
422 Validation error
GET /v1/monitors/{monitor_id}

Retrieve a monitor

🔑 API Key — read:monitors

Returns a single monitor by ID, including current status, assigned regions, and tags.

Path Parameters
monitor_idrequiredinteger
The ID of the monitor to retrieve
Responses
200 Monitor details
404 Monitor not found
PUT /v1/monitors/{monitor_id}

Update a monitor

🔑 API Key — write:monitors

Updates a monitor's configuration. Only include the fields you want to change.

Path Parameters
monitor_idrequiredinteger
The ID of the monitor to update
Request Body — application/json
namestring
Updated display name
urlstring
Updated URL or hostname
check_intervalinteger
Updated check interval in seconds
region_idsarray[integer]
Updated list of probe region IDs
Responses
200 Updated monitor
404 Monitor not found
DELETE /v1/monitors/{monitor_id}

Delete a monitor

🔑 API Key — delete:monitors

Permanently deletes a monitor and all associated metrics, incidents, and check history.

Path Parameters
monitor_idrequiredinteger
The ID of the monitor to delete
Responses
204 Monitor deleted successfully
POST /api/monitors/{monitor_id}/pause

Pause a monitor

🔒 JWT — Editor+

Pauses monitoring and auto-resolves any active incidents for this monitor.

Responses
200Monitor paused
POST /api/monitors/{monitor_id}/resume

Resume a monitor

🔒 JWT — Editor+

Resumes monitoring for a previously paused monitor.

Responses
200Monitor resumed
GET /api/monitors/{monitor_id}/history

Get check history

🔒 JWT

Returns historical check results for a monitor, including response times, status codes, and regional data.

Query Parameters
hoursinteger
Number of hours of history to return (default: 24)
Responses
200List of check results
POST /api/monitors/bulk

Bulk operations

🔒 JWT — Editor+

Perform bulk operations on multiple monitors at once: delete, pause, resume, add or remove tags.

Request Body — application/json
actionrequiredstring
Operation to perform
deletepauseresumeadd_tagsremove_tags
monitor_idsrequiredarray[integer]
IDs of monitors to operate on
tag_idsarray[integer]
Tag IDs (required for add_tags / remove_tags actions)
Responses
200Operation result

💓 Push Monitors

Push monitors (also called heartbeat monitors) work in reverse: your service calls Media Luna on a schedule to confirm it's alive. If a ping isn't received within the expected interval plus grace period, an incident is created. Identify your monitor with its unique push_token, visible in the dashboard.

POST /api/push/{push_token}

Submit a heartbeat ping

🔓 Public — push token auth

Signals that your service is alive. Marks the monitor as UP and records a metric. No body required. Authentication is via the unique push_token embedded in the URL — do not share it publicly.

Path Parameters
push_tokenrequiredstring
The unique push token for the monitor (found in monitor settings)
Responses
200Heartbeat recorded — monitor marked UP
404Invalid push token
GET /api/push/{push_token}

Get heartbeat monitor status

🔓 Public — push token auth

Returns the current status of a push monitor. Useful for debugging your heartbeat integration.

Path Parameters
push_tokenrequiredstring
The unique push token for the monitor
Responses
200Monitor status details
404Invalid push token

🔥 Incidents

Incidents are automatically created when a monitor detects a failure. Each incident has a lifecycle: TRIGGERED → ACKNOWLEDGED → RESOLVED. Incidents include a timeline of events for post-mortem analysis.

GET /v1/incidents

List all incidents

🔑 API Key — read:incidents

Returns a list of incidents, optionally filtered by monitor, incident type, or time range.

Query Parameters
monitor_idinteger
Filter by monitor ID
incident_typestring
Filter by type
DOWNSSL_EXPIRYPERFORMANCE
start_datestring (ISO 8601)
Return incidents at or after this datetime
end_datestring (ISO 8601)
Return incidents at or before this datetime
skipinteger
Number of records to skip (default: 0)
limitinteger
Maximum number of records to return (default: 100, max: 1000)
Responses
200Array of incidents
GET /v1/incidents/{incident_id}

Retrieve an incident

🔑 API Key — read:incidents

Returns full incident details including the complete event timeline for post-mortem analysis.

Responses
200Incident with timeline
404Incident not found
GET /api/incidents/counts

Get incident counts

🔒 JWT

Returns efficient counts of incidents by type and status. Optimized for dashboard rendering.

Responses
200Incident count breakdown
POST /api/incidents/{incident_id}/acknowledge

Acknowledge an incident

🔒 JWT — Editor+

Marks an incident as acknowledged. This records an ACKNOWLEDGED event in the timeline and suppresses further notifications.

Request Body — application/json
messagestring
Optional acknowledgement message
Responses
200Incident acknowledged
POST /api/incidents/{incident_id}/snooze

Snooze an incident

🔒 JWT — Editor+

Temporarily snoozes notifications for an incident for a specified duration.

Request Body — application/json
duration_minutesrequiredinteger
Snooze duration in minutes (5–10080, i.e. up to 7 days)
reasonstring
Reason for snoozing
Responses
200Incident snoozed
POST /api/incidents/{incident_id}/timeline

Add timeline comment

🔒 JWT — Editor+

Adds a COMMENT event to the incident timeline. Useful for post-mortem notes and investigation tracking.

Request Body — application/json
messagerequiredstring
Comment text to add to the incident timeline
Responses
201Comment added to timeline

📋 Notification Rules

Notification rules control when and how you get alerted. Rules define conditions (status changes, response time thresholds, consecutive failures) and route notifications to specific channels.

GET /api/notification-rules

List notification rules

🔒 JWT

Returns all notification rules for your account.

Responses
200List of notification rules
POST /api/notification-rules

Create a notification rule

🔒 JWT — Editor+

Creates a new notification rule with specified conditions and channels.

Request Body — application/json
namerequiredstring
Display name for the rule
conditionsrequiredarray[object]
Array of conditions. Each condition has:
typestring
Condition type
STATUSRESPONSE_TIME
operatorstring
Comparison operator
eqgtltgtelte
valueany
Threshold value (ms for response time)
channel_idsrequiredarray[integer]
Notification channel IDs to route alerts to
monitor_idsarray[integer]
Specific monitors to apply rule to (empty = all monitors)
consecutive_checksinteger
Number of consecutive failures before triggering (default: 1)
enabledboolean
Whether the rule is active (default: true)
Responses
201Rule created
422Validation error
GET/api/notification-rules/{rule_id}

Get a notification rule

🔒 JWT

Returns a single notification rule by ID with all conditions and channels.

Responses
200Rule details
PATCH/api/notification-rules/{rule_id}

Update a notification rule

🔒 JWT — Editor+

Partially updates a notification rule. Only include fields you want to change.

Responses
200Updated rule
DELETE/api/notification-rules/{rule_id}

Delete a notification rule

🔒 JWT — Editor+

Permanently deletes a notification rule.

Responses
204Rule deleted

🔔 Notification Channels

Notification channels define how alerts are delivered — via email, Slack, PagerDuty, webhooks, SMS, or Telegram. Channels are referenced by notification rules.

GET/api/notification-channels

List notification channels

🔒 JWT

Returns all configured notification channels for your account.

Responses
200List of channels
POST/api/notification-channels

Create a notification channel

🔒 JWT — Editor+

Creates a new notification channel.

Request Body — application/json
namerequiredstring
Channel display name
channel_typerequiredstring
Channel type
EMAILSMSSLACKPAGERDUTYWEBHOOKTELEGRAM
email_recipientstring
Email address (required for EMAIL type)
slack_webhook_urlstring
Slack incoming webhook URL (required for SLACK type)
webhook_urlstring
Webhook endpoint URL (required for WEBHOOK type)
telegram_bot_tokenstring
Telegram bot token (required for TELEGRAM type)
telegram_chat_idstring
Telegram chat ID (required for TELEGRAM type)
Responses
201Channel created
POST/api/notification-channels/{channel_id}/test

Test a notification channel

🔒 JWT — Editor+

Sends a test notification through the channel to verify it's configured correctly.

Responses
200Test notification sent

📊 Metrics

Access detailed performance metrics for your monitors including response times, uptime percentages, and time-series data broken down by probe region.

GET/v1/metrics/monitors/{monitor_id}

Get monitor metrics

🔑 API Key — read:metrics

Returns aggregated metrics for a specific monitor over a given time range.

Query Parameters
start_timestring (ISO 8601)
Start of the time range (default: 24 hours ago)
end_timestring (ISO 8601)
End of the time range (default: now)
Responses
200Metrics data
GET/api/metrics/{monitor_id}/summary

Get metrics summary

🔒 JWT

Returns aggregated metrics summary including average response time, uptime %, and p95 latency.

Responses
200Aggregated summary
GET/api/metrics/{monitor_id}/timeseries

Get time-series data

🔒 JWT

Returns time-bucketed metrics data for charting. Specify bucket size for the desired granularity.

Query Parameters
hoursinteger
Time window (default: 24)
bucket_minutesinteger
Bucket size in minutes (default: 5)
Responses
200Time-bucketed data points
GET/api/metrics/overview

Account metrics overview

🔒 JWT

Returns a high-level overview of all monitors' health across your entire account.

Responses
200Account-wide metrics

🌍 Regions

Probe regions represent geographic locations where health checks are executed. Monitors are assigned to one or more regions. Regions are dynamic — new probes register on deployment.

GET/api/regions/public

List probe regions

🔓 Public

Returns all active probe regions. No authentication required.

Responses
200List of active regions with code, name, lat/lng
GET/api/regions/monitors/{monitor_id}/latency

Get per-region latency

🔒 JWT

Returns latency breakdown by region for a specific monitor. Useful for geographic performance analysis.

Query Parameters
hoursinteger
Time window (default: 24)
Responses
200Per-region latency data

📃 Status Pages

Public-facing status pages let your users see the health of your services. Each page gets a unique subdomain and can display selected monitors.

GET/api/status-pages

List status pages

🔒 JWT

Returns all status pages for your account.

Responses
200List of status pages
POST/api/status-pages

Create a status page

🔒 JWT — Editor+

Creates a new public status page.

Request Body — application/json
titlerequiredstring
Status page title
subdomainrequiredstring
Unique subdomain (e.g., "myapp" → myapp.media-luna.co)
monitor_idsarray[integer]
Monitors to display on the page
custom_cssstring
Custom CSS for branding
logo_urlstring
Logo URL for the status page
Responses
201Status page created

🔧 Maintenance Windows

Schedule maintenance windows to suppress incident creation and notifications during planned maintenance periods.

GET/api/maintenance-windows

List maintenance windows

🔒 JWT 🔑 API Key — read:maintenance

Returns all maintenance windows for your account. Use ?active_only=true to filter to enabled windows only.

Query Parameters
active_onlyboolean
Only return enabled windows. Default: false
Responses
200List of maintenance windows
GET/api/maintenance-windows/active

Get active maintenance windows

🔒 JWT 🔑 API Key — read:maintenance

Returns maintenance windows that are currently in effect — enabled and the current time is between start_time and end_time.

Responses
200List of currently active maintenance windows
GET/api/maintenance-windows/{id}

Get a maintenance window

🔒 JWT 🔑 API Key — read:maintenance

Returns detailed information about a specific maintenance window.

Responses
200Maintenance window details
404Maintenance window not found
POST/api/maintenance-windows

Create a maintenance window

🔒 JWT — Editor+ 🔑 API Key — write:maintenance

Creates a scheduled maintenance window. During active windows, incident creation and notifications are suppressed for affected monitors.

Request Body — application/json
namerequiredstring
Name for the maintenance window (1–200 chars)
start_timerequiredstring (ISO 8601)
When the maintenance window starts
end_timerequiredstring (ISO 8601)
When the maintenance window ends (must be after start_time)
applies_to_all_monitorsboolean
Apply to all monitors. Default: false
monitor_idsarray[integer]
Specific monitor IDs to affect (ignored if applies_to_all_monitors is true)
is_recurringboolean
Enable recurrence. Default: false
recurrence_patternstring
Recurrence pattern
dailyweeklymonthly
recurrence_daysstring
Comma-separated days for weekly recurrence (0=Sunday, 6=Saturday)
recurrence_end_datestring (ISO 8601)
When recurrence stops (optional)
is_activeboolean
Enable/disable the window. Default: true
Responses
201Maintenance window created
PUT/api/maintenance-windows/{id}

Update a maintenance window

🔒 JWT — Editor+ 🔑 API Key — write:maintenance

Update a maintenance window. Partial update — only include fields to change.

Responses
200Updated maintenance window
404Maintenance window not found
DEL/api/maintenance-windows/{id}

Delete a maintenance window

🔒 JWT — Editor+ 🔑 API Key — write:maintenance

Permanently delete a maintenance window.

Responses
204Maintenance window deleted
POST/api/maintenance-windows/{id}/toggle

Toggle maintenance window

🔒 JWT — Editor+ 🔑 API Key — write:maintenance

Toggle a maintenance window between enabled and disabled without a full update.

Responses
200Updated maintenance window

Maintenance Window Response Object

Fields
idinteger
Unique window ID
namestring
Window name
descriptionstring | null
Optional description
start_timedatetime
Window start (ISO 8601)
end_timedatetime
Window end (ISO 8601)
is_recurringboolean
Whether the window repeats
recurrence_patternstring | null
daily, weekly, or monthly
recurrence_daysstring | null
Days for weekly recurrence (0=Sun, 6=Sat)
applies_to_all_monitorsboolean
Whether all monitors are affected
monitor_idsarray[integer]
Specific monitor IDs affected by this window
is_activeboolean
Whether the window is enabled
created_atdatetime
Creation timestamp
updated_atdatetime
Last update timestamp

👥 Account & Users

Manage your account settings, team members, and API keys. Users have roles: Admin (full access), Editor (manage monitors & incidents), and Viewer (read-only).

GET/v1/account

Get account info

🔑 API Key — read:account

Returns account details including plan, usage, and settings.

Responses
200Account information
GET/api/accounts/users

List team members

🔒 JWT

Returns all users in your account with their roles.

Responses
200List of users
POST/api/accounts/users/invite

Invite a team member

🔒 JWT — Admin

Sends an invitation email to a new team member.

Request Body — application/json
emailrequiredstring
Email address of the person to invite
rolerequiredstring
Role to assign
ADMINEDITORVIEWER
Responses
200Invitation sent
POST/api/users/api-keys

Create an API key

🔒 JWT

Creates a new API key. The unhashed key is returned only once in the response — store it securely.

Request Body — application/json
namerequiredstring
Descriptive name for the key
scopesrequiredarray[string]
Permission scopes
read:monitorswrite:monitorsdelete:monitorsread:incidentsread:metricsread:accountwrite:accountread:maintenancewrite:maintenance
expires_atstring (ISO 8601)
Optional expiration date (null = never expires)
Responses
201API key created (includes unhashed key)

💳 Billing & Plans

Manage subscriptions, view plan details, and check usage limits. Billing is powered by Stripe.

GET/api/plans

List available plans

🔓 Public

Returns all available subscription plans with features and limits.

Responses
200List of plans
GET/api/billing/subscription

Get current subscription

🔒 JWT

Returns current subscription status, plan, and billing cycle details.

Responses
200Subscription details
GET/api/billing/usage

Get usage & limits

🔒 JWT

Returns current resource usage compared to plan limits (monitors, users, regions, etc.).

Responses
200Usage and limits breakdown

🔗 Webhooks

Outbound webhooks let Media Luna push real-time events to your own systems. Configure a webhook channel (see Notification Channels) and it will receive HTTP POST requests whenever a notification rule fires.

Event Types

Each webhook payload includes an event field identifying the type of event:

Events
incident.triggered
A monitor went DOWN or a threshold was breached
incident.acknowledged
An incident was acknowledged by a team member
incident.resolved
A monitor recovered and the incident was resolved
monitor.recovered
Monitor status changed from DOWN to UP

Payload Format

Webhook payloads are sent as HTTP POST with Content-Type: application/json. Your endpoint must respond with a 2xx status within 10 seconds.

Payload Fields
eventstring
Event type (see above)
occurred_atstring (ISO 8601)
When the event occurred
monitorobject
Monitor snapshot: id, name, url, type
incidentobject
Incident snapshot: id, incident_type, message, status, sent_at
account_idinteger
Your account ID

Verification

To verify that a webhook request originated from Media Luna, compare the incoming payload against a known-good test notification sent from the dashboard (Notification Channels → Test). In a future release, webhook signatures will be added via an X-Media-Luna-Signature header.

Retry Policy
2xxDelivery confirmed — no retry
4xx / 5xxDelivery failed — retried up to 3 times with exponential backoff