Skills に戻る
samber/developer-platform-skillsチェック済み

SKILL DETAIL

api-status-communication

samber/developer-platform-skills/api-status-communication

Design how an API platform communicates status and incidents to external consumers - status-page modeling (the four-stage incident lifecycle, degraded/partial/major component semantics, component granularity), monitoring-driven status instead of a hand-flipped green light, pull and push channels, incident-update cadence and templates, public postmortems for a developer audience, public SLA/SLO reporting, and maintenance-window notices. Use whenever the user mentions a status page, Statuspage, incident updates, uptime or SLA reporting, postmortems, or scheduled maintenance - even if they never say "status communication". Do NOT use for deprecation and breaking-change notices - use samber/developer-platform-skills@api-versioning-policy instead.

インストール · 326出典を見る

Installation

npx skills add https://github.com/samber/developer-platform-skills --skill api-status-communication

スキルファイル

SKILL.md

最終同期 · 2026/10/23

evals/evals.json›
{
  "skill_name": "api-status-communication",
  "evals": [
    {
      "id": 1,
      "prompt": "I'm the platform lead at Parcelforge, a logistics API used by about 900 integrators. We're finally building a proper status page. My plan: list all 38 of our microservices as components so customers see exactly what's affected, use our own lifecycle vocabulary (Detected, Diagnosing, Patching, Stable) because it matches our internal runbooks, and use a six-color severity scale so we can express nuance. Also, last month our Frankfurt data center went fully down for 40 minutes while everything else was fine, and we argued about how to represent that. Design the component and status model for us.",
      "expected_output": "A status-page model that rejects the microservice mirror and custom vocabulary, uses the four industry lifecycle statuses and four visual states, defines severity by breadth of impact, aggregates top-level status from the worst component with a documented blend rule, and scopes the Frankfurt case as a regional partial outage.",
      "files": [],
      "expectations": [
        "Rejects listing all 38 microservices as status-page components",
        "Recommends grouping into a handful of consumer-recognizable components chosen by the user's mental model of the product (e.g. API, dashboard, webhooks, docs), not internal architecture",
        "Rejects the custom Detected/Diagnosing/Patching/Stable lifecycle vocabulary",
        "Uses exactly the four statuses Investigating, Identified, Monitoring, Resolved",
        "Justifies the standard vocabulary by subscriber comprehension: readers already know the industry-wide set, a custom set costs comprehension and buys nothing",
        "Rejects the six-color scale and caps the page at four visual states (operational / degraded / partial / major)",
        "Defines Degraded Performance as working but slow for everyone",
        "Defines Partial Outage as completely broken for a subset of users",
        "Defines Major Outage as unavailable for everyone",
        "States explicitly that component severity encodes breadth of impact, not felt severity",
        "States that the top-level page status aggregates from the worst component state",
        "Recommends writing the aggregation/blend rule down so it is applied consistently rather than re-argued per incident",
        "Classifies the Frankfurt case as a Partial Outage scoped to that region, not a blanket page-wide state alarming users elsewhere"
      ]
    },
    {
      "id": 2,
      "prompt": "We run Quotable, a pricing-data API. Our incident process: monitoring pages the on-call engineer, the engineer confirms the problem is real, then our support lead reviews the wording before anything goes on the status page - we added that step to avoid false alarms and embarrassing typos. During our last outage the page showed all green for 45 minutes of a 60-minute incident, and customers found out from a Reddit thread before we posted. Our monitoring itself is solid: health checks, latency thresholds, uptime probes on every endpoint. Tighten this process so it doesn't happen again.",
      "expected_output": "A redesign that removes the human approval gate, auto-opens Investigating incidents from monitoring alerts with humans enriching afterwards, writes a staged escalation pipeline, adds a workflow-level probe, and installs detection-to-disclosure and third-party-first measurements.",
      "files": [],
      "expectations": [
        "Removes the human confirmation/approval gate as a precondition for the first public status change",
        "Recommends auto-opening an Investigating incident directly from the monitoring alert",
        "Frames the human role as enrichment (adding substance, scope, cadence) after disclosure, never as first disclosure",
        "Rejects or re-scopes the support-lead wording review so it cannot delay the initial public post",
        "Recommends writing down a staged escalation pipeline: an explicit rule for when an internal event becomes a public communication (alerts, incidents of note, triage, problems, status updates, published report)",
        "Recommends adding at least one workflow-level probe exercising a real multi-step user journey, not only infrastructure checks",
        "Distinguishes infrastructure-green from product-broken as different claims when justifying the workflow probe",
        "Installs detection-to-disclosure lag (alert-fired to page-updated) as a per-incident measurement driven to minutes",
        "States that a lag in the tens of minutes indicates a human gate is still in the loop",
        "Installs zero third-party-first disclosures (no aggregator or social post beating the page) as a binary per-incident gate",
        "Identifies customer migration to third-party complaint aggregators as the failure signal of lost trust in the page",
        "Recommends calibrated accuracy rather than maximal alarm, noting an honestly earned green history is itself valuable"
      ]
    },
    {
      "id": 3,
      "prompt": "Hatchbill is a self-serve invoicing API - credit-card signups only, no enterprise contracts, no SLAs with penalties anywhere. Our integrators are developers, and most already consume our product webhooks. The status page we spun up last quarter runs in the same AWS account and behind the same Route53 zone as the product itself. I have two engineers and roughly two weeks to get incident notifications right. Which notification channels should we build, and in what order? I was thinking email, SMS, maybe push later.",
      "expected_output": "A ranked channel plan: page plus email/RSS as the default rung, webhook push promoted for the developer audience, SMS removed from the menu entirely with a named re-promotion trigger, and out-of-band redundancy promoted because the page shares infrastructure with the platform.",
      "files": [],
      "expectations": [
        "Recommends the status page with email and RSS subscription enabled as the default first rung",
        "Notes hosted status tooling provides email/RSS subscription nearly free",
        "States that subscriptions reduce inbound support tickets during incidents (a support-load lever, not a courtesy)",
        "Promotes webhook push because the audience is integrating developers who wire status into their own alerting",
        "Notes webhook push is cheap here specifically because the platform already runs webhook delivery infrastructure",
        "Removes SMS/phone-grade push from the plan entirely rather than ranking it last or deferring it to later",
        "Justifies the SMS deletion by the absence of contractual SLAs and enterprise customers, given its per-message cost and deliverability work",
        "Names the SMS re-promotion trigger: the first contract that specifies a notification channel",
        "Flags the shared AWS account / shared DNS hosting as a problem: the page dies with the platform at the only moment it matters",
        "Promotes out-of-band redundancy (page hosted off the platform's own infrastructure, or at least one channel surviving a platform DNS/CDN failure) because of the shared hosting",
        "Distinguishes pull (the page the customer must visit) from push (subscriptions) and states a mature practice needs both",
        "States the channel ranking explicitly rather than leaving it implied by list order",
        "Ties the final ordering to the user's stated answers (no contracts, developer audience, shared infra, two-week ceiling), saying which constraint moved which rung"
      ]
    },
    {
      "id": 4,
      "prompt": "Live incident at Corklane right now - API requests have been failing for 20 minutes. My draft for the status page, internally we're tracking it as INC-CORK-77 'Operation Redwing': \"Operation Redwing - We believe this is an upstream AWS networking problem. Our k8s ingress pods keep getting rescheduled by the operator, which churns the endpoints. Will post more when we know more.\" Can you clean this up and post-ready it? We haven't actually confirmed the AWS theory yet, but it's our best guess. We know retries usually succeed right now.",
      "expected_output": "A rewritten update that drops the vendor blame and internal jargon, states only confirmed facts while admitting the cause is unconfirmed, carries a zoned timestamp, a plain-language title, the retry workaround, and a specific next-update time.",
      "files": [],
      "expectations": [
        "Removes the attribution of the incident to AWS from the public update",
        "States the rule: never deflect to an upstream vendor in public updates, even when the root cause genuinely is upstream",
        "Removes the internal jargon (k8s ingress pods, operator, endpoint churn) from the customer-facing text",
        "Removes the unconfirmed AWS theory as stated fact, keeping only what is confirmed",
        "Has the update explicitly admit the cause is not yet confirmed rather than omitting the topic",
        "Replaces the open-ended 'will post more when we know more' with a specific next-update time",
        "Adds a timestamp with an explicit time zone to the update",
        "Includes the retry workaround in the update since retries are known to succeed",
        "Replaces the 'Operation Redwing' codename with a plain-language title stating the nature of the problem",
        "States that internal incident identifiers and codenames never surface publicly",
        "Describes impact in the consumers' terms (what they are experiencing), not in infrastructure terms",
        "Recommends posting now rather than waiting for a fuller picture, and keeping page, social, and email consistent with this same content"
      ]
    },
    {
      "id": 5,
      "prompt": "Vaultic's authentication API is completely down in ap-southeast - 100% of requests failing there for the last half hour. That region is about 15% of our customer base. Our CEO wants the whole page flipped to Major Outage red because 'for those customers it IS major - total failure'. Internally we've classed it SEV2. The on-call engineer just messaged that error rates dropped back to normal two minutes ago and wants to mark the incident Resolved immediately so the outage window looks shorter. What do we set on the page and what do we post?",
      "expected_output": "Classification as a regionally-scoped Partial Outage per the breadth axis and the written SEV mapping, a Monitoring stage before Resolved instead of instant closure, and a Resolved update that quantifies the window and scope, owns the impact, and commits to a follow-up summary.",
      "files": [],
      "expectations": [
        "Sets the component to Partial Outage, not Major Outage, despite the CEO's framing",
        "Justifies via the breadth axis: completely broken for a subset (one region) is the definition of Partial Outage; Major Outage means unavailable for everyone",
        "Scopes the incident to ap-southeast in the title or scope statement so users elsewhere are not alarmed",
        "Rejects marking the incident Resolved immediately upon error rates recovering",
        "Moves the incident to Monitoring status with the recovery noted and the incident held open under observation",
        "Explains that resolving on the first green minute and then reopening costs more trust than a visible monitoring period",
        "Maps SEV2 to Partial Outage consistent with a severity-to-component-state mapping",
        "Recommends the severity-to-public-state mapping be agreed once in writing, not debated mid-incident",
        "Keeps the internal SEV2 label off the public page (internal severity vocabulary never surfaces publicly)",
        "Has the eventual Resolved update quantify the impact window and affected scope (times and the affected share/region)",
        "Has the Resolved update acknowledge or apologize for the disruption",
        "Has the Resolved update commit to a posted summary of cause and prevention within a stated timeframe"
      ]
    },
    {
      "id": 6,
      "prompt": "Brightmesh (data-sync API for B2B SaaS) had a 3-hour total outage last Tuesday - our worst ever, internally a P1. Enterprise customers are furious and two have mentioned churn on calls. The internal postmortem is done: it names Priya, the staff engineer whose config push triggered it, walks through our internal service mesh topology, and mentions the auth token exposure we found and fixed along the way. Legal wants us to post a one-line 'resolved, we've fixed it' note and move on. Our CTO asked me what we should actually publish, and where. We do have an active engineering blog.",
      "expected_output": "A recommendation to publish a full public postmortem on the engineering blog, with the argument for publishing over legal's default, a filtered and blameless external document structured around the three customer questions, split action items with owners and follow-through tracking, and acknowledgment of the sign-off and irreversibility costs.",
      "files": [],
      "expectations": [
        "Recommends a full public postmortem rather than the one-line resolved note",
        "Recommends the engineering blog as the channel, since the developer audience reads the deep version for trust-building",
        "Justifies promotion by the P1/major class of the incident and the visibly shaken trust",
        "Counters legal's default with the SRE argument: sharing a postmortem widely multiplies its learning value, and an honest postmortem is a key tool in restoring shaken trust",
        "Removes Priya's name from the public document, referring to a role instead of a person",
        "States the blameless rule concretely: never name an individual human in the published document",
        "Applies an explicit internal-to-external filtering step rather than publishing the internal document as-is",
        "Filters out the internal service-mesh/topology detail beyond what the explanation needs",
        "Filters out the security-sensitive auth-token detail",
        "Structures the external document around: why did this happen; could it have been worse; how do we make sure it won't happen again",
        "Includes a 'could it have been worse / where we got lucky' section transferred close to as-is from the internal version",
        "Includes a UTC timeline from first alert to resolution and quantified impact figures",
        "Splits action items into mitigative and preventative, each with an owner and a status",
        "Commits to publicly updating action-item status, noting completion below roughly 50% is the threshold at which postmortems become theater",
        "Warns that publication is irreversible (a correction can be appended, an admission cannot be unpublished) and that the deep write-up triggers legal/comms sign-off on cause language"
      ]
    },
    {
      "id": 7,
      "prompt": "Meterly sells a usage-metering API. Marketing wants a big '99.99% uptime' banner and a public uptime page to close enterprise deals. Reality: our internal reliability target is 99.9%, our contracts today promise nothing specific, and we've never written down what counts as 'down' - last quarter we had two separate 20-minute periods where p50 latency doubled but requests still succeeded, and we counted both as 100% up. Build the public uptime page for us.",
      "expected_output": "A public reporting design that keeps SLI/SLO/SLA distinct, refuses to publish the aspirational 99.99%, defines the downtime edge cases in writing first, translates percentages into minutes, publishes incident history beside the headline figure with the degraded-counts-as-up caveat surfaced, and separates the SLA page from the status page.",
      "files": [],
      "expectations": [
        "Distinguishes SLIs (measured metrics), SLOs (internal targets), and SLAs (contractual commitments with consequences) in the design",
        "Refuses to publish 99.99% while the internal target is 99.9%, identifying an aspirational number presented as a commitment as a dispute source",
        "Requires the edge cases be defined in writing before any number is published",
        "Defines a response-time threshold above which a slow response counts as downtime",
        "Defines whether the number is evaluated service-wide or per affected component, consistent with the status page's breadth model",
        "States planned maintenance is excluded from the arithmetic only when adequate notice was given, with that condition written into the SLA text",
        "Flags monitoring calibration: probing too sensitively overcounts downtime, too coarsely undercounts it, either corrupting the published number",
        "Translates the percentage target into allowed downtime minutes published alongside it (e.g. 99.9% as roughly 43 minutes per month, 99.99% as roughly 4.3 minutes per month)",
        "Publishes incident history next to the headline uptime figure",
        "Explains that Degraded Performance conventionally counts as 0% downtime, which is exactly how the two latency-doubling periods vanished from the number",
        "Recommends the latency-doubling periods surface as incidents (degraded state) rather than remaining invisible behind a 100% figure",
        "Treats the SLA/uptime page and the status page as distinct artifacts: historical performance against commitments versus current discrete incidents",
        "Recommends offering both pages, cross-linked"
      ]
    },
    {
      "id": 8,
      "prompt": "Draftify (document-generation API) is migrating its primary database in 12 days: about two hours where document-write calls will fail, reads unaffected. Ops picked Saturday 8pm US-Eastern 'because the office is closed then' - though most of our customers run batch jobs from Asia-Pacific overnight. We have one enterprise contract that requires 5 business days notice for planned downtime. Marketing wants to bundle into the same announcement that our legacy v1 endpoints are being retired at the end of next year, 'since we're emailing everyone anyway'. Current draft: 'Heads up - the API will be down for a couple hours Saturday night for maintenance.' Plan the communication.",
      "expected_output": "A maintenance-communication plan that separates the v1 retirement into its own communication track, rewrites the notice with exact zoned times and precise affected/unaffected scope plus expected behavior, honors the contractual notice floor, reschedules against customers' low-traffic hours, delivers via page plus push with reminders and start/completion confirmations.",
      "files": [],
      "expectations": [
        "Removes the v1 endpoint retirement from the maintenance announcement, making it a separate communication",
        "Justifies the split: a maintenance window and a deprecation are different communications on different timelines (day-to-week notice versus a multi-month runway) and must never be blended into one announcement",
        "Rewrites the notice with exact start and end times",
        "States an explicit time zone for those times",
        "States precise scope: write/document-generation calls affected, reads and other surfaces unaffected - replacing the blanket 'the API will be down'",
        "States what consumers should expect and do during the window (e.g. failing write calls, whether to pause batch jobs or retry)",
        "Verifies the schedule satisfies the enterprise contract's 5-business-day notice floor",
        "Challenges the Saturday-8pm-Eastern choice: schedule against the affected users' low-traffic hours, not the provider's office hours, given the Asia-Pacific overnight batch load",
        "Delivers the notice via the status page plus at least one push channel, never the page alone",
        "Schedules a reminder notification as the date approaches, in addition to the initial notice",
        "Posts start and completion confirmations even for the short two-hour window",
        "Notes that SLA exclusion is not trust exclusion: a badly communicated window still costs trust even when the arithmetic forgives it"
      ]
    }
  ],
  "trigger_queries": [
    { "query": "Design a status page for our public API - right now we just tweet when something breaks.", "should_trigger": true },
    { "query": "Our status page stayed green through the whole outage yesterday and customers found out from DownDetector.", "should_trigger": true },
    { "query": "Write the public postmortem for last week's 90-minute API outage.", "should_trigger": true },
    { "query": "We're taking the API down for a two-hour database migration in ten days - plan the maintenance communication.", "should_trigger": true },
    { "query": "Should our incident postmortems go on the engineering blog or stay on the status page?", "should_trigger": true },
    { "query": "How should we report our uptime publicly against the SLA we sell?", "should_trigger": true },
    { "query": "Help me set up Statuspage components for our platform.", "should_trigger": true },
    { "query": "What update cadence should we commit to during an open incident?", "should_trigger": true },
    { "query": "Draft the maintenance window notice for Saturday's migration.", "should_trigger": true },
    { "query": "Customers keep asking support if we're down - how do we communicate outages better?", "should_trigger": true },
    { "query": "the api is throwing 500s and I need to post something on the status page right now, what do I write", "should_trigger": true },
    { "query": "How many components should our status page show?", "should_trigger": true },
    { "query": "Wire the status page to our monitoring so it updates without a human in the loop.", "should_trigger": true },
    { "query": "Should customers be able to subscribe to status updates via webhook?", "should_trigger": true },
    { "query": "What's the difference between degraded performance and partial outage, and which do we set?", "should_trigger": true },
    { "query": "We found the cause of the outage - write the identified update for the page.", "should_trigger": true },
    { "query": "Legal doesn't want us to publish the incident write-up - what's the argument for doing it anyway?", "should_trigger": true },
    { "query": "We advertise 99.9% uptime - what should the public uptime page actually show?", "should_trigger": true },
    { "query": "How much advance notice do enterprise customers need for scheduled maintenance?", "should_trigger": true },
    { "query": "People learned about our outage from a Reddit thread before we posted anything - fix our process.", "should_trigger": true },
    { "query": "All our infra checks are green but checkout has been broken for an hour - do we post an incident?", "should_trigger": true },
    { "query": "Design the public uptime reporting page for our developer platform.", "should_trigger": true },
    { "query": "Our incident updates just say 'we're looking into it' - make them not terrible.", "should_trigger": true },
    { "query": "Translate a 99.95% uptime target into actual allowed downtime per month.", "should_trigger": true },
    { "query": "Everyone says our status page is useless during incidents - overhaul it.", "should_trigger": true },
    { "query": "Should an internal SEV1 automatically show as a major outage publicly?", "should_trigger": true },
    { "query": "One region is completely down - do we call that a major outage or a partial outage?", "should_trigger": true },
    { "query": "What should the resolved message say after an hour-long outage?", "should_trigger": true },
    { "query": "We need a written rule for when an internal alert becomes a public status update.", "should_trigger": true },
    { "query": "Should we add SMS alerts for status page incidents?", "should_trigger": true },
    { "query": "Our status page is hosted on the same DNS and CDN as the product - is that a problem?", "should_trigger": true },
    { "query": "How long do we stay in monitoring before marking an incident resolved?", "should_trigger": true },
    { "query": "Give me a blameless postmortem structure we can publish to customers.", "should_trigger": true },
    { "query": "A customer's account manager knew about our outage before our own page did - never again, fix it.", "should_trigger": true },
    { "query": "Marketing wants to publish our internal SLO as an uptime guarantee - good idea?", "should_trigger": true },
    { "query": "Announce next week's planned downtime to our API developers.", "should_trigger": true },
    { "query": "Do slow responses count as downtime in the uptime number we publish?", "should_trigger": true },
    { "query": "Turn on email subscriptions for our status page and tell me what else we need.", "should_trigger": true },
    { "query": "The internal post-incident review is done - what do we actually share with customers?", "should_trigger": true },
    { "query": "Our page lists forty microservices and nobody can parse it mid-incident.", "should_trigger": true },
    { "query": "Can we say the outage was our cloud provider's fault in the public update?", "should_trigger": true },
    { "query": "When something breaks we post on X and hope people see it - is that enough of a process?", "should_trigger": true },
    { "query": "How do we rebuild developer trust after last month's six-hour outage?", "should_trigger": true },
    { "query": "Should planned maintenance count against our published uptime?", "should_trigger": true },
    { "query": "Every incident we argue for twenty minutes about whether to flip the page red - fix that.", "should_trigger": true },
    { "query": "Write the deprecation notice for sunsetting our v1 API next June.", "should_trigger": false },
    { "query": "How much notice do we owe integrators before a breaking change to the API?", "should_trigger": false },
    { "query": "Add RFC 8594 Sunset headers to our legacy endpoints.", "should_trigger": false },
    { "query": "Design the error response body our API returns when a request fails.", "should_trigger": false },
    { "query": "What should a 500 error payload look like so integrators can self-serve debug?", "should_trigger": false },
    { "query": "Should our 429 responses include Retry-After, and which rate-limit headers do we send?", "should_trigger": false },
    { "query": "Build a dashboard where each partner sees their own integration's failed requests and can replay them.", "should_trigger": false },
    { "query": "Alert a specific partner automatically when their webhook endpoint keeps failing.", "should_trigger": false },
    { "query": "Design the retry and dead-letter policy for our outbound webhooks.", "should_trigger": false },
    { "query": "How should we sign webhook payloads so consumers can verify them?", "should_trigger": false },
    { "query": "Add delivery-status tracking so a developer can see whether their webhook was delivered.", "should_trigger": false },
    { "query": "Design idempotency keys so clients can retry POST requests safely.", "should_trigger": false },
    { "query": "Audit our API reference for undocumented response codes.", "should_trigger": false },
    { "query": "Where should the status page link sit in our developer portal's navigation?", "should_trigger": false },
    { "query": "Design zero-downtime API key rotation for our customers.", "should_trigger": false },
    { "query": "Set up a sandbox mode so partners can test without touching production data.", "should_trigger": false },
    { "query": "Set up Prometheus alerting rules for API latency and error rate.", "should_trigger": false },
    { "query": "Which synthetic uptime monitoring tool should we use to probe our endpoints?", "should_trigger": false },
    { "query": "Define internal SLOs and error budgets for the platform team's OKRs.", "should_trigger": false },
    { "query": "Design our internal incident response process and on-call rotation.", "should_trigger": false },
    { "query": "Write the internal postmortem of yesterday's database failover for the engineering wiki.", "should_trigger": false },
    { "query": "Pick a paging tool and escalation policy for on-call.", "should_trigger": false },
    { "query": "Should a deleted resource return 404 or 410 from our REST API?", "should_trigger": false },
    { "query": "Design the Kubernetes liveness and readiness probes for our API pods.", "should_trigger": false },
    { "query": "Add a /healthz endpoint to the API for the load balancer.", "should_trigger": false },
    { "query": "Plan the launch announcement for our new app marketplace to partners.", "should_trigger": false },
    { "query": "Write the listing standards third-party apps must meet on our marketplace.", "should_trigger": false },
    { "query": "Draft the internal Slack announcement telling the company about today's outage.", "should_trigger": false },
    { "query": "Write a press release announcing our new public API.", "should_trigger": false },
    { "query": "Email customers about the upcoming pricing change to our API plans.", "should_trigger": false },
    { "query": "Draft the regulatory breach-notification letter for the incident that exposed user emails.", "should_trigger": false },
    { "query": "Set up a changelog so developers hear about new API features.", "should_trigger": false },
    { "query": "Communicate the new, lower rate limits to existing API customers.", "should_trigger": false },
    { "query": "Write the migration guide for moving integrations from REST v1 to v2.", "should_trigger": false },
    { "query": "Negotiate SLA credit and penalty terms into our enterprise master agreement.", "should_trigger": false },
    { "query": "Calculate the service credits we owe customers after missing 99.9% last month.", "should_trigger": false },
    { "query": "Which integration surface should we ship first, REST or GraphQL?", "should_trigger": false },
    { "query": "Our deploys cause 30 seconds of 503s - design zero-downtime deployments.", "should_trigger": false },
    { "query": "Our MTTR is four hours - help us resolve incidents faster.", "should_trigger": false },
    { "query": "Build a DownDetector-style site that tracks other companies' outages.", "should_trigger": false },
    { "query": "What observability metrics should we collect to detect outages sooner?", "should_trigger": false },
    { "query": "Notify users in-app before their session expires.", "should_trigger": false },
    { "query": "Design the notification preference center in our web app.", "should_trigger": false },
    { "query": "Write runbooks for the top five incident scenarios for the on-call team.", "should_trigger": false },
    { "query": "Schedule a maintenance window in Kubernetes to drain and upgrade nodes.", "should_trigger": false }
  ]
}
references/incident-update-templates.md›
# Incident update templates

Templates and examples for step 4 of the workflow. Every update below is composed as an illustration, not quoted from a published incident - copy the shape and the discipline, never the specifics. All timestamps are UTC with the zone stated; copy that habit too.

The shape is observed practice, not only prescription: major cloud providers post each update with:

- A zoned timestamp.
- An explicit workaround line (including "none at this time" when there is none).
- A named datetime for the next update.

They drop the next-update commitment only on the final mitigated/resolved post. Hold that discipline even where a large provider you admire settles for "we will post updates as we learn more" - an open-ended promise is the one this practice replaces.

## Severity to component-state mapping

Internal incident-response vocabularies commonly grade severity SEV1-4. That scale is internal - it never surfaces publicly - but responders need a pre-agreed mapping from it to the public component states, decided once in writing, not debated mid-incident. Status-page platform OpenStatus publishes a severity matrix template in this same shape: a Critical tier maps to a "Major Outage" public label with a 15-minute response target, High to "Partial Outage" at 30 minutes, Medium to "Degraded Performance" at 2 hours, and Low to a minor-issue label at one business day, with classification meant to be deterministic so every engineer reaches the same row given the same inputs. A workable default mapping in the same shape (adapt the internal column to your own scale):

| Internal severity | Typical meaning (internal)                  | Public component state | First public update                           |
| ----------------- | ------------------------------------------- | ---------------------- | --------------------------------------------- |
| SEV1              | Service down for all users                  | Major Outage           | Immediately, auto-opened from the alert       |
| SEV2              | Major feature degraded, many users affected | Partial Outage         | Immediately, auto-opened from the alert       |
| SEV3              | Minor issue, some users affected            | Degraded Performance   | Within the response window your pipeline sets |
| SEV4              | Cosmetic, no functional impact              | No public incident     | None - fix note in changelog if relevant      |

The internal meanings above come from a published internal-incident severity table. Two named platforms confirm the same severity-versus-public-state split in practice: incident.io separates "severity" (an internal, subjective triage field) from "impact" (the separate, public-facing field that actually drives the status page color), and Cloudflare's incident management policy ties its internal P0/P1 priority classes to Status Page updates without exposing the priority label itself. Remember the axis from step 1: the public state encodes breadth of impact, so a SEV2 that is "broken for everyone but only in one region" is still Partial Outage, scoped to that region.

## Update skeleton per lifecycle status

Every update carries:

- The incident title.
- The current lifecycle status.
- The affected components and their states.
- A timestamped body.
- The time of the next update.

The body follows one skeleton throughout:

1. Acknowledge the impact (what consumers are experiencing, in their terms).
2. State what is known and confirmed - never what is suspected.
3. Give a workaround if one exists.
4. Set the expectation: what happens next, and when the next update lands.

### Investigating

> **Elevated error rates on the REST API** - Investigating
> 14:02 UTC - We are seeing elevated 5xx error rates on the REST API and are investigating. Requests to the dashboard and webhooks are unaffected. Next update by 14:20 UTC.

Posted automatically from the monitoring alert (step 2); a human enriches it within minutes. It commits to a next-update time even though nothing is diagnosed yet.

### Identified

> 14:17 UTC - We have identified the cause as a failing database node affecting API requests in eu-west. Requests in other regions are succeeding normally. A workaround is to retry failed requests, which are routed to healthy nodes with increasing probability as we drain traffic. Next update by 14:45 UTC.

States the confirmed cause and the scoped breadth, gives the workaround, keeps the cadence promise.

### Monitoring

> 14:41 UTC - We have failed over to a healthy database node and error rates have returned to normal levels as of 14:38 UTC. We are monitoring before declaring the incident resolved. Next update by 15:15 UTC.

The fix is deployed but the incident stays open - closing on the first green minute and reopening is worse for trust than a visible monitoring period.

### Resolved

> 15:10 UTC - This incident is resolved. Between 13:54 and 14:38 UTC, approximately 12% of REST API requests in eu-west failed with 5xx errors. We apologize for the disruption. A summary of cause and prevention will be posted here within 3 business days.

Quantifies the impact window and scope, owns it, and - per the postmortem ladder in step 5 - commits to the follow-up in the same message.

## Good/bad update pairs

**Bad - speculation, jargon, blame, no cadence:**

> We think this might be an issue with our cloud provider's networking. The k8s ingress pods are being rescheduled. Will update when we know more.

Three violations:

- Speculation stated as information.
- Internal jargon the reader can't act on.
- Blame pre-assigned to an upstream vendor.
- An open-ended "when we know more" instead of a next-update time.

**Good - same moment, same knowledge:**

> 09:12 UTC - We are investigating connection timeouts affecting roughly a third of API requests. We have not yet confirmed the cause. Requests that succeed are processing normally, so retrying is a viable workaround. Next update by 09:40 UTC.

Says less that is unconfirmed and more that is useful. Note it admits "not yet confirmed" outright - precise includes being precise about uncertainty.

**Bad - the silent-degraded non-update:**

Latency has doubled for an hour; the page shows green and no incident exists "because nothing is down."

**Good:**

> **Increased API latency** - Investigating
> 11:05 UTC - API response times are roughly twice their normal levels for all consumers. Requests are completing successfully. We are investigating the cause. Next update by 11:35 UTC.

Degraded Performance exists as a state precisely so this gets posted; a component that is slow for everyone is an incident even though uptime arithmetic may count it as up.

## The five practices, expanded

Atlassian's five incident-communication practices, as a review checklist for every update before it posts:

1. **Early** - is this going out now, or is someone waiting for a fuller picture? An update saying "still working on it, nothing new" beats silence; silence makes readers expect the worst.
2. **Often** - does this update name the time of the next one, and was the previous promise kept?
3. **Precise** - is every claim in it confirmed? Move suspicions to internal channels.
4. **Consistent** - do the page, social posts, and emails currently say the same thing? A reader mid-incident experiences any divergence as dishonesty.
5. **Owned, with empathy** - does it acknowledge what consumers are experiencing, and does it avoid deflecting to an upstream vendor even when the root cause is genuinely upstream? The customer's contract is with you.

## Titling

Title in plain language stating the nature of the problem and its scope: "Elevated error rates on the REST API in eu-west", "Webhook deliveries delayed". Internal template names, codenames, and severity labels are team-organization artifacts and never surface publicly - the public surface is the title and the update bodies.
references/public-postmortem-structure.md›
# Public postmortem structure

Structure, filtering rules, and a skeleton for step 5 of the workflow.

## The publish decision

Internal and external postmortems serve different jobs, not just different detail levels: the internal version optimizes for deep technical accuracy across engineering, product, and support; the external version optimizes for clarity, reassurance, and accountability toward users and partners. The decision to publish affects legal exposure, customer trust, and long-term reliability culture - make it deliberately per incident (against the ladder in SKILL.md step 5), never as an unexamined default in either direction.

The sourced case for leaning toward publication comes from the Google SRE workbook: the value of a postmortem is proportional to the learning it creates, so sharing it as widely as possible - "perhaps even with your customers" - multiplies that value. The workbook also calls a thoughtful and honest postmortem "a key tool in restoring shaken trust." Hand that argument to a team hesitant to publish.

## Channel choice

- **Status page** - suits active users monitoring uptime in the moment; the right home for the default summary postmortem attached to the incident.
- **Engineering blog** - suits the deeper technical write-up, and is the better channel specifically for API/developer-audience incidents: that audience is largely technical and reads the deep version for trust-building, not just resolution confirmation. Link it from the incident entry so both audiences find it.

## The three-question structure

Frame the external document around the three questions a customer actually has (Google's Customer Reliability Engineering framing):

1. **Why did this happen?** - the root cause and trigger section.
2. **Could it have been worse?** - a "where we got lucky" section. Transfer this from the internal version close to as-is, reworded only for clarity; its honesty is the section readers trust most.
3. **How do we make sure it won't happen again?** - the action-items table.

## What transfers from the internal document

Sections that move from internal to external well, with light rewording:

- **Quantified impact** - users/requests affected, error rate, duration; include SLO or error-budget burn where you publish those.
- **A UTC timeline** from first alert to resolution. Timestamps anchor credibility; vagueness reads as concealment.
- **2-5 systemic contributing factors**, framed blamelessly (see below).
- **Action items**, split into **mitigative** (fixes this specific gap) and **preventative** (fixes the class of failure). Publishing the split shows you distinguish patching from learning.

What gets filtered out on the way to public:

- Internal system names and architecture detail beyond what the explanation needs.
- Individual names and team attributions.
- Security-sensitive specifics.
- Any speculation that didn't survive the internal review.

This filtering step is the one internal postmortem processes skip entirely - add it explicitly to your pipeline.

## Blameless, concretely

- **Never name an individual human.** Write "a network engineer", not the person's name - this is what blameless concretely means in the document itself, not just in tone.
- Reframe every "who caused this" instinct as "what condition allowed this". The trigger is a condition; the cause is systemic.
- Run the internal review timeline-first, analysis-second: establish the facts before assigning cause.
- Use 5-Whys with cited evidence at each step, ending in a root cause with named systemic fixes - never ending at a person.

## Follow-through is part of the artifact

Postmortems without follow-through are theater - written to satisfy a process, not to change anything; one source pins the theater threshold at an action-item completion rate below 50%. Treat action-item tracking as part of this skill's own success metric (see SKILL.md Measurement): give every public action item an owner and a status, and when the promised items complete, say so - an update on a months-old postmortem is a cheap, high-credibility trust signal.

## Skeleton

```markdown
# [Plain-language incident title] - [date]

## Summary

One paragraph: what broke, who was affected, for how long, and the one-sentence cause.

## Impact

Quantified: affected share of requests/users, error rates, duration, regions/components.

## Timeline (all times UTC)

- HH:MM - first alert fired
- HH:MM - incident opened publicly (Investigating)
- HH:MM - cause identified
- HH:MM - mitigation deployed (Monitoring)
- HH:MM - resolved

## Why this happened

Root cause and trigger, plus 2-5 systemic contributing factors, blamelessly framed.

## Where we got lucky / could it have been worse

Honest assessment of the blast radius that almost was.

## What we are doing about it

| Action | Type         | Status             |
| ------ | ------------ | ------------------ |
| ...    | mitigative   | done / in progress |
| ...    | preventative | in progress        |

We will update this table as items complete.
```
references/sla-maintenance-reporting.md›
# SLA/SLO public reporting and maintenance notices

Detail for steps 6 and 7 of the workflow.

## SLI / SLO / SLA in public material

| Term | What it is                                                             | Public role                                                                   |
| ---- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| SLI  | The measured metric (e.g. response time, error rate)                   | The raw material - measured by your observability stack, not by this practice |
| SLO  | The internal target (e.g. 99.9% of requests under a latency bound)     | Publish only if you will report against it honestly                           |
| SLA  | The contractual, customer-facing commitment with consequences attached | The number the public page reports on                                         |

Keep the vocabulary straight in everything published: presenting an internal aspiration as if it carried contractual weight - or a contractual number you don't actually measure - is how disputes start.

## SLA page vs status page

A public SLA/uptime page and a status page are distinct artifacts answering distinct questions:

- **SLA page**: historical uptime percentages per component against commitments - "are you meeting your number". Directly checkable by a prospect or a procurement reviewer.
- **Status page**: discrete current incidents and manually-or-automatically set component states - "what is happening right now". It can cover components with no formal SLA at all (third-party dependencies, databases).

A mature reporting practice offers both, cross-linked.

## Edge cases to define before publishing any number

Each of these is a documented dispute source; define them in writing first:

- **Slow-but-responding requests**: set an explicit maximum acceptable response-time threshold above which a response counts as downtime - otherwise "downtime" silently excludes real user-facing pain.
- **Partial outages**: state whether the SLA is evaluated service-wide or per affected component. This is the same breadth axis the status page models; the two must agree.
- **Planned maintenance**: excluded from downtime arithmetic only when adequate notice was given (see notice scaling below) - write the notice condition into the SLA text itself.
- **Monitoring calibration**: probing too sensitively overcounts downtime (every 500ms blip flagged); probing too coarsely (long intervals, multi-failure thresholds) undercounts it. Either miscalibration corrupts the public number regardless of the reporting around it.

## Percentage to minutes

Translate targets into stakes a non-engineer feels - publish the minutes alongside the percentage (values are arithmetic on a 30-day month / 365-day year):

| Target | Allowed downtime / month | Allowed downtime / year |
| ------ | ------------------------ | ----------------------- |
| 99%    | ~7.2 hours               | ~3.7 days               |
| 99.9%  | ~43 minutes              | ~8.8 hours              |
| 99.95% | ~22 minutes              | ~4.4 hours              |
| 99.99% | ~4.3 minutes             | ~53 minutes             |

Where an error-budget model is in use internally, a visible burn-down communicates urgency for deployment and prioritization decisions in a way the percentage alone doesn't.

Publish incident history beside the headline figure. Degraded Performance conventionally counts as 0% downtime and partial outages may be weighted at a fraction of their duration - so an excellent-looking percentage can mask real incidents, and the honest page lets the reader check the number against the incident list behind it.

## Maintenance-notice scaling

Notice scales with impact and audience - there is no single correct number:

| Change                                  | Notice                                                                                   | Reminders                   |
| --------------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------- |
| Minor, low-impact work                  | ~24 hours minimum                                                                        | none needed                 |
| Major changes                           | weeks                                                                                    | yes, as the date approaches |
| Anything affecting enterprise customers | a week or more, even when self-serve users would get same-day                            | yes                         |
| Contractual floor                       | whatever the contract says - a 5-business-day minimum is a documented real-world example | per contract                |

This horizon (24 hours to ~2 weeks) is this skill's; the 6-12-month deprecation/breaking-change runway belongs to `samber/developer-platform-skills@api-versioning-policy`. They are different communications - never fold a breaking change into a maintenance notice.

## Maintenance notice content checklist

- Exact start and end times with an explicit time zone - ambiguous timing is the single most common cause of maintenance confusion.
- Scheduled against the affected user base's actual low-traffic hours, not the provider's office hours.
- Precise scope: which endpoints/features are affected, and which remain available.
- What consumers should expect and do (errors vs read-only vs full outage; whether to pause jobs or retry).
- Delivered via status page plus at least one push channel - never the page alone.
- Start and completion confirmations posted, even for short windows.

Good communication does not make maintenance disappear from customers' trust ledger just because the SLA arithmetic excludes it - a poorly communicated but SLA-compliant window still costs trust.

## Worked examples

Both notices are composed as illustrations, not quoted from a real vendor announcement. Their shape matches Atlassian's own guide to scheduled-maintenance messaging, which documents real vendor examples (DigitalOcean, Heroku, ToutApp) using the same elements: exact times in a neutral time zone, explicit affected-versus-unaffected scope, and a stated consumer action. The start/completion confirmation step in the good example below goes beyond Atlassian's documented pattern.

**Bad notice:**

> The API will be down for maintenance this Saturday night.

No date, no times, no time zone, no scope ("the API" - all of it?), no expected behavior, no channel redundancy, "night" in whose timezone?

**Good notice (sent 10 days ahead, re-sent 24 hours ahead):**

> **Scheduled maintenance: database migration affecting write endpoints**
> On Saturday 2026-09-12, from 02:00 to 04:00 UTC, POST/PUT/DELETE requests to the REST API will return 503 with a Retry-After header while we migrate our primary database. GET requests, the dashboard, and webhook deliveries are unaffected. We chose this window as the lowest-traffic period across our user base. We will post a confirmation here when the window starts and when it completes. Follow this page or subscribe to updates to be notified.

Scoped, timed, zoned, behavior-specified, redundantly delivered, with progress confirmations promised.
SKILL.md›
---
name: api-status-communication
description: Design how an API platform communicates status and incidents to external consumers - status-page modeling (the four-stage incident lifecycle, degraded/partial/major component semantics, component granularity), monitoring-driven status instead of a hand-flipped green light, pull and push channels, incident-update cadence and templates, public postmortems for a developer audience, public SLA/SLO reporting, and maintenance-window notices. Use whenever the user mentions a status page, Statuspage, incident updates, uptime or SLA reporting, postmortems, or scheduled maintenance - even if they never say "status communication". Do NOT use for deprecation and breaking-change notices - use samber/developer-platform-skills@api-versioning-policy instead.
license: MIT
metadata:
  author: Samuel Berthe
  version: "1.0.1"
---

# API Status Communication

You are designing how an API platform tells its external consumers what is happening - the status page, incident updates, public postmortems, SLA/SLO reporting, and maintenance notices. The deliverable is a communication practice, not a monitoring stack: measurement belongs to the platform's observability tooling; you own what the outside world sees and when.

Trustworthiness is the design constraint every step below serves. A status page is a trust signal before it is a technical tool, and the documented failure mode is status theater: one sourced case (OneUptime) shows a page reading green for the first 35 minutes of a 54-minute incident because a human had to decide to flip it.

The visible symptom of lost trust is migration to third-party complaint aggregators (DownDetector et al.) - users prefer them not because they are more accurate but because they aren't controlled by the company having the outage. Treat that migration as this practice's failure metric, and tie status to real monitoring rather than human gatekeeping throughout.

**Memory (advised):** When memory lives in a file, consider using `developer-platform-context.md`; if a different memory system is in use, rely on that instead. The file is an advisory reference, not a mandatory requirement. Separate task info in different sections. Remove finished tasks. Add a date to a task; no date for general project context. Some interview responses may differ between 2 tasks.

## Clarifying questions

Ask these before designing anything; each answer changes a later step. Batch them - this is a tactical design task, not a strategy interview.

1. Existing status page or greenfield? If one exists, request its URL and the full update history of the last 2-3 incidents.
2. Is status set by monitoring today, or does a human flip it? Which health checks, latency thresholds, and uptime probes already exist?
3. Who reads the page: integrating developers, business stakeholders/end customers, enterprise customers - in what mix? (see next section)
4. Are there contractual SLAs with consequences attached, and do any contracts specify a maintenance-notice floor?
5. Does the status page share infrastructure with the platform itself (same DNS, CDN, cloud account)? (drives channel redundancy in step 3)
6. In the last few incidents, how did consumers actually find out - and did any third party report the outage before the page did?
7. Deadline and effort ceiling - three sub-questions:
   - By when must this practice be live?
   - Is it a one-off fix after a bad incident, or a compounding trust asset you will run for years?
   - What can you spend: engineering hours to wire monitoring, an on-call rotation to hold cadence, budget for per-message channels?

Question 7 exists because the channel and postmortem menus diverge sharply on effort and on how long the payoff lasts, and neither ranking in steps 3 and 5 can be picked without it.

- A hard deadline promotes the rungs hosted tooling gives you nearly free.
- A compounding-asset mandate promotes out-of-band redundancy and the deep write-up.

If your harness has persistent memory, store the practice's core decisions: component model and blend rule, escalation thresholds, channel set, postmortem-depth policy, published SLA edge cases. Later runs - a live incident, a postmortem, a maintenance notice - start from the practice instead of re-deriving it.

## Reader roles

Regardless of whoever bought the product, the people reading a status page during an incident split by role, and the two roles want different pages:

- **Integrating developers** - want component-level technical detail: which endpoints, per-region scoping, latency numbers, timestamps, and a postmortem deep enough to trust. They wire status into their own alerting, which makes machine-readable push channels (webhook, RSS) first-class.
- **Business stakeholders and end customers** - want plain language: is it down, what's affected, when will it be fixed. Latency metrics read as noise to them.

Audience-tiered pages are the established pattern for API providers when the mix demands it:

- A public developer-facing page with API-level detail.
- An enterprise page behind SSO showing SLA compliance.
- Plain-language end-user messaging.

Default to one public developer-facing page and add tiers only when question 3 shows a real second audience - every extra tier is another surface to keep consistent during a live incident.

## Workflow

1. Model the status vocabulary and component granularity.
2. Wire status to monitoring - the trust step.
3. Choose the channels: pull page plus push subscriptions.
4. Design the incident-lifecycle communication practice.
5. Set the postmortem policy.
6. Publish SLA/SLO reporting.
7. Set maintenance-window conventions.

Each step has a section below, in order.

## 1. Model statuses and components

- Use the four de facto incident-lifecycle statuses below. Subscribers already read this vocabulary (it is Statuspage's, industry-wide); a custom set costs comprehension and buys nothing.
  - **Investigating** - alerted, looking into a potential problem.
  - **Identified** - cause or affected component confirmed.
  - **Monitoring** - fix deployed, being watched.
  - **Resolved**
- Model component severity as **breadth of impact, not felt severity** - the single most load-bearing decision here.
  - Degraded Performance: works but slow for everyone.
  - Partial Outage: completely broken for a subset (e.g. one region).
  - Major Outage: unavailable for everyone.
- Cap the page at four visual states (operational / degraded / partial / major, the industry green-yellow-orange-red). Five severities across many components is a matrix no reader holds in their head mid-incident.
- Aggregate the top-level page status from the worst component state, and document the blend rule you choose so it is applied consistently, not re-argued per incident.
- Choose component granularity by the user's mental model of the product, never by internal architecture - forty microservice names turn the page into noise exactly when it must be parseable. Group into a handful of consumer-recognizable components (e.g. API, dashboard, webhooks, docs) rather than one flat internal list.
- Scope regional incidents regionally: one data center down should read as a scoped partial outage, not a blanket "degraded" alarming users elsewhere - Cloudflare's page signals per-region for exactly this reason.
- Note the uptime-math consequence now: Degraded Performance conventionally counts as 0% downtime in SLA arithmetic, so a headline uptime figure can look excellent while masking real incidents. Step 6 handles the honest-reporting side of this.

## 2. Wire status to monitoring

- Tie page state directly to health checks, latency thresholds, and uptime data. No human gate decides whether customers "deserve to know" - that gate is what produced the 35-minute green lie.
- Auto-open an **Investigating** incident from the monitoring alert; humans then add substance, scope, and cadence. The human role is enrichment, never first disclosure.
- Write down your own staged escalation pipeline - the explicit rule for when an internal event becomes a public communication. Copy Cloudflare's citable staging below, set your own thresholds.
  1. Events trigger alerts.
  2. Some alerts become incidents of note.
  3. All are triaged.
  4. Some become problems.
  5. "Major" problems trigger status-page updates.
  6. P1 majors require a full published incident report.
- Include at least one workflow-level probe (a real multi-step user journey), not only infrastructure checks: infrastructure-green and product-broken are different claims. The sourced cautionary case (Sentry) is a retailer at perfect uptime while checkout was silently broken for a user segment.
- Hold the granularity tension honestly rather than resolving it by fiat: in almost any real outage most components still show green, and ThousandEyes' point is that a locked-out user does not care that everything but authentication is fine.
- An all-red page fails the reader in the other direction - that is the "sea of green dots" criticism aimed at AWS, cutting both ways. Step 1's granularity is the mitigation here, not a slogan.
- Aim for calibrated accuracy, not maximal alarm. A long green history honestly earned is itself valuable (Splunk): it stops one outage from reading as "the whole product is unreliable".
- Expect transparency to pay back: the trust–transparency paradox documented around Cloudflare's practice is that openly admitting failure increases customer trust in the provider's competence to handle the next one. A well-run public incident is evidence, not only liability.

## 3. Choose the channels

A status page is a **pull** channel - the customer has to go check it. Subscriptions (email, RSS, webhook, SMS) are **push**. Cloudflare's own self-critique of its pull-only page - it creates "confusion and wasted resources" during live incidents - is the design argument: a mature practice needs both, not either.

- efficiency: `page + built-in email/RSS subscription > webhook push > SMS push`
- value during a live incident: `any push channel > the pull page alone`
- effort: `SMS push > webhook push > page + email/RSS subscription`

- **Default rung: the status page with email and RSS subscription enabled.** With hosted status tooling this comes nearly free, and subscription is a support-load lever, not a courtesy - letting affected users self-serve the answer measurably reduces inbound tickets during an incident (Atlassian).
- **Promote webhook push** when question 3 says developers: an integrator audience wires status into its own alerting, and machine-readable push is what makes that possible. If the platform already runs webhook infrastructure, this rung gets cheap - the delivery machinery is sibling `samber/developer-platform-skills@webhook-platform-design` territory; you only define the status event.
- **Promote SMS/phone-grade push** for enterprise customers with contractual SLAs - the audience whose contracts (question 4) often expect it, and the only rung whose per-message cost and deliverability work justify the effort.
- **Deleted, not demoted: SMS/phone-grade push with no contractual audience.** When question 4 returns no SLAs with consequences and question 3 no enterprise tier, this rung leaves the menu rather than sitting at its bottom - per-message cost and deliverability work bought for nobody. Not parked last, because "we could add SMS later" reappears as scope every time an incident feels loud. Re-promotion trigger: the first contract that specifies a notification channel.
- **The starved option: out-of-band redundancy** - hosting the page off the platform's own infrastructure and keeping at least one channel that works when your DNS or CDN is down. Highest effort, invisible value on a good day, so it loses every efficiency round; question 5 is what promotes it, because a status page that dies with the platform is worth nothing at the only moment it matters. Status pages becoming unreachable during the outage they should be reporting is a documented failure mode.
- This ranking is a default, not a law. Re-rank against what you know about the user and say which answer moved which rung:
  - An enterprise-heavy base promotes SMS.
  - An integrator base that already consumes the platform's webhooks gets webhook push nearly free.
  - A page already hosted on shared infrastructure makes redundancy the first task rather than the last.
  - Question 7's effort ceiling decides how many rungs land in the first pass.

## 4. Design the incident-lifecycle communication practice

Run every incident through the four statuses of step 1, writing updates against Atlassian's five practices - the industry checklist:

1. **Early** - an update saying "still investigating, nothing new yet" beats silence; silence makes readers assume the worst.
2. **Often** - commit to a cadence: every update names the time of the next one, and that promise is kept even with nothing new to say.
3. **Precise** - facts over speculation; state what is confirmed, not what is suspected.
4. **Consistent across channels** - page, social, email must say the same thing at the same time; a customer mid-incident experiences "your service is broken" regardless of whose fault it technically is.
5. **Own it with empathy** - acknowledge impact, apologize when warranted, and never deflect to an upstream vendor even when the root cause is genuinely theirs.

Title incidents in plain language stating the nature of the problem ("Elevated error rates on the REST API in eu-west"), never internal codenames - internal template names exist for team organization and must not surface publicly. Map your internal severity vocabulary (SEV1-4 or equivalent) onto component states once, in writing, so responders know what to flip without debating it mid-incident.

See [references/incident-update-templates.md](references/incident-update-templates.md) for per-status update templates, a severity-to-component-state mapping, and good/bad update pairs.

## 5. Set the postmortem policy

Publishing a postmortem externally is a deliberate decision - it affects legal exposure, customer trust, and reliability culture. The sourced default for developer platforms leans toward publishing anyway.

Google SRE's position is that a postmortem's value is proportional to the learning it creates, so sharing it "perhaps even with your customers" multiplies that value. Google SRE also calls a thoughtful and honest postmortem "a key tool in restoring shaken trust."

Depth ladder for what to publish per incident:

- value for rebuilding developer trust: `engineering-blog postmortem > status-page summary postmortem > resolved-note only`
- effort: `engineering-blog postmortem > status-page summary postmortem > resolved-note only`
- compliance cost: `engineering-blog postmortem > status-page summary postmortem > resolved-note only` - the deep write-up triggers legal and comms sign-off on cause language and named third parties, and every rung is irreversible once published: you can append a correction, never unpublish an admission an enterprise customer already screenshotted.
- efficiency: `status-page summary postmortem > resolved-note only > engineering-blog postmortem`

- **Default rung: the status-page summary postmortem** - impact, cause, fix, prevention in a few paragraphs, attached to the incident. Owed for any incident that consumers visibly felt.
- **Step down to a resolved-note only** for brief blips with no consumer-visible impact beyond the incident entry itself.
- **Promote to a full public postmortem** for major (P1-class) incidents - Cloudflare mandates a published incident report at that tier - and whenever trust is visibly shaken. For an API audience the engineering blog is the right channel: that audience is technical and reads the deep version for trust-building, not just resolution confirmation.
- The full blog write-up is the starved rung - highest value, highest effort, loses every efficiency round - and the promotion conditions above are exactly what override that. This ranking is a default, not a law: re-rank against question 7 and the user's assets, and say which answer moved which rung.

- An active engineering blog and practiced writers get the deep write-up nearly free, which flips the effort line.
- A one-off fix under a hard deadline holds every incident at the summary rung.

Structure the external document around the three questions a customer actually has - why did this happen, could it have been worse, how do you make sure it won't happen again - and keep it blameless in the concrete sense: never name an individual human. Postmortems without follow-through are theater; action-item completion is part of this skill's measurement, not an afterthought.

See [references/public-postmortem-structure.md](references/public-postmortem-structure.md) for the full structure, the internal-to-external filtering step, blameless-writing rules, and a skeleton.

## 6. Publish SLA/SLO reporting

- Keep the three terms distinct in everything public:
  - **SLIs** are measured metrics.
  - **SLOs** are internal targets.
  - **SLAs** are contractual commitments with consequences.
- Publishing a number you privately treat as aspirational is how disputes start.
- A public SLA/uptime page is a distinct artifact from the status page, not a rebrand: it shows historical uptime against commitments; the status page shows discrete current incidents and can cover components with no formal SLA at all. A mature practice offers both - they answer "are you meeting your number" and "what is happening right now" respectively.
- Define the edge cases in writing before publishing any number, each a documented dispute source:
  - The response-time threshold above which a slow response counts as down.
  - Whether the SLA is evaluated service-wide or per affected component.
  - That planned maintenance is excluded only when adequate notice was given.
- Translate percentages into stakes: state targets as minutes of allowed downtime per month alongside the percentage, and show error-budget burn where that model is in use.
- Publish incident history next to the headline uptime figure. Step 1's uptime-math caveat means the percentage alone can mask real degradation - the honest page lets a reader check the number against the incidents behind it. "Monitoring without reporting is just watching"; reporting is what turns the metric into either evidence of a kept promise or a transparent admission of a missed one.

See [references/sla-maintenance-reporting.md](references/sla-maintenance-reporting.md) for edge-case definitions, the percentage-to-minutes table, and worked examples.

## 7. Set maintenance-window conventions

This skill owns the 24-hour-to-2-week notice horizon. The 6-12-month runway for deprecations and breaking changes is sibling `samber/developer-platform-skills@api-versioning-policy` territory - a maintenance window and a deprecation are different communications with different timelines; never blend them into one announcement.

- Scale notice with impact and audience:
  - Roughly 24 hours for minor low-impact work.
  - Weeks plus reminder notifications for major changes.
  - Enterprise customers conventionally get a week or more, even for changes that would be same-day for self-serve users.
- Check question 4's contracts for hard floors - a 5-business-day contractual minimum is a documented real-world example.
- State exact start and end times with an explicit time zone - ambiguous timing is the single most common cause of maintenance confusion - and schedule against the affected users' low-traffic hours, not the provider's office hours.
- State scope precisely: which endpoints and features are affected and which stay available, never a blanket "the API will be down".
- Post start and completion confirmations even for short windows; visible progress signals the work is controlled.
- Publish through the status page plus at least one push channel, never the page alone (step 3's pull-vs-push logic applies to planned work too).
- Do not treat SLA exclusion as trust exclusion: a badly communicated window still costs trust even when the arithmetic forgives it.

Notice templates live in [references/sla-maintenance-reporting.md](references/sla-maintenance-reporting.md).

## Failure modes

Anti-pattern checklist - each is a direct audit finding:

- Status theater: monitoring is red, the page is green, because a human hadn't decided to flip it yet.
- A third-party aggregator or social media reports the outage before the status page does.
- Silent degraded: latency doubles for everyone and nothing is posted because the service is "technically up".
- Components mirror internal architecture; the page is unreadable mid-incident.
- Severity modeled as felt badness instead of breadth of impact.
- The status page shares infrastructure with the platform and goes down with it.
- An open incident with no update and no promised next-update time.
- A public update deflecting blame to an upstream vendor.
- A postmortem that names an individual, or one whose action items quietly die.
- A headline uptime percentage published with no incident history beside it.
- A maintenance notice with no time zone, or a blanket "the API will be down".

## Measurement

- Detection-to-disclosure lag: the first public status change is generated from monitoring; measure alert-fired-to-page-updated on every incident and drive it to minutes. A lag in tens of minutes means a human gate is still in the loop - the 35-minutes-green case is the anti-benchmark.
- Third-party-first disclosures: zero incidents where an outside aggregator or social post beat the page. Binary, per incident.
- Lifecycle completeness: every incident shows all four statuses with timestamps, and every update's next-update promise was kept.
- Postmortem follow-through: track public action-item completion; below ~50% is the sourced threshold at which postmortems become theater, so set your target above it and report against it.
- Support-load trend: inbound tickets during incidents should fall as status subscriptions grow - the sourced direction (Atlassian); no industry threshold exists, so baseline from your own next incident and improve against it.

The first three are gates - iterate the design until they pass. The last two are trends to watch afterwards, never pass thresholds.

## Invocation examples

- "Design a status page for our public API - today we only tweet when something breaks."
- "Our status page stayed green through yesterday's outage and customers found out from DownDetector - fix the practice, not just the page."
- "Write the public postmortem for last week's 90-minute API outage and tell me whether it belongs on the status page or the engineering blog."
- "We're taking the API down for a two-hour migration in ten days - plan the maintenance communication."

## References

- [references/incident-update-templates.md](references/incident-update-templates.md) - per-status update templates, severity-to-component-state mapping, good/bad update pairs, the five-practices checklist expanded.
- [references/public-postmortem-structure.md](references/public-postmortem-structure.md) - public postmortem structure, internal-to-external filtering, blameless-writing rules, action-item tracking, skeleton.
- [references/sla-maintenance-reporting.md](references/sla-maintenance-reporting.md) - SLI/SLO/SLA distinctions, edge-case definitions, percentage-to-minutes table, maintenance-notice scaling and worked examples.

See also, same collection:

- `samber/developer-platform-skills@api-error-design` - designs what a single failed request returns; when the failure is the platform's fault at scale, this skill owns telling everyone.
- `samber/developer-platform-skills@api-versioning-policy` - deprecation and breaking-change communication on the 6-12-month horizon; this skill stops at the 2-week maintenance notice.
- `samber/developer-platform-skills@webhook-platform-design` - the webhook delivery machinery a status webhook-push channel rides on, and delivery status of webhooks themselves.
- `samber/developer-platform-skills@integration-error-observability` - per-integration error surfacing to an individual consumer, versus this skill's one-to-many broadcast.
- `samber/developer-platform-skills@developer-portal-design` - the portal that links the status page as a first-class entry point.
- `samber/developer-platform-skills@public-roadmap-strategy` - a slipped roadmap item is a roadmap update, not an incident; it never goes on the status page.