BUMIT API V1 API

Trust infrastructure for business and autonomous transactions. BUMIT verifies Swiss businesses using authoritative evidence and returns deterministic, machine-readable decisions, reason codes, freshness and provenance.

Operations 17

GET /api/health Service liveness #
POST /api/v1/lei-lookup GLEIF Level 1 LEI linkage for a Swiss UID (body-based) #
POST /api/v1/vat-verify Swiss UID register VAT status for a Swiss UID (body-based) #
POST /api/v1/registry-events Historical SHAB/SOGC publications for a Swiss UID (body-based) #
POST /api/v1/verify-business Agent-first Swiss business verification (one call) #
GET /api/v1 Compact machine discovery index #
GET /api/v1/capabilities Capability support and operational availability #
GET /api/v1/status Public service, source, and capability status #
GET /api/v1/company/search Search Swiss companies by name (Zefix) #
GET /api/v1/company/{uid} Normalized company record (Zefix) #
GET /api/v1/company/{uid}/events Historical commercial-register publications (SHAB/SOGC) for a UID #
GET /api/v1/company/{uid}/sanctions Direct SECO sanctions screening for a UID #
GET /api/v1/company/{uid}/finma FINMA authorisation-list membership and warning-list candidates for a UID #
GET /api/v1/company/{uid}/lei GLEIF Level 1 LEI records linked to a Swiss UID by exact identifier equality #
GET /api/v1/company/{uid}/vat Swiss UID register VAT registration state for a canonical UID #
GET /api/v1/address/verify Correspondence of an address with the official Swiss building-address directory #
GET /api/v1/openapi.json This specification #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/bumit-ai:bumit-api-v1-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

bumit-ai-v1-openapi.json Raw ↑
{
  "openapi": "3.1.0",
  "info": {
    "title": "BUMIT API",
    "version": "0.10.5",
    "description": "Trust infrastructure for business and autonomous transactions. BUMIT verifies Swiss businesses using authoritative evidence and returns deterministic, machine-readable decisions, reason codes, freshness and provenance.\n\n## Data sources and attribution\n\nZefix (Swiss Central Business Name Index / Commercial Register) is the source of the company-register data returned by this API. Every Zefix-derived fact carries `source: ZEFIX`, a retrieval timestamp, the source record identifier where available and an official-source reference.\n\n## No guarantee\n\nZefix does not guarantee the completeness, accuracy or availability of this data. Upstream information may be incomplete, delayed, unavailable or erroneous.\n\n## No legal effect\n\nZefix-reported information has no legal effect. It is registry-derived information retrieved from Zefix, not a legally certified, binding or guaranteed statement of legal status.\n\n## BUMIT-derived fields\n\nBUMIT normalizes, validates and enriches source data. Normalized names, mapped status enums, freshness flags, coverage statements and PASS/REVIEW/FAIL/UNKNOWN decisions are BUMIT-derived values, reported under `bumit_derived_values` and `decision_origin`, and are NOT fields published by Zefix. BUMIT logic does not change the legal status of the underlying Zefix data.\n\n## Freshness\n\nResponses expose `freshness` (`observed_at`, `retrieved_at`, `source_timestamp`, `age_seconds`, `max_age_hours`, `stale`, `served_from_cache`, `source_state`, `upstream_status`). BUMIT is cache-first: sufficiently fresh stored data is reused instead of calling Zefix, and cached data is never presented as a fresh verification. `source_state` is one of LIVE (produced by a successful upstream call for this request), CACHED (served from local storage within the freshness window), STALE (older than `max_age_hours`), DEGRADED (upstream not confirmed available) or UNAVAILABLE (no observation at all).\n\n## Decision semantics\n\n`decision` is BUMIT-derived and is one of PASS, REVIEW, FAIL, UNKNOWN. It is produced by a versioned verification profile (`profile`), whose MANDATORY checks alone determine the outcome: any mandatory FAIL yields FAIL, otherwise any mandatory REVIEW yields REVIEW, otherwise any mandatory UNKNOWN yields UNKNOWN, otherwise PASS. Optional and informational findings stay visible in `checks`, `reason_codes`, `claims` and `coverage` but never compensate for unresolved or adverse mandatory evidence. No weighted score, majority vote, positive-signal counting, fuzzy decisioning or LLM is used. UNKNOWN means the evidence required for a conclusion was missing, unavailable, stale or unusable — explicitly NOT a negative and NEVER a positive result. PASS means only that the configured profile's applicable mandatory checks were satisfied: it does not mean safe to transact, trustworthy, risk-free, solvent, legally approved, complete KYB, free of sanctioned owners or controllers, or confirmed signatory authority. See `x-verification-profiles`.\n\n## Reason codes\n\n`reason_codes` on verification results and `error.reason_code` on failures are stable machine-readable identifiers. Human-readable `message` text may change at any time; machines must key on codes. `error.retryable` states whether repeating the identical request may succeed.\n\n## Evidence classification\n\nEvery claim carries `claim_type`: SOURCE_FACT (explicitly published by the source), NORMALIZED (deterministic transformation of a source fact), DERIVED (deterministic BUMIT conclusion), INFERRED (probabilistic, not stated by the source) or UNAVAILABLE (required evidence missing). `inference_used` is true if and only if `claim_type` is INFERRED, so an inferred value can never be presented as a source fact. `confidence` appears only on INFERRED claims; deterministic authoritative facts never receive an invented confidence score. Nothing in the current implementation produces INFERRED claims.\n\n## Capabilities\n\n`x-capabilities` lists the stable BUMIT capability taxonomy. A capability being listed does NOT mean it is operationally available. Query `/api/v1/capabilities` for deployment-specific support and availability; fixture-only capabilities remain unavailable for production evidence.\n\n## Idempotency\n\nVerification accepts an optional `Idempotency-Key` request header. Within the retention window, the same key with the same request replays the stored response (`Idempotent-Replay: true`) instead of repeating the operation or upstream work. Reusing a key with a different request returns BAD_REQUEST. No payment or charging behaviour exists."
  },
  "servers": [
    {
      "url": "https://bumit.ai",
      "description": "Current deployment"
    }
  ],
  "security": [],
  "paths": {
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Service liveness",
        "responses": {
          "200": {
            "description": "Service is up",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "service"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    },
                    "service": {
                      "type": "string",
                      "enum": [
                        "bumit"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/lei-lookup": {
      "post": {
        "operationId": "lookupLei",
        "summary": "GLEIF Level 1 LEI linkage for a Swiss UID (body-based)",
        "description": "Replacement for the deprecated GET /api/v1/company/{uid}/lei. Reads locally stored GLEIF data only; GLEIF is never contacted.\n\nThe UID is supplied in the JSON request body and never in the URL. Only the listed fields are accepted; unknown fields are rejected (400). No login, no API key, no caller persistence. Responses are never cacheable (Cache-Control: no-store). No legal effect.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "uid"
                ],
                "properties": {
                  "uid": {
                    "type": "string",
                    "maxLength": 64,
                    "example": "CHE-123.456.789",
                    "description": "Swiss UID in canonical or compact form. Validated locally (prefix, format, mod-11 check digit) before any lookup."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result with the same semantics as the deprecated UID-in-path operation."
          },
          "400": {
            "description": "Malformed body, missing uid or unknown field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "Only POST is accepted."
          },
          "413": {
            "description": "Body larger than 1024 bytes (PAYLOAD_TOO_LARGE); rejected before any lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "415": {
            "description": "Content-Type is not application/json (UNSUPPORTED_MEDIA_TYPE); rejected before any lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "422": {
            "description": "Structurally invalid UID; rejected before any lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "501": {
            "description": "No authoritative source is configured in this deployment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotImplemented"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vat-verify": {
      "post": {
        "operationId": "verifyVat",
        "summary": "Swiss UID register VAT status for a Swiss UID (body-based)",
        "description": "Replacement for the deprecated GET /api/v1/company/{uid}/vat. Reads locally stored UID register data only; the register is never contacted.\n\nThe UID is supplied in the JSON request body and never in the URL. Only the listed fields are accepted; unknown fields are rejected (400). No login, no API key, no caller persistence. Responses are never cacheable (Cache-Control: no-store). No legal effect.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "uid"
                ],
                "properties": {
                  "uid": {
                    "type": "string",
                    "maxLength": 64,
                    "example": "CHE-123.456.789",
                    "description": "Swiss UID in canonical or compact form. Validated locally (prefix, format, mod-11 check digit) before any lookup."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result with the same semantics as the deprecated UID-in-path operation."
          },
          "400": {
            "description": "Malformed body, missing uid or unknown field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "Only POST is accepted."
          },
          "413": {
            "description": "Body larger than 1024 bytes (PAYLOAD_TOO_LARGE); rejected before any lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "415": {
            "description": "Content-Type is not application/json (UNSUPPORTED_MEDIA_TYPE); rejected before any lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "422": {
            "description": "Structurally invalid UID; rejected before any lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "501": {
            "description": "No authoritative source is configured in this deployment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotImplemented"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/registry-events": {
      "post": {
        "operationId": "listRegistryEvents",
        "summary": "Historical SHAB/SOGC publications for a Swiss UID (body-based)",
        "description": "Replacement for the deprecated GET /api/v1/company/{uid}/events. Reads stored publications only; no live SHAB call.\n\nThe UID is supplied in the JSON request body and never in the URL. Only the listed fields are accepted; unknown fields are rejected (400). No login, no API key, no caller persistence. Responses are never cacheable (Cache-Control: no-store). No legal effect.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "uid"
                ],
                "properties": {
                  "uid": {
                    "type": "string",
                    "maxLength": 64,
                    "example": "CHE-123.456.789",
                    "description": "Swiss UID in canonical or compact form. Validated locally (prefix, format, mod-11 check digit) before any lookup."
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 500,
                    "default": 100
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result with the same semantics as the deprecated UID-in-path operation."
          },
          "400": {
            "description": "Malformed body, missing uid or unknown field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "Only POST is accepted."
          },
          "413": {
            "description": "Body larger than 1024 bytes (PAYLOAD_TOO_LARGE); rejected before any lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "415": {
            "description": "Content-Type is not application/json (UNSUPPORTED_MEDIA_TYPE); rejected before any lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "422": {
            "description": "Structurally invalid UID; rejected before any lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "501": {
            "description": "No authoritative source is configured in this deployment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotImplemented"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/verify-business": {
      "post": {
        "operationId": "verifyBusiness",
        "summary": "Agent-first Swiss business verification (one call)",
        "x-primary-operation": true,
        "security": [],
        "description": "Primary BUMIT operation. No authentication, no API key, no account; no payment is currently required. Request bodies are not logged and no caller identity is stored.\n\nSend `Content-Type: application/json` (otherwise 415). Maximum body 8192 bytes (otherwise 413). Body: any supported combination of uid, name and address; only these fields are accepted (unknown fields → 400). A UID must carry the CHE prefix and a valid mod-11 check digit, otherwise the request is rejected (422) before any source lookup.\n\nResolution: a UID resolves cache-first against the commercial register. A name alone is enough to start: BUMIT searches the commercial register (discovery), then resolves identity conservatively. Exactly one exact normalized legal-name match resolves its UID and runs the same verification as a UID request. Several exact matches (optionally narrowed by address.locality = seat) return AMBIGUOUS / MULTIPLE_EXACT_NAME_MATCHES. No exact match but register candidates (even one) return AMBIGUOUS / NAME_CANDIDATES_REQUIRE_SELECTION — partial or similar names are never auto-selected, and locality never narrows them. No candidates → NOT_FOUND. A partial local cache never proves absence, uniqueness or identity (UNAVAILABLE / REGISTER_SEARCH_UNAVAILABLE). To continue after AMBIGUOUS, choose a candidate and call again with {\"uid\": \"<candidate uid>\"}. Address alone is UNSUPPORTED for resolution.\n\nOverall outcome is derived deterministically from REQUIRED checks (register existence, register status, direct SECO screening against the accepted production baseline, and name match when uid and name are both supplied): any NOT_VERIFIED → NOT_VERIFIED; else any REVIEW_REQUIRED → REVIEW_REQUIRED; else any other non-VERIFIED → UNAVAILABLE; else VERIFIED. An unresolved business returns the resolution outcome (NOT_FOUND, AMBIGUOUS, UNAVAILABLE, UNSUPPORTED). FINMA authorisation-list membership is reported but never required. VAT, address, LEI and FINMA warning checks have no production source and are reported as UNSUPPORTED (NOT_REQUESTED when the input was not supplied). See `x-agent-guidance`.\n\nInterpreting the evidence: read `result.outcome` first, then each `checks[]` entry. `sources` names the source (ZEFIX = commercial-register index; SECO_SANCTIONS and FINMA = operator-ingested datasets), `data_basis` says whether it is a cache-first register lookup, an accepted production dataset, a synthetic fixture or NONE, `provenance` carries the source record or dataset reference, and `freshness` carries the times BUMIT actually holds (`observed_at`, `retrieved_at`, `source_timestamp`) plus `served_from_cache` and `stale`; `freshness_mode` says whether the evidence is LIVE, REGISTER_CACHE, STORED_DATASET, FIXTURE or NONE. For SECO/FINMA, `provenance` separates `source_date` / `source_last_modified` (the source's own date), `retrieved_at` (download), `dataset_activated_at` (acceptance into production) and `last_successful_check_at` (last successful acquisition run, changed or unchanged). Staleness is measured from `freshness.observed_at` (download), never from the source record date or the last check. A null timestamp is unknown; there is no universal last-updated time.\n\nSECO and FINMA are never contacted by this operation, and it cannot trigger any acquisition. Responses are `Cache-Control: no-store`. Not a complete KYB result.",
        "x-agent-guidance": {
          "VERIFIED": "Only the defined BUMIT required checks passed. Does not establish general trustworthiness, safety to transact or complete KYB.",
          "NOT_VERIFIED": "One or more required verification conditions failed; see result.blocking_capabilities and checks[].reason_code.",
          "REVIEW_REQUIRED": "Treat as neither VERIFIED nor NOT_VERIFIED. Inspect the blocking checks' unresolved or adverse evidence (e.g. a possible sanctions name candidate) before acting.",
          "UNAVAILABLE": "Required evidence could not currently support a conclusion. Not a negative result; retrying later may help (see checks[] and freshness).",
          "NOT_FOUND": "The business could not be resolved: the UID lookup found no company, or the register name search returned no candidate. Not proof that the business does not exist.",
          "AMBIGUOUS": "The name did not identify exactly one company (resolution.reason_code MULTIPLE_EXACT_NAME_MATCHES or NAME_CANDIDATES_REQUIRE_SELECTION). Do not silently select a candidate: inspect resolution.candidates, select the intended legal entity using your available context (or ask the user), then resubmit verifyBusiness with the selected candidate's uid. Candidates are register search results, not verified identities; candidates_truncated=true means more existed.",
          "UNSUPPORTED": "The supplied input combination cannot resolve a business (e.g. address only). Supply a UID or a name."
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "minProperties": 1,
                "description": "Identify a Swiss company by uid or name; supply at least one of them. A uid is not required when a name is given. address is optional and only assists; address alone is not supported (result outcome UNSUPPORTED). If uid is given, it identifies the company and a supplied name is checked against the registered name. Only uid, name and address are accepted.",
                "properties": {
                  "uid": {
                    "type": "string",
                    "maxLength": 64,
                    "pattern": "^[\\s._/-]*[Cc][\\s._/-]*[Hh][\\s._/-]*[Ee](?:[\\s._/-]*[0-9]){9}[\\s._/-]*$",
                    "description": "Optional Swiss UID, canonical (CHE-123.456.789) or compact (CHE123456789). When present it identifies the company directly. Check digit validated server-side; an invalid UID is rejected before any source lookup."
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 300,
                    "description": "Optional company legal name; use it when no UID is known. Name-only resolution needs at least 3 characters. A company is resolved only on a unique exact normalized legal-name match — never fuzzy. Otherwise candidates are returned for explicit selection: do not guess; resubmit with the chosen candidate's uid. With uid, the name is compared against the registered name instead."
                  },
                  "address": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "street",
                      "house_number",
                      "postcode",
                      "locality"
                    ],
                    "description": "Optional Swiss postal address; all four fields are required when address is supplied. It is checked against the official building-address directory (this never proves the company is at that address). With name, locality may narrow several exact legal-name matches by registered seat; it never turns a non-exact match into an identity. Address alone cannot identify a company.",
                    "properties": {
                      "street": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200,
                        "description": "Street name, without house number."
                      },
                      "house_number": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 20,
                        "description": "House number."
                      },
                      "postcode": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 10,
                        "description": "Postcode."
                      },
                      "locality": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100,
                        "description": "Locality (town). Also compared with the registered seat when narrowing exact name matches."
                      }
                    }
                  }
                }
              },
              "examples": {
                "byUid": {
                  "summary": "Verify by UID (synthetic identifier)",
                  "value": {
                    "uid": "CHE-000.000.000"
                  }
                },
                "byName": {
                  "summary": "Name only: resolves when exactly one exact legal-name match exists, otherwise returns AMBIGUOUS candidates",
                  "value": {
                    "name": "Example AG"
                  }
                },
                "byUidAndName": {
                  "summary": "Verify UID and claimed name",
                  "value": {
                    "uid": "CHE-000.000.000",
                    "name": "Example AG"
                  }
                },
                "byNameAndAddress": {
                  "summary": "Resolve by exact name, narrowed by locality",
                  "value": {
                    "name": "Example AG",
                    "address": {
                      "street": "Musterstrasse",
                      "house_number": "1",
                      "postcode": "8000",
                      "locality": "Zürich"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Structured verification result. Every outcome, including NOT_FOUND / AMBIGUOUS / UNAVAILABLE / UNSUPPORTED, is a 200.",
            "headers": {
              "Cache-Control": {
                "description": "Always `no-store`: answers are request-specific and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessVerificationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON, empty body, non-object body, unknown field, field too long or invalid field (BAD_REQUEST; `error.details.reason` names the rule).",
            "headers": {
              "Cache-Control": {
                "description": "Always `no-store`: answers are request-specific and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "Method other than POST (METHOD_NOT_ALLOWED).",
            "headers": {
              "Cache-Control": {
                "description": "Always `no-store`: answers are request-specific and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "413": {
            "description": "Body larger than 8192 bytes (PAYLOAD_TOO_LARGE); no source was contacted, no usage event.",
            "headers": {
              "Cache-Control": {
                "description": "Always `no-store`: answers are request-specific and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "415": {
            "description": "Content-Type is not application/json (UNSUPPORTED_MEDIA_TYPE); no source was contacted, no usage event.",
            "headers": {
              "Cache-Control": {
                "description": "Always `no-store`: answers are request-specific and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "422": {
            "description": "Structurally invalid UID or invalid check digit (INVALID_UID); no source was contacted.",
            "headers": {
              "Cache-Control": {
                "description": "Always `no-store`: answers are request-specific and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error (INTERNAL_ERROR). No internal detail is exposed.",
            "headers": {
              "Cache-Control": {
                "description": "Always `no-store`: answers are request-specific and must not be cached.",
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1": {
      "get": {
        "operationId": "getDiscoveryIndex",
        "summary": "Compact machine discovery index",
        "description": "Read-only. States service identity, API version, the primary operation, authentication (none), current payment requirement (none currently) and a data-handling summary, and links to this document, capabilities, status, documentation and the RFC 9727 API catalog at /.well-known/api-catalog. Never performs a lookup. Other methods → 405.",
        "security": [],
        "responses": {
          "200": {
            "description": "Discovery index",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiscoveryIndex"
                }
              }
            }
          },
          "405": {
            "description": "Only GET and HEAD are accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/capabilities": {
      "get": {
        "operationId": "listCapabilities",
        "summary": "Capability support and operational availability",
        "description": "Derived from the canonical BUMIT capability registry and local source configuration. Fixture-only capabilities are never reported as available.",
        "responses": {
          "200": {
            "description": "Public capability contract",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "capabilities",
                    "legal_effect"
                  ],
                  "properties": {
                    "capabilities": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "legal_effect": {
                      "const": false
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/status": {
      "get": {
        "operationId": "getPublicStatus",
        "summary": "Public service, source, and capability status",
        "description": "Reports public-safe local state without making live upstream

# --- truncated at 32 KB (206 KB total) ---
# Full source: https://artifacts.apis.io/bumit-ai/openapi/_original/bumit-ai-v1-openapi.json