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.jsonand/status.mdlist every service;/status/{slug}.jsonand/status/{slug}.mdanswer for one. They take the same filters and?history=1as the/api/v1/servicesroutes below, with the format fixed by the extension. - Markdown: send
Accept: text/markdown(or add?format=md) to the/api/v1/servicesroutes; JSON is the default. A plainGET /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 anETag(sendIf-None-Matchfor a 304) andLast-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-RemainingandX-RateLimit-Reset. Over the limit returns 429 withRetry-After: 60. Errors are never cached. - is_down:
truefor partial or major outage,falsefor operational or degraded,nullwhen the status is unknown.
/api/v1/servicesNo keyList 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"
}
]
}/api/v1/services/{slug}No keyIs 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:
- Look for the StatusDrop widget script tag:
<script src="https://statusdrop.dev/widget.js" data-stack="STACK_ID"> - Extract the
data-stackattribute to get the stack ID - Call
GET /api/v1/status/{id}to get current status - Read the
status_summaryfield for a human-readable description - Use
_linksfor 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:
| Value | Description | Color |
|---|---|---|
| operational | Service is running normally | Green |
| degraded | Service is experiencing minor issues | Yellow |
| partial_outage | Some components are affected | Orange |
| major_outage | Service is significantly impacted | Red |
| unknown | Status could not be determined | Gray |
Endpoints
/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"
}
}/api/v1/status/{id}/servicesGet 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
}
]
}/api/v1/status/{id}/historyGet 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"
}
]
}/api/v1/status/{id}/feedRSS 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>/api/v1/status/{id}/llmsAI-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 ...
/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"
}/api/v1/healthHealth 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"
}/api/v1/openapiOpenAPI 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.
/api/v1/stacksAuth RequiredList 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
}
]/api/v1/stacksAuth RequiredCreate 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"
}/api/v1/stacks/{id}Auth RequiredUpdate Stack
Update stack settings. All fields are optional.
Parameters
idpathStack IDnamebodyNew stack namestatus_page_enabledbodyEnable/disable status pagestatus_header_textbodyCustom header text for the status pageResponse
{ "success": true }/api/v1/stacks/{id}Auth RequiredDelete Stack
Permanently deletes a stack, all services, status checks, and catalog entries.
Parameters
idpathStack IDResponse
{ "success": true }/api/v1/stacks/{id}/servicesAuth RequiredAdd Service
Add a service from catalog (provide catalog_service_id) or a custom URL service (provide name + status_page_url).
Parameters
idpathStack IDcatalog_service_idbodyAdd from catalog (mutually exclusive with name/url)namebodyCustom service namestatus_page_urlbodyCustom status page URLResponse
{ "id": "service_id" }/api/v1/stacks/{id}/services?service_id=...Auth RequiredRemove Service
Remove a service from a stack by its service ID.
Parameters
idpathStack IDservice_idqueryService ID to removeResponse
{ "success": true }/api/v1/stacks/{id}/publishAuth RequiredPublish to Catalog
Publishes your stack to the StatusDrop service catalog. Other users can then add your service as a monitored dependency.
Parameters
idpathStack IDResponse
{ "success": true, "catalog_slug": "sd-my-saas" }/api/v1/stacks/{id}/publishAuth RequiredUnpublish from Catalog
Removes your stack from the service catalog.
Parameters
idpathStack IDResponse
{ "success": true }/api/v1/catalogAuth RequiredSearch 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 pageoffsetqueryPagination offsetResponse
{
"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"
}| Status | Meaning |
|---|---|
| 401 | Invalid or revoked API key (authenticated endpoints only) |
| 403 | Stack limit reached |
| 404 | Stack not found (invalid or nonexistent stack ID) |
| 429 | Rate limit exceeded (120 req/min per IP per stack). Check Retry-After header. |
| 500 | Internal 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)