Documentation

Docs / API

API reference

Query third-party service status programmatically. No authentication required for public endpoints.

Overview

The StatusDrop API provides read-only access to service status data. All responses are JSON (except RSS feed and CSV export). All endpoints support CORS for browser-based access.

Base URL: https://statusdrop.dev

Rate Limits: 120 requests per minute per IP per stack. Exceeding the limit returns HTTP 429 with a Retry-After header.

Caching: Status endpoints are cached for 30 seconds at the edge. Widget data is cached for 60 seconds. The last_updated field indicates when data was last refreshed.

Stack ID: All endpoints use the stack ID as the identifier. This is the same value from your embed code data-stack attribute (a Convex document ID like js7ey5magretd3kfxhzaen3c7n82pgph).

Is it down? API (no key)

The live status of every service in the StatusDrop catalog, the same data as the Is it down? pages. No API key, no signup. Built for scripts, dashboards and AI agents.

  • Shortcuts: /status.json and /status.md list every service; /status/{slug}.json and /status/{slug}.md answer for one. They take the same filters and ?history=1 as the /api/v1/services routes below, with the format fixed by the extension.
  • Markdown: send Accept: text/markdown (or add ?format=md) to the /api/v1/services routes; JSON is the default. A plain GET /status/{slug} with that header also returns Markdown instead of the HTML page.
  • CORS: open to every origin (GET, HEAD, OPTIONS). Rate limit and caching headers are exposed to browsers.
  • Caching: Cache-Control: public, max-age=30, s-maxage=60, stale-while-revalidate=120. Every response has an ETag (send If-None-Match for a 304) and Last-Modified. Services are checked every 5 minutes, so polling faster than once a minute gains nothing.
  • Rate limit: 120 requests per minute per IP, reported in X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Over the limit returns 429 with Retry-After: 60. Errors are never cached.
  • is_down: true for partial or major outage, false for operational or degraded, null when the status is unknown.
GET/api/v1/servicesNo key

List every monitored service

Current status of all 550+ services StatusDrop watches, with counts by status and a one-sentence summary. Also served at /status.json (always JSON) and /status.md (always Markdown).

Parameters

statusqueryComma list of operational, degraded, partial_outage, major_outage, unknown. Use issues for every service that is degraded or in an outage.
categoryqueryOne of payments, cloud, cdn, email, devtools, analytics, auth, database, messaging, monitoring, ai, storage, other. Anything else returns 400 with the allowed list.
qqueryCase-insensitive match on name, slug or domain (first 100 characters).
limitqueryPage size, 1 to 1000. Omit to return every match.
offsetqueryNumber of matches to skip. Default 0.
formatqueryjson or md. Overrides the Accept header.

Response

{
  "generated_at": "2026-10-30T06:44:56.473Z",
  "latest_check_at": "2026-10-30T06:42:59.636Z",
  "summary": "8 of 565 monitored services have an outage and 34 are degraded right now.",
  "counts": {
    "operational": 484,
    "degraded": 34,
    "partial_outage": 8,
    "major_outage": 0,
    "unknown": 39
  },
  "total": 42,
  "count": 2,
  "offset": 0,
  "limit": 2,
  "services": [
    {
      "slug": "adyen",
      "name": "Adyen",
      "category": "payments",
      "status": "degraded",
      "status_label": "Degraded",
      "is_down": false,
      "as_of": "2026-10-30T06:42:10.118Z",
      "url": "https://statusdrop.dev/status/adyen",
      "api_url": "https://statusdrop.dev/api/v1/services/adyen"
    }
  ]
}
GET/api/v1/services/{slug}No key

Is one service down?

Current status of one service with an answer-first summary, the active incident, 90-day uptime and recent incidents. Append .md to the slug for Markdown. Also served at /status/{slug}.json and /status/{slug}.md. The response carries Link headers to the HTML page and the Markdown version.

Parameters

slugpathService slug as used in /status/{slug}, for example stripe or aws. Unknown slugs return 404 with a hint.
historyquerySet to 1 to add a daily array: 90 days of uptime_percent and worst_status per UTC day.
formatqueryjson or md. Overrides the Accept header (a .json or .md suffix overrides both).

Response

{
  "slug": "stripe",
  "name": "Stripe",
  "category": "payments",
  "category_label": "Payments",
  "domain": "stripe.com",
  "status": "operational",
  "status_label": "Operational",
  "is_down": false,
  "summary": "Stripe is operational (not down) as of 2026-10-30T06:42:59.636Z.",
  "as_of": "2026-10-30T06:42:59.636Z",
  "active_incident": null,
  "uptime_90d": { "percent": 100, "days_with_data": 90 },
  "recent_incidents": [],
  "check_interval_minutes": 5,
  "official_status_url": "https://status.stripe.com",
  "source": "StatusDrop reads the service's official status page and records its overall status.",
  "url": "https://statusdrop.dev/status/stripe",
  "api_url": "https://statusdrop.dev/api/v1/services/stripe",
  "markdown_url": "https://statusdrop.dev/status/stripe.md",
  "generated_at": "2026-10-30T06:44:51.369Z"
}

Examples

# Is Stripe down right now?
curl https://statusdrop.dev/status/stripe.json

# Same answer as Markdown, with 90 days of daily uptime
curl -H "Accept: text/markdown" "https://statusdrop.dev/api/v1/services/stripe?history=1"

# Every payments service with a problem right now
curl "https://statusdrop.dev/status.json?status=issues&category=payments"

# Search and page through the catalog
curl "https://statusdrop.dev/api/v1/services?q=cloud&limit=20&offset=20"

For AI agents

StatusDrop is designed to be machine-readable. When an AI agent visits a client site that uses StatusDrop:

  1. Look for the StatusDrop widget script tag: <script src="https://statusdrop.dev/widget.js" data-stack="STACK_ID">
  2. Extract the data-stack attribute to get the stack ID
  3. Call GET /api/v1/status/{id} to get current status
  4. Read the status_summary field for a human-readable description
  5. Use _links for navigating to related endpoints (HATEOAS)

To check any public service without a stack ID, call the Is it down? API, for example GET /status/stripe.json, or ask for Markdown with Accept: text/markdown.

StatusDrop also provides /llms.txt and /llms-full.txt files following the llmstxt.org standard, plus JSON-LD structured data (schema.org) on all status pages for discovery by crawlers and agents.

Status values

All status fields use one of these normalized values:

ValueDescriptionColor
operationalService is running normallyGreen
degradedService is experiencing minor issuesYellow
partial_outageSome components are affectedOrange
major_outageService is significantly impactedRed
unknownStatus could not be determinedGray

Endpoints

GET/api/v1/status/{id}

Get Stack Status

Returns the current status of all third-party services in a stack, including an AI-friendly summary, overall status, recent incidents, and HATEOAS navigation links. Responses are cached for 30 seconds.

Parameters

idpathThe stack ID (from your embed code data-stack attribute)

Response

{
  "stack_id": "js7ey5magretd3kfxhzaen3c7n82pgph",
  "stack_name": "My SaaS",
  "overall_status": "operational",
  "status_summary": "All 5 third-party services are running normally.",
  "status_header_text": "All Dependencies Online",
  "operational_count": 5,
  "total_services": 5,
  "services": [
    {
      "name": "Stripe",
      "domain": "stripe.com",
      "status": "operational",
      "last_checked": "2026-03-07T12:00:00Z",
      "status_page_url": "https://status.stripe.com"
    }
  ],
  "recent_incidents": [
    {
      "service": "AWS",
      "status": "degraded",
      "timestamp": "2026-03-07T10:30:00Z"
    }
  ],
  "status_page_url": "https://statusdrop.dev/s/js7ey5magretd3kfxhzaen3c7n82pgph",
  "last_updated": "2026-03-07T12:05:00Z",
  "_links": {
    "self": "https://statusdrop.dev/api/v1/status/js7ey5magretd3kfxhzaen3c7n82pgph",
    "services": "https://statusdrop.dev/api/v1/status/js7ey5magretd3kfxhzaen3c7n82pgph/services",
    "history": "https://statusdrop.dev/api/v1/status/js7ey5magretd3kfxhzaen3c7n82pgph/history",
    "openapi": "https://statusdrop.dev/api/v1/openapi"
  }
}
GET/api/v1/status/{id}/services

Get Detailed Services

Returns a detailed list of all visible services in a stack with check times, display order, and status page URLs.

Parameters

idpathThe stack ID (from your embed code data-stack attribute)

Response

{
  "stack_id": "js7ey5magretd3kfxhzaen3c7n82pgph",
  "stack_name": "My SaaS",
  "total": 5,
  "services": [
    {
      "name": "Stripe",
      "domain": "stripe.com",
      "status": "operational",
      "status_page_url": "https://status.stripe.com",
      "last_checked": "2026-03-07T12:00:00Z",
      "order": 0
    }
  ]
}
GET/api/v1/status/{id}/history

Get Status History

Returns status change events for a stack over a specified time period. Supports JSON and CSV export. Useful for tracking incidents and calculating uptime.

Parameters

idpathThe stack ID (from your embed code data-stack attribute)
daysqueryNumber of days of history (1-30, default: 7)
formatqueryResponse format: "json" (default) or "csv" (downloads a CSV file)

Response

{
  "stack_id": "js7ey5magretd3kfxhzaen3c7n82pgph",
  "stack_name": "My SaaS",
  "period_days": 7,
  "total_events": 3,
  "events": [
    {
      "service": "AWS",
      "domain": "aws.amazon.com",
      "old_status": "operational",
      "status": "degraded",
      "timestamp": "2026-03-01T14:30:00Z"
    }
  ]
}
GET/api/v1/status/{id}/feed

RSS Feed

Returns an RSS 2.0 feed of status change events for a stack. Subscribe in any RSS reader to track incidents. Each item includes the service name, old status, new status, and timestamp.

Parameters

idpathThe stack ID (from your embed code data-stack attribute)

Response

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="...">
  <channel>
    <title>My SaaS - Service Status</title>
    <item>
      <title>AWS: Operational → Degraded</title>
      <description>AWS status changed from Operational to Degraded</description>
      <pubDate>Sat, 01 Mar 2026 14:30:00 GMT</pubDate>
    </item>
  </channel>
</rss>
GET/api/v1/status/{id}/llms

AI-Readable Status (llms.txt)

Returns a plain-text, llms.txt-style description of the stack's current status, written for AI models and agents. Point your AI assistant here for machine-readable status context.

Parameters

idpathThe stack ID (from your embed code data-stack attribute)

Response

# My SaaS - Service Status

> Live third-party dependency status for My SaaS.

## Current Status
All 5 services operational.

- Stripe: operational
- AWS: operational
...
GET/api/widget/{id}

Widget Data

Returns widget configuration and service statuses optimized for the embeddable widget. Can also be used for custom integrations. Cached for 60 seconds.

Parameters

idpathThe stack ID (same as data-stack attribute in embed code)

Response

{
  "stackName": "My SaaS",
  "slug": "my-saas",
  "services": [
    {
      "name": "Stripe",
      "domain": "stripe.com",
      "status": "operational",
      "faviconUrl": "...",
      "showLogo": true,
      "isClickable": true
    }
  ],
  "config": {
    "template": "minimal-dot",
    "theme": "light",
    "showStatusPageLink": true,
    "showBranding": true
  },
  "statusPageUrl": "https://statusdrop.dev/s/...",
  "lastUpdated": "2026-03-07T12:00:00Z"
}
GET/api/v1/health

Health Check

Returns the API health status. Use this for uptime monitoring of the StatusDrop API itself.

Response

{
  "status": "ok",
  "version": "1.0",
  "service": "StatusDrop API",
  "timestamp": "2026-03-07T12:00:00Z"
}
GET/api/v1/openapi

OpenAPI Specification

Returns the OpenAPI 3.1.0 specification for all v1 endpoints. Use this to auto-generate client libraries or integrate with API tools like Postman.

Response

{ "openapi": "3.1.0", "info": { ... }, "paths": { ... } }

Authenticated API

Subscribers get one API key per account to manage stacks, services, and catalog publishing programmatically. Generate your key in Settings on the dashboard. Keys are SHA-256 hashed before storage and shown only once at creation.

Authentication: Authorization: Bearer sd_live_your_key_here

If your subscription is canceled, your API key is automatically revoked and all authenticated endpoints will return 401.

GET/api/v1/stacksAuth Required

List Stacks

Returns all stacks owned by the API key holder with service counts and overall status.

Response

[
  {
    "_id": "js7ey5magretd3kfxhzaen3c7n82pgph",
    "name": "My SaaS",
    "slug": "my-saas",
    "overall_status": "operational",
    "service_count": 5,
    "is_published": true,
    "createdAt": 1709827200000
  }
]
POST/api/v1/stacksAuth Required

Create Stack

Creates a new monitoring stack. Returns the new stack ID.

Parameters

namebodyStack name (required, max 200 chars)

Response

{
  "id": "new_stack_id",
  "slug": "my-saas"
}
PATCH/api/v1/stacks/{id}Auth Required

Update Stack

Update stack settings. All fields are optional.

Parameters

idpathStack ID
namebodyNew stack name
status_page_enabledbodyEnable/disable status page
status_header_textbodyCustom header text for the status page

Response

{ "success": true }
DELETE/api/v1/stacks/{id}Auth Required

Delete Stack

Permanently deletes a stack, all services, status checks, and catalog entries.

Parameters

idpathStack ID

Response

{ "success": true }
POST/api/v1/stacks/{id}/servicesAuth Required

Add Service

Add a service from catalog (provide catalog_service_id) or a custom URL service (provide name + status_page_url).

Parameters

idpathStack ID
catalog_service_idbodyAdd from catalog (mutually exclusive with name/url)
namebodyCustom service name
status_page_urlbodyCustom status page URL

Response

{ "id": "service_id" }
DELETE/api/v1/stacks/{id}/services?service_id=...Auth Required

Remove Service

Remove a service from a stack by its service ID.

Parameters

idpathStack ID
service_idqueryService ID to remove

Response

{ "success": true }
POST/api/v1/stacks/{id}/publishAuth Required

Publish to Catalog

Publishes your stack to the StatusDrop service catalog. Other users can then add your service as a monitored dependency.

Parameters

idpathStack ID

Response

{ "success": true, "catalog_slug": "sd-my-saas" }
DELETE/api/v1/stacks/{id}/publishAuth Required

Unpublish from Catalog

Removes your stack from the service catalog.

Parameters

idpathStack ID

Response

{ "success": true }
GET/api/v1/catalogAuth Required

Search Service Catalog

Lists or searches the 550+ service catalog. Use the returned id as catalog_service_id when adding services to a stack.

Parameters

qquerySearch query (name, domain, or category)
categoryqueryFilter by category (payments, cloud, cdn, ...)
limitqueryMax results per page
offsetqueryPagination offset

Response

{
  "total": 568,
  "count": 1,
  "offset": 0,
  "services": [
    {
      "id": "catalog_id",
      "name": "Stripe",
      "slug": "stripe",
      "domain": "stripe.com",
      "status_page_url": "https://status.stripe.com",
      "parser_type": "statuspage-io",
      "category": "payments",
      "favicon_url": "..."
    }
  ]
}

Error responses

All error responses follow this format:

{
  "error": "Human-readable error message"
}
StatusMeaning
401Invalid or revoked API key (authenticated endpoints only)
403Stack limit reached
404Stack not found (invalid or nonexistent stack ID)
429Rate limit exceeded (120 req/min per IP per stack). Check Retry-After header.
500Internal server error

Usage examples

cURL

# Get overall status
curl -s https://statusdrop.dev/api/v1/status/js7ey5magretd3kfxhzaen3c7n82pgph | jq .

# Get status history (last 14 days)
curl -s "https://statusdrop.dev/api/v1/status/js7ey5magretd3kfxhzaen3c7n82pgph/history?days=14" | jq .

# Export history as CSV
curl -s "https://statusdrop.dev/api/v1/status/js7ey5magretd3kfxhzaen3c7n82pgph/history?format=csv" -o history.csv

# Subscribe to RSS feed
curl -s https://statusdrop.dev/api/v1/status/js7ey5magretd3kfxhzaen3c7n82pgph/feed

cURL (Authenticated)

# List your stacks
curl -s https://statusdrop.dev/api/v1/stacks \
  -H "Authorization: Bearer sd_live_your_key_here" | jq .

# Create a stack
curl -X POST https://statusdrop.dev/api/v1/stacks \
  -H "Authorization: Bearer sd_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"name": "My SaaS"}'

# Add a service from catalog
curl -X POST https://statusdrop.dev/api/v1/stacks/STACK_ID/services \
  -H "Authorization: Bearer sd_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"catalog_service_id": "CATALOG_ID"}'

# Publish to service catalog
curl -X POST https://statusdrop.dev/api/v1/stacks/STACK_ID/publish \
  -H "Authorization: Bearer sd_live_your_key_here"

JavaScript / TypeScript

const STACK_ID = "js7ey5magretd3kfxhzaen3c7n82pgph";

const res = await fetch(`https://statusdrop.dev/api/v1/status/${STACK_ID}`);
const data = await res.json();

console.log(data.overall_status);   // "operational"
console.log(data.status_summary);   // "All 5 third-party services..."

// Check if any service is down
const issues = data.services.filter(s => s.status !== "operational");
if (issues.length > 0) {
  console.warn("Issues detected:", issues.map(s => s.name).join(", "));
}

Python

import requests

STACK_ID = "js7ey5magretd3kfxhzaen3c7n82pgph"

resp = requests.get(f"https://statusdrop.dev/api/v1/status/{STACK_ID}")
data = resp.json()

print(data["overall_status"])    # "operational"
print(data["status_summary"])    # "All 5 third-party services..."

for svc in data["services"]:
    print(f"{svc['name']}: {svc['status']}")

# Get history as CSV
csv_resp = requests.get(
    f"https://statusdrop.dev/api/v1/status/{STACK_ID}/history",
    params={"format": "csv", "days": 30}
)
with open("history.csv", "w") as f:
    f.write(csv_resp.text)