{"openapi": "3.0.3", "info": {"title": "UdiWatch API", "version": "1.0.0", "description": "Watch public EUDAMED UDI-DI and SRN records. Not an official European Commission service. Human reference: https://docs.udiwatch.com"}, "servers": [{"url": "https://app.udiwatch.com"}, {"url": "https://udiwatch.com"}], "components": {"securitySchemes": {"ApiKey": {"type": "apiKey", "in": "header", "name": "X-API-Key"}}}, "paths": {"/health": {"get": {"summary": "Health"}}, "/openapi.json": {"get": {"summary": "This document"}}, "/v1/trial": {"post": {"summary": "Create an account. Body {email, password}. Returns a session and the first API key. No card."}}, "/v1/login": {"post": {"summary": "Sign in. Body {email, password}. Returns a session."}}, "/v1/password": {"post": {"summary": "Set a password for the signed-in user, or for the owner when using an API key.", "security": [{"ApiKey": []}]}}, "/v1/users": {"post": {"summary": "Add a user to the account. Owner or API key. Body {email, password}.", "security": [{"ApiKey": []}]}}, "/v1/users/{id}": {"delete": {"summary": "Remove a user. Cannot remove the last owner.", "security": [{"ApiKey": []}]}}, "/v1/keys": {"post": {"summary": "Create an API key. The full key is returned once. Body {label}.", "security": [{"ApiKey": []}]}}, "/v1/keys/{id}": {"delete": {"summary": "Revoke an API key.", "security": [{"ApiKey": []}]}}, "/v1/search": {"get": {"summary": "Search the public register. Query q, optional status (on, off, not-eu), risk (i, iia, iib, iii, a, b, c, d), and page. A query or a filter is required. Not a dump of the register.", "parameters": [{"name": "q", "in": "query", "schema": {"type": "string"}}, {"name": "status", "in": "query", "schema": {"type": "string"}}, {"name": "risk", "in": "query", "schema": {"type": "string"}}, {"name": "page", "in": "query", "schema": {"type": "integer"}}]}}, "/v1/devices/{udi}": {"get": {"summary": "One public device page's data, including certificate dates when published"}}, "/v1/actors/{srn}": {"get": {"summary": "One public actor and one page of devices. Optional status, risk, and page."}}, "/v1/me": {"get": {"summary": "Account for the API key", "security": [{"ApiKey": []}]}}, "/v1/webhook": {"post": {"summary": "Set or clear a signed HTTPS webhook. Body {url}. Empty url clears it.", "security": [{"ApiKey": []}]}}, "/v1/webhook/test": {"post": {"summary": "Deliver a signed watch.test event to the saved URL. Body {}.", "security": [{"ApiKey": []}]}}, "/v1/watches": {"get": {"summary": "List watches", "security": [{"ApiKey": []}]}, "post": {"summary": "Watch a UDI-DI or SRN. Body {subject}.", "security": [{"ApiKey": []}]}}, "/v1/watches/{id}": {"patch": {"summary": "Rename a watch. Body {label}. A later sync keeps a name you set.", "security": [{"ApiKey": []}]}, "delete": {"summary": "Remove a watch", "security": [{"ApiKey": []}]}}, "/v1/sync": {"post": {"summary": "Refresh watches and return real diffs. First sync is a baseline.", "security": [{"ApiKey": []}]}}, "/v1/events": {"get": {"summary": "Audit trail of stored diffs", "security": [{"ApiKey": []}]}}, "/v1/expiring": {"get": {"summary": "Certificate dates in stored snapshots, from 30 days past to 180 days ahead", "security": [{"ApiKey": []}]}}, "/v1/import": {"post": {"summary": "Import a CSV of UDI-DIs or SRNs. Body {csv}.", "security": [{"ApiKey": []}]}}, "/v1/billing/checkout": {"post": {"summary": "Start Stripe Checkout. 7-day trial with a card if this account has not used a trial. Body {}.", "security": [{"ApiKey": []}]}}, "/v1/billing/confirm": {"post": {"summary": "Apply a finished Checkout session. Body {session_id}.", "security": [{"ApiKey": []}]}}, "/v1/billing/cancel": {"post": {"summary": "Cancel at period end. Access continues until expires_at.", "security": [{"ApiKey": []}]}}, "/v1/billing/resume": {"post": {"summary": "Undo a cancel while the period is still open.", "security": [{"ApiKey": []}]}}, "/v1/billing/portal": {"post": {"summary": "Stripe customer portal for the card on file.", "security": [{"ApiKey": []}]}}, "/v1/billing/webhook": {"post": {"summary": "Stripe webhook. Header Stripe-Signature. Unknown event types are acknowledged."}}, "/v1/logout": {"post": {"summary": "Revoke the current session."}}, "/v1/password/forgot": {"post": {"summary": "Send a password reset link if mail is configured. Body {email}."}}, "/v1/password/reset": {"post": {"summary": "Set a password from a reset token. Body {token, password}."}}, "/v1/account/delete": {"post": {"summary": "Delete the account. Body {password}. Cancels a Stripe subscription.", "security": [{"ApiKey": []}]}}, "/mcp": {"post": {"summary": "MCP JSON-RPC. Tools include search_devices, lookup_udi, get_device, get_actor, list_watches, add_watch, sync_watches, list_changes."}}}}