Service status

AffixIO service status

Every check on this page runs in your browser, against the same public endpoints your own monitoring can call. There is no cached verdict written into this document, so what you read is the live path between you and the service, measured a moment ago rather than reported by us.

Running checks

Waiting on the first result

Components

Each row names the endpoint it was checked against, so you can repeat the check yourself and get the same answer. Components are grouped by what breaks if they fail.

Verification plane

  • Verify API

    Checking

    The route your SDK calls to verify a proof and get an eligibility outcome back. If this is unavailable, remote verification stops and your gate falls back to whatever you configured it to do.

      GET https://api.affix-io.com/api/health, expect 200 and status ok

    • Proof engine and circuits

      Checking

      The circuit catalogue the engine has loaded. A drop in the circuit count means a family is missing and calls naming it will fail even though the API itself answers.

        Read from the API health document: engine, circuit_count

      Evidence plane

      • ML-DSA-65 attestation signing

        Checking

        The signing service behind post-quantum attestation on verification outcomes. Verification can still return a decision while this is degraded, but that decision arrives without signed evidence attached.

          GET https://api.affix-io.com/v1/attestation/public-key, expect 200 and ML-DSA-65

        • Signing key discovery

          Checking

          The well-known document a verifier fetches to resolve the current public key. Attestations already in your possession keep verifying against a key you have cached, so this affects first-time resolution rather than existing evidence.

            GET https://api.affix-io.com/.well-known/affix-mldsa65.json, expect 200

          • Merkle audit tree

            Checking

            The append-only digest tree behind audit proofs and evidence export. The leaf count only ever moves up. If it moves down, treat the reading as wrong and tell us before you trust it.

              Read from the API health document: merkle_root, merkle_leaf_count

            Operator surfaces

            • Operator Hub

              Checking

              Sign-in, API key management, usage figures and webhook endpoint registration. Keys already issued keep working while the Hub is unavailable, because verification does not route through it.

                GET https://hub.affix-io.com/, expect 200

              • Marketing site and docs

                Checking

                Public documentation, SDK reference and the machine-readable briefs. No runtime dependency, so a failure here is a documentation outage rather than a service one.

                  GET https://www.affix-io.com/robots.txt, expect 200

                Upstream dependencies

                • npm package registry

                  Checking

                  Where @affix-io/sdk and @affix-io/sdk-light are published. Operated by npm, not by us, and listed here because a registry problem blocks your installs and CI while every AffixIO service is fine.

                    GET https://registry.npmjs.org/@affix-io/sdk/latest, expect 200

                  What the API is reporting

                  Read straight out of the health document on the last successful check. These are the numbers worth screenshotting into a ticket, because they pin down which build answered you.

                  Policy version
                  Not read yet
                  Quote this when you report a decision you disagree with.
                  Circuits loaded
                  Not read yet
                  Total circuit families available to the engine.
                  Merkle leaves
                  Not read yet
                  Append-only count. It should never go backwards.
                  Signing key
                  Not read yet
                  The ML-DSA-65 key currently used for attestation.

                  Values appear once a check reads the response body.

                  What this page actually measures

                  Worth reading once, so you know how far to trust a green row.

                  It measures your path, not a global one

                  The checks run from the browser you are reading this in. That is deliberate: a status page maintained by the same estate it reports on will happily tell you everything is fine while a region is dark. Measuring from the client puts your DNS resolver, your network and your TLS path inside the test, which is usually where the problem is when the service itself is healthy.

                  The cost is that a red row does not automatically mean an outage. A corporate proxy, a blocked request or a dead connection on your side produces the same result as a service that is down. Before escalating, run the same check from a second network. If one passes and the other fails, the fault is on the path rather than at our end.

                  Two levels of detail

                  Where the endpoint grants cross-origin read permission to this page, the check reads the response and asserts on real fields: status equal to ok, algorithm equal to ML-DSA-65, and so on. Where it does not, the check falls back to an opaque request that proves the host answered and times the round trip without seeing the body. Each row states which of the two it got, so a thin row is a permissions boundary and not a hidden failure.

                  Be clear about the limit of the second one. An opaque request cannot tell a 200 from a 403, because the browser hands back an empty response either way. A row marked reachable therefore means the host answered, not that it answered correctly. If a call of your own is failing while every row here reads reachable, run the commands below from a terminal: those see the status code and will show you what the browser was not allowed to.

                  Latency is indicative

                  Timings include DNS, TLS and your own network, and they are taken from a single request rather than a percentile over a window. Treat them as a smoke test. Use the X-RateLimit-* and x-request-id response headers on your own calls when you need to reason about real API behaviour under load.

                  This page is not a monitoring dependency

                  It is static HTML with no server-side logic, deliberately the simplest thing on the estate so it survives a failure of the services it reports on. Do not have your alerting parse it. Point alerts at https://api.affix-io.com/api/health and keep this page for people.

                  What each state means

                  Fixed definitions, so the same words mean the same thing in an incident as they do on a quiet day.

                  Status states used on this page and what each one implies
                  StateDefinitionWhat you should do
                  Operational The check completed and the response matched what the component is supposed to return. Nothing.
                  Degraded The host answered, but the round trip was slower than the threshold for that component or the payload did not assert cleanly. Expect slower verification. Check your own timeouts have headroom before you retry aggressively.
                  Unreachable The request did not complete from this browser: DNS, TLS, connection or timeout. Repeat from another network. If both fail, treat it as an outage and apply your fallback.
                  Not checked The check has not run, or it was blocked before it reached the network. Reload. If it stays unchecked, something local is blocking the request.
                  Maintenance Planned work announced on this page in advance. Follow the note on the entry. Windows are chosen to avoid changing verification behaviour.

                  Incident and maintenance log

                  Written by hand, kept short, and served as JSON at /history/incidents.json so it can be pulled into your own change calendar.

                  No incidents recorded. This log opened on and holds nothing from before that date.

                  There is no uptime percentage on this page for the same reason. A figure like that only means something with a continuous measurement record behind it, and inventing one to fill the space would make every other number here worth less. Historic availability goes up once there is a full recorded period to publish.

                  Run these checks yourself

                  No API key needed for any of them. If you are putting AffixIO on a gate that matters, your own monitoring should not depend on our status page being up.

                  The one check worth alerting on

                  Fails loudly on a non-2xx, a timeout, or a health document that does not say ok.

                  curl -fsS -m 10 https://api.affix-io.com/api/health \ | jq -e '.status == "ok"' > /dev/null

                  Everything the health document gives you

                  Public, uncached, and the fastest way to identify which build answered.

                  curl -fsS https://api.affix-io.com/api/health | jq '{ status, service, engine, policy_version, circuit_count, merkle_root, merkle_leaf_count }'

                  Attestation signing

                  Assert on the algorithm as well as the status code. A 200 carrying the wrong algorithm is not a pass.

                  curl -fsS -m 10 https://api.affix-io.com/v1/attestation/public-key \ | jq -e '.algorithm == "ML-DSA-65" and (.key_id | length) > 0'

                  Key enforcement, by hand and not on a timer

                  A keyed route should refuse an unauthenticated request, so this returns 401 and a 200 would be the finding worth paging someone for. Run it when you want to confirm the auth layer, then stop.

                  test "$(curl -s -o /dev/null -w '%{http_code}' -m 10 \ https://api.affix-io.com/v1/health)" = "401"

                  Do not put that one in a monitoring loop. Unauthenticated requests to keyed routes are counted as authentication failures, and enough of them will get your address temporarily blocked from the whole API. A recurring check built on it eventually causes the outage it was meant to detect, and on a shared office address it takes your colleagues with it. Recurring checks belong on the unauthenticated routes above.

                  Keeping the component list in sync

                  The registry this page renders from is published as JSON, with the probe URL and expected response for each component. Read it rather than hard-coding a list that drifts.

                  curl -fsS https://status.affix-io.com/components.json \ | jq -r '.groups[].components[] | "\(.id)\t\(.probe)"'

                  Questions people actually ask

                  Mostly asked during an incident, which is the wrong time to be reading them for the first time.

                  Is AffixIO down right now?

                  The component list above answers it for your network. For an answer without loading a page, request api.affix-io.com/api/health and read the status field. It returns ok when the verification plane is serving.

                  Why does a component show as reachable with no detail?

                  The browser was allowed to open the connection but not to read the response. The API sends cross-origin read permission only to origins on its allow-list, so when this page is not on that list the check falls back to an opaque request. It still proves the host answered and still times the round trip. Nothing is wrong with the service.

                  Why is every AffixIO component returning 403 for me?

                  A 403 carrying error: forbidden means your address has been temporarily blocked, not that the service is down. It is applied after repeated unauthenticated requests to routes that need an API key, so the usual causes are a client that lost its key, a monitoring loop pointed at a keyed route, or a colleague on the same office address doing one of those. It clears by itself after a short period, and requests carrying a valid key are unaffected.

                  Why no uptime percentage?

                  A percentage needs a continuous measurement record behind it, and the log here opened on 15 August 2026. Publishing a number covering a period nobody measured would be made up, and it would undermine the readings that are real.

                  Does an outage stop proof generation on my host?

                  No. Proving runs locally against your own records with @affix-io/sdk or @affix-io/sdk-light. Remote verification, ML-DSA-65 attestation and Merkle anchoring are the parts that need this API. Whether an unavailable verify call fails open or fails closed is a decision that belongs in your application.

                  Do already-issued attestations keep verifying during an incident?

                  Yes. An ML-DSA-65 signature is verified against the public key, and if you have cached that key the check is entirely local. Key discovery being unavailable affects resolving a key you do not hold yet, not evidence you already have.

                  How is planned maintenance announced?

                  Posted here before it starts and kept in the log afterwards, in the page and in incidents.json. Windows are picked so that verification behaviour does not change under you mid-window.

                  How do I report something that is not shown here?

                  Email hello@affix-io.com with the x-request-id from a failing response, the endpoint, the UTC timestamp and the status code you got. That header is on every response and it is what makes the report traceable.