w6w docs

API health

Applies to: HTTP · SDK (through client.request) · MCP (w6w_check_health) · Studio (the Reliability board). There is no dedicated method for these routes in the SDK’s stable surface today, so the SDK form is the generic client.request.

w6w answers “is this API working?” with two separate signals, and never blends them into one number:

SignalQuestion it answersWhere it comes from
Your callsHave your calls to this API been succeeding?w6w’s own record of the calls your account made.
Vendor statusWhat does the API say about itself right now?The app’s own public status check, when the app declares one.

Both are reported as one of four states: ok, degraded, down or unknown. There is no fifth state. An API you have never called is unknown, never ok.

The two can disagree, and that is useful. A vendor can say ok while your calls fail because your credential expired. Your calls can look fine while the vendor reports an incident that has not hit you yet. “Your calls” measures your traffic, not the vendor’s status page.

Check a target with an MCP client

The w6w_check_health tool takes a target and returns both signals. It is read-only: it never re-tests a connection or sends traffic to the API on your behalf, apart from fetching the vendor’s public status.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "w6w_check_health",
    "arguments": { "target": "app:sendgrid", "days": 30 }
  }
}

target is an app (app:<appId>, or just the bare app id), a connection (conn_…), or a Function, Workflow or Endpoint (fn_…, wf_…, ep_…). days is the window for “your calls” only, from 1 to 365 (default 30); it does not change the vendor check.

The result carries one entry per app the target touches, plus an overall summary:

{
  "target": "app:sendgrid",
  "measuredAt": "2026-10-06T09:30:00.000Z",
  "summary": { "state": "ok", "basis": ["…"], "oldestMeasurementAt": "2026-10-06T09:28:41.000Z" },
  "window": { "from": "2026-09-06T00:00:00.000Z", "to": "2026-10-07T00:00:00.000Z", "days": 30 },
  "apps": [
    {
      "appId": "sendgrid",
      "displayName": "SendGrid",
      "yourCalls": {
        "state": "ok",
        "calls": 412,
        "errors": { "e4xx": 3, "e429": 0, "eAuth": 0, "e5xx": 0 },
        "p95Ms": 380,
        "lastCallAt": "2026-10-06T09:14:02.826Z",
        "ongoingOutageId": null
      },
      "vendor": {
        "published": true,
        "state": "ok",
        "checkedAt": "2026-10-06T09:28:41.000Z",
        "ageSeconds": 79,
        "message": null,
        "attributedTo": []
      }
    }
  ],
  "nextActions": []
}

(yourCalls and vendor carry a few more fields — a description of what the window measured, per-component states and quota — omitted here.)

How to read it:

  • summary.state is the worst of the states already reported. It is not a third opinion.
  • vendor.published: false means the app declares no public status check. That is a different fact from vendor.state: "unknown", which means a check exists but gave no answer.
  • vendor.ageSeconds tells you how old the vendor reading is. Vendor readings are cached, so a repeat check inside the cache window returns the same reading rather than hitting the vendor again.
  • A connection target adds a connection block with the last stored result of testing it (lastTestOk, lastTestedAt). The tool never runs a new test; for that, use the connection test.

Read the reliability board over HTTP

Studio’s Reliability board is GET /reliability/services. It is scoped to a project and to the apps you name:

import { W6WClient } from "@w6w/sdk";

const client = new W6WClient(); // reads W6W_BASE_URL and W6W_TOKEN

const { body } = await client.request({
  method: "GET",
  path: "/reliability/services",
  query: { project: "prj_01H…", apps: "sendgrid,stripe", days: 30 },
});

for (const s of body.services) {
  console.log(s.appId, s.state, s.vendorStatus?.state ?? "no public check");
}
curl -sS "$W6W_BASE_URL/reliability/services?project=prj_01H…&apps=sendgrid,stripe&days=30" \
  -H "Authorization: Bearer $W6W_TOKEN"
QueryMeaning
projectRequired. The project whose calls are counted.
appsRequired. Comma-separated app ids, at most 10.
daysWindow, 1–365. Default 30.
limitCap the number of rows. The most urgent rows are kept, so a cap cannot hide a service that is down.

The answer has the account, the window, a plain-words uptimeMeans (“your calls succeeded, not the vendor’s own status page”), the definition of what counts as an outage, and a services list. Each service has:

  • state — your calls’ verdict for the app.
  • calls, errors (e4xx, e429, eAuth, e5xx), p95Ms, lastCallAt.
  • uptime — one cell per day with its own state, calls and errors, which is the uptime strip.
  • ongoingOutageId — set while an outage is open.
  • vendorStatus — the vendor’s signal (state, message, checkedAt, attributedTo, and component and incident detail when the vendor publishes it), or null when the app has no public check.
  • attention — now (degraded or down right now, on either signal), recent (clear now but there was a failure in the window), or none.

To find out which apps a project has used, list them first:

curl -sS "$W6W_BASE_URL/reliability/services/members?project=prj_01H…&days=30" \
  -H "Authorization: Bearer $W6W_TOKEN"
# → { "account": "…", "window": { … }, "appIds": ["sendgrid", "stripe"], … }

Check an app’s public status directly

GET /apps/{id}/health runs the app’s public health checks — the ones that need no credential — and rolls them up. It needs no connection and sends nothing signed.

curl -sS "$W6W_BASE_URL/apps/sendgrid/health" \
  -H "Authorization: Bearer $W6W_TOKEN"
{
  "state": "ok",
  "attributedTo": [],
  "results": [
    { "key": "status-page", "report": { "state": "ok" }, "checkedAt": "2026-10-06T09:28:41.000Z", "durationMs": 212 }
  ]
}

state is the worst state across the checks, attributedTo lists the checks that were not ok, and each entry in results is one check’s own report. Repeat calls inside a check’s minimum interval are answered from cache. Pass ?version= to check a specific version of the app.

If the app has no public check, the answer is { "state": "unknown", "attributedTo": [], "results": [] } — “nothing was probed”, not “all clear”.

Test a connection

Whether your credential works is a different question, and the answer is on the connection:

curl -sS -X POST "$W6W_BASE_URL/connections/conn_01H…/test" \
  -H "Authorization: Bearer $W6W_TOKEN"
# → { "ok": true, "actionKey": "list-contacts" }

The test checks the app’s own credential check and runs one harmless read action when the app has one. If the app has neither, you get { "ok": true, "untested": true, "message": "…" } — the credential was stored, but nothing was verified. A failed test marks the connection invalid until it passes again or its credential changes.

Errors

Statuserror.codeWhen
400missing_projectproject was left off a /reliability/* request.
400unknown_projectThe project does not exist in your account.
400invalid_app_filterapps is missing, empty, or lists more than 10 apps.
400invalid_daysdays is not a whole number from 1 to 365.
400invalid_limitlimit is not a positive integer.
404unknown_appThe app id is not in the catalog you can see. A hidden app answers the same as one that does not exist.
404unknown_connectionThe connection is not yours or does not exist.

From MCP, w6w_check_health refuses with invalid_argument (empty target), unknown_ref (nothing resolves for the target), unknown_app, or app_not_entitled (your account has no access to that app). Reserved built-in @w6w/* apps are refused with forbidden_internal_app.

Next