API Overview
The Hoppla REST API lets you programmatically manage monitors, read check results, handle incidents, and automate your monitoring setup. Everything you can do in the dashboard is available through the API.
Base URL
All API endpoints are served from:
https://app.hoppla.dev/api/v1Authentication
Authenticate using a Bearer token in the Authorization header. See API Tokens for how to create one.
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://app.hoppla.dev/api/v1/monitorsTokens are opaque strings with a short prefix that indicates their type — personal API tokens start with sk-…. Treat the whole string as a secret and never embed it in client-side code.
All requests without a valid token receive a 401 Unauthorized response.
Scopes
Every token carries a set of scopes that determine what it can do. Scopes use a resource:action format, grouped into families:
monitors,checks,incidents,notifications,escalation,status-pages,maintenance,team,settings,billing
Each family supports :read, :write, and (where applicable) :manage. For example, a token with monitors:read can list monitors but not create them; monitors:write allows creating and updating.
A token usually holds only a subset of all scopes — pick the minimum your integration needs. Any request that targets an endpoint outside the token's scopes is rejected with 403 Forbidden.
Pagination
Hoppla uses two pagination styles depending on the endpoint.
Offset pagination
Most list endpoints page by number. Control them with query parameters:
| Parameter | Default | Description |
|---|---|---|
page | 1 | Page number |
per_page | 15 | Items per page (max 100) |
Responses include a meta object:
{
"data": [...],
"meta": {
"current_page": 1,
"last_page": 3,
"per_page": 15,
"total": 42
}
}Cursor pagination
High-volume endpoints (for example, incidents) use cursor pagination instead, which is faster and stable while data changes. Pass the cursor returned by the previous response:
| Parameter | Description |
|---|---|
cursor | Opaque cursor from the previous page's meta.next_cursor |
per_page | Items per page (max 100) |
Responses include cursor info in meta:
{
"data": [...],
"meta": {
"next_cursor": "eyJpZCI6...",
"prev_cursor": null,
"has_more": true
}
}Keep requesting with next_cursor until has_more is false.
Rate Limiting
Rate limits depend on how the request is authenticated:
| Request | Limit |
|---|---|
| Unauthenticated (per IP) | 60 requests/minute |
| Authenticated | 300 requests/minute |
Authenticated with a tenant-scoping header (X-Tenant) | 600 requests/minute |
Rate limit information is included in every response:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per minute |
X-RateLimit-Remaining | Requests remaining in current window |
When the limit is exceeded, the API returns 429 Too Many Requests. Wait for the window to reset before retrying.
Error Format
All errors return JSON with a consistent structure:
{
"message": "The given data was invalid.",
"errors": {
"url": ["The url field is required."]
}
}Common HTTP status codes:
| Status | Meaning |
|---|---|
200 | Success |
201 | Resource created |
204 | Success, no content (deletes) |
401 | Unauthorized (invalid or missing token) |
403 | Forbidden (insufficient permissions) |
404 | Resource not found |
422 | Validation error |
429 | Rate limit exceeded |
500 | Server error |
Available Endpoints
| Category | Endpoints | Description |
|---|---|---|
| Monitors | GET/POST/PATCH/DELETE /monitors | Create, read, update, delete monitors |
| Monitor Tags | GET /monitors/tags | List all tags used across monitors |
| Monitor Checks | GET/POST/DELETE /monitors/{id}/checks | Manage checks within a monitor |
| Check Actions | PATCH /checks/{id}, POST /checks/{id}/request-run, POST /checks/{id}/snooze, POST /checks/{id}/unsnooze, POST /checks/{id}/enable, POST /checks/{id}/disable | Update settings, trigger manual runs, snooze/unsnooze, enable/disable individual checks |
| Check Results | GET /checks/{id}/results, GET /checks/{id}/timeseries, POST /checks/timeseries-batch | Read check results, time-series data, and batch timeseries |
| Monitor Statistics | GET /monitors/{id}/uptime, /performance, /certificate, /dns-history, /lighthouse, /domain-expiry, /health, /sitemap, /ping, /tcp, /security-headers, /robots-txt, /dnsbl, /redirect-chain, /mixed-content, /broken-links, /agent | Detailed stats per monitor and check type |
| Crawl Runs | GET /monitors/{id}/crawl-runs, GET /monitors/{id}/crawl-runs/{runId}, GET /monitors/{id}/crawl-runs/{runId}/pages | Broken link scan results and affected pages |
| Incidents | GET/POST/PATCH/DELETE /incidents, POST /incidents/{id}/updates, POST /incidents/{id}/acknowledge, POST /incidents/{id}/snooze, POST /incidents/{id}/unsnooze, POST /incidents/{id}/archive, POST /incidents/{id}/unarchive | Full incident lifecycle management |
| Notification Channels | GET/POST/PATCH/DELETE /notification-channels, POST /notification-channels/{id}/test | Manage notification channels and test delivery |
| Notification Rules | GET/POST/PATCH/DELETE /notification-rules | Configure which events trigger which channels |
| Notification Logs | GET /notification-logs, GET /notification-logs/{id} | View notification delivery history |
| Escalation Policies | GET/POST/PATCH/DELETE /escalation-policies, step management | Multi-step escalation chains with wait times |
| On-Call Schedules | GET/POST/PATCH/DELETE /on-call-schedules, rotation management, GET /on-call-schedules/{id}/current | Rotation-based on-call scheduling |
| Maintenance Windows | GET/POST/PATCH/DELETE /maintenance-windows | Schedule planned downtime to suppress alerts |
| Status Pages | GET/POST/PATCH/DELETE /status-pages, updates management, custom domain verification, search_indexing | Public status pages with custom domains and per-page search-engine indexing |
| Migration (import) | GET /public/migration-sources, GET/POST /migrations, GET /migrations/{id}, POST /migrations/{id}/import, GET /migrations/{id}/resources | Import monitors from Oh Dear, Uptime Robot, Better Stack and Pingdom |
| Migration (shadow & switch) | POST /migrations/{id}/shadow, POST /migrations/{id}/shadow/stop, GET /migrations/{id}/divergences, POST /migrations/{id}/divergences/{divergenceId}/acknowledge, GET /migrations/{id}/cutover-readiness, POST /migrations/{id}/cutover, POST /migrations/{id}/rollback | Run imported monitors alongside the old tool, compare, then switch over |
| Cron Monitors | GET/POST/PATCH/DELETE /cron-monitors, POST /cron-monitors/{id}/rotate-url | Cron heartbeat monitors with URL rotation |
| Agent Monitors | GET/POST/PATCH/DELETE /agent-monitors, POST /agent-monitors/{id}/rotate-token, GET /agent-monitors/{id}/metrics | Server agent monitors with token rotation and metrics |
| Dashboard | GET /dashboard/stats | Aggregate monitoring statistics |
| Profile | GET/PATCH /profile, PUT /profile/password, GET /profile/export, DELETE /profile | User profile, password change, GDPR export, account deletion |
| API Tokens | GET/POST/DELETE /api-tokens | Manage personal API tokens |
| Team Members | GET /team/members, PATCH /team/members/{id}, DELETE /team/members/{id} | Team member management |
| Team Invitations | GET/POST /team/invitations, POST /team/invitations/{id}/resend, DELETE /team/invitations/{id} | Invite and manage team invitations |
| Branding | GET/PATCH /branding | White-label branding settings |
| Custom SMTP | GET/PATCH/DELETE /smtp-config, POST /smtp-config/test | Custom SMTP configuration for emails |
| SSO Configuration | GET/PATCH /sso/config | OIDC SSO settings |
| Audit Log | GET /audit-log, GET /audit-log/filters | View tenant audit trail and available filter values |
| Badges | GET /badges/{uuid}, GET /badges/{uuid}/small | Public SVG uptime badges (no auth required) |
| Monthly Reports | GET/PATCH /monthly-report/config, POST /monthly-report/preview | Monthly report configuration and preview |
| Plan | GET /plan | Current plan limits and usage |
| Billing | GET /billing, POST /billing/checkout, POST /billing/swap, POST /billing/cancel, POST /billing/resume, GET /billing/transactions | Subscription management |
Rate Limits by Operation Type
Read operations (GET) share your account's standard limit. Write operations (POST/PATCH/DELETE) and check-triggering endpoints (e.g., request-run) may have lower limits. Rate limit headers in each response always reflect the applicable limit for that endpoint.
Badges (Public)
Embeddable SVG badges show a monitor's live uptime status. These endpoints are public — no authentication required. Badges only reflect the uptime check status (not GEO, security headers, etc.).
Default Badge
GET /api/badges/{monitor_uuid}Returns a shields.io-style SVG badge with label ("uptime") and value (percentage or "down").
Small Badge
GET /api/badges/{monitor_uuid}/smallReturns a compact SVG with a colored dot and percentage text.
Query Parameters
| Parameter | Default | Description |
|---|---|---|
label_color | 555 | Hex color for the label background (e.g., 2d333b for dark mode) |
text_color | fff | Hex color for badge text |
style | default | Badge style: default (gradient) or flat |
Example
<!-- Light mode -->
<img src="https://app.hoppla.dev/api/badges/YOUR-MONITOR-UUID" alt="Uptime">
<!-- Dark mode -->
<img src="https://app.hoppla.dev/api/badges/YOUR-MONITOR-UUID?label_color=2d333b&style=flat" alt="Uptime">Caching
Badges are cached at the CDN level (5 minutes) and browser level (1 minute). Rate limited to 120 requests/minute per IP.
Audit Log
List Audit Events
GET /api/v1/audit-logReturns a paginated list of audit log entries for the current tenant.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
action | string | Filter by action(s). Comma-separated for multiple (e.g., check_snoozed,check_unsnoozed) |
entity_type | string | Filter by entity type. One of: monitor, check, notification_channel, notification_rule, status_page, maintenance_window, incident, user, tenant, managed_tenant, personal_access_token, team_invitation, escalation_policy, escalation_step, on_call_schedule, on_call_rotation |
entity_id | uuid | Filter by specific entity ID |
user_id | uuid | Filter by user who performed the action |
Get Available Filters
GET /api/v1/audit-log/filtersReturns distinct actions and entity_types that exist in your tenant's audit log — useful for building dynamic filter dropdowns.
Response (200):
{
"data": {
"actions": ["check_snoozed", "check_unsnoozed", "monitor_created", "..."],
"entity_types": ["check", "monitor", "incident", "..."]
}
}Check Snooze / Unsnooze
Snooze a Check
POST /api/v1/checks/{id}/snoozeSuppresses notifications for the check for the specified duration.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
minutes | integer | yes | Duration in minutes (1–1440) |
Unsnooze a Check
POST /api/v1/checks/{id}/unsnoozeImmediately removes the snooze from a check, re-enabling notifications.
Response (200): Returns the updated check resource.
OpenAPI Specification
Browse the full, interactive API reference — API Reference — or grab the machine-readable OpenAPI 3.1 spec:
- Interactive reference: docs.hoppla.dev/api/reference
- Download the spec: api-documentation.json
- Live spec (Hoppla Cloud):
https://app.hoppla.dev/api/v1/openapi.json
Import the spec into Postman, Insomnia, or any OpenAPI-compatible tool to explore and test endpoints interactively.
Self-hosted
On a self-hosted instance, both are served from your own domain (no external dependencies):
- Interactive reference:
https://<your-domain>/api/docs - OpenAPI spec:
https://<your-domain>/api/v1/openapi.json
The spec's servers URL is set automatically to your instance's own base URL.
MCP Server (AI Integration)
Connect AI assistants like Claude Desktop, Claude Code, or Cursor directly to your Hoppla data using the Model Context Protocol. Query monitors, incidents, uptime stats, and more through natural language conversations. See the MCP Server documentation for setup instructions.
Reseller API
If you are a hosting provider or agency managing customer teams, the Reseller API provides additional endpoints for provisioning and managing teams programmatically. See the Reseller API Reference for details.