{
  "openapi": "3.1.0",
  "info": {
    "title": "UK Rules & Rates",
    "version": "0.1.0",
    "summary": "Sourced, date-aware UK tax and payroll rates, deadlines and UK business checks.",
    "description": "Every rate and deadline comes with its official source, the dates it applies and when it was last verified. Information only, not tax or legal advice. Verify with the source.\n\nPaid endpoints accept an API key (Authorization: Bearer or x-api-key) or an x402 payment. An invalid API key returns 401; only a valid key over its monthly limit gets the 402 x402 offer. Free endpoints and this document never return 402.",
    "contact": {
      "email": "info@blakestecsolutions.info",
      "url": "https://ukrules.dailylifeelevation.workers.dev/"
    },
    "termsOfService": "https://ukrules.dailylifeelevation.workers.dev/terms",
    "license": {
      "name": "Open Government Licence v3.0 (source data)",
      "url": "https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/"
    }
  },
  "servers": [
    {
      "url": "https://ukrules.dailylifeelevation.workers.dev"
    }
  ],
  "externalDocs": {
    "description": "MCP quick-start, pricing and API keys",
    "url": "https://ukrules.dailylifeelevation.workers.dev/pricing"
  },
  "tags": [
    {
      "name": "Rates",
      "description": "UK tax and payroll rates and deadlines"
    },
    {
      "name": "Business checks",
      "description": "UK company checks"
    }
  ],
  "paths": {
    "/v1/topics": {
      "get": {
        "operationId": "listTopics",
        "tags": [
          "Rates"
        ],
        "summary": "List rule topics (free)",
        "security": [],
        "responses": {
          "200": {
            "description": "Topics with rule counts.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "topics": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "topic": {
                            "type": "string"
                          },
                          "rule_count": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "topic",
                          "rule_count"
                        ]
                      }
                    },
                    "disclaimer": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "topics"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/rate": {
      "get": {
        "operationId": "getRate",
        "tags": [
          "Rates"
        ],
        "summary": "Rate in force for a key on a date (paid, $0.005 or 1 plan call)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyHeader": []
          },
          {
            "x402": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": true,
            "description": "Rule key, e.g. vat_registration_threshold. List topics with /v1/topics.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9_]+$",
              "maxLength": 100
            }
          },
          {
            "name": "date",
            "in": "query",
            "description": "YYYY-MM-DD; defaults to today in Europe/London.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "jurisdiction",
            "in": "query",
            "description": "Defaults to UK. Falls back to rUK/UK when no specific row exists.",
            "schema": {
              "type": "string",
              "enum": [
                "UK",
                "England",
                "Scotland",
                "Wales",
                "NI",
                "rUK"
              ],
              "default": "UK"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The rule version in force on the date.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requested": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string"
                        },
                        "date": {
                          "type": "string",
                          "format": "date"
                        },
                        "jurisdiction": {
                          "type": "string"
                        }
                      }
                    },
                    "rule": {
                      "$ref": "#/components/schemas/Rule"
                    },
                    "disclaimer": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "requested",
                    "rule"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key: unknown, malformed or cancelled. Not charged. Fix the key or remove it to pay with x402.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer error=\"invalid_token\"",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Payment required: no API key and no payment, or a valid API key whose plan limit is reached (the message says so). Pay with x402 ($0.005 per call; $0.02 for a business check). The PAYMENT-REQUIRED header holds the x402 payment requirements (base64 JSON); retry with a PAYMENT-SIGNATURE header.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "Base64-encoded x402 payment requirements.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequired"
                }
              }
            }
          },
          "404": {
            "description": "Not found. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An upstream service (Companies House, HMRC) is unavailable. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/deadlines": {
      "get": {
        "operationId": "listDeadlines",
        "tags": [
          "Rates"
        ],
        "summary": "Tax and payroll deadlines with next due date (paid, $0.005 or 1 plan call)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyHeader": []
          },
          {
            "x402": []
          }
        ],
        "parameters": [
          {
            "name": "from_date",
            "in": "query",
            "description": "YYYY-MM-DD; defaults to today in Europe/London.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          },
          {
            "name": "to_date",
            "in": "query",
            "description": "YYYY-MM-DD; on or after from_date.",
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Fixed-date deadlines (with next_due) followed by period-dependent ones (next_due null).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "from_date": {
                      "type": "string",
                      "format": "date"
                    },
                    "to_date": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "deadlines": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Deadline"
                      }
                    },
                    "disclaimer": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "deadlines"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key: unknown, malformed or cancelled. Not charged. Fix the key or remove it to pay with x402.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer error=\"invalid_token\"",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Payment required: no API key and no payment, or a valid API key whose plan limit is reached (the message says so). Pay with x402 ($0.005 per call; $0.02 for a business check). The PAYMENT-REQUIRED header holds the x402 payment requirements (base64 JSON); retry with a PAYMENT-SIGNATURE header.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "Base64-encoded x402 payment requirements.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequired"
                }
              }
            }
          },
          "404": {
            "description": "Not found. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An upstream service (Companies House, HMRC) is unavailable. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/company/search": {
      "get": {
        "operationId": "searchCompanies",
        "tags": [
          "Business checks"
        ],
        "summary": "Find UK companies by name (free)",
        "security": [],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Company name, 2 to 100 characters.",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Up to 10 matches.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "company_number": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "incorporation_date": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date"
                          },
                          "source_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uri"
                          }
                        }
                      }
                    },
                    "disclaimer": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Companies House unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/company/{company_number}": {
      "get": {
        "operationId": "checkUkBusiness",
        "tags": [
          "Business checks"
        ],
        "summary": "Sourced UK business check (paid, $0.02 or 2 plan calls)",
        "description": "Companies House facts (status, type, incorporation date, registered office, SIC codes, insolvency and charges flags), filing health (accounts and confirmation statement overdue and by how many days), the GOV.UK late filing penalty band if accounts are overdue, active officers and PSCs, each with a source_url. VAT check: coming soon; vat is accepted but not checked yet (vat_check.status is coming_soon). Not a credit check, sanctions or PEP screening. An unknown company is a 404 and is not charged.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyHeader": []
          },
          {
            "x402": []
          }
        ],
        "parameters": [
          {
            "name": "company_number",
            "in": "path",
            "required": true,
            "description": "Companies House number, e.g. 00445790 or SC123456.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 12
            }
          },
          {
            "name": "vat",
            "in": "query",
            "description": "Optional UK VAT number, e.g. GB123456789.",
            "schema": {
              "type": "string",
              "minLength": 9,
              "maxLength": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The business check. Fields include company, filing_health, late_filing_penalty, officers, pscs, vat_check, summary, checked_at, cache and disclaimer.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "summary": {
                      "type": "string"
                    },
                    "checked_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "disclaimer": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key: unknown, malformed or cancelled. Not charged. Fix the key or remove it to pay with x402.",
            "headers": {
              "WWW-Authenticate": {
                "description": "Bearer error=\"invalid_token\"",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Payment required: no API key and no payment, or a valid API key whose plan limit is reached (the message says so). Pay with x402 ($0.005 per call; $0.02 for a business check). The PAYMENT-REQUIRED header holds the x402 payment requirements (base64 JSON); retry with a PAYMENT-SIGNATURE header.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "description": "Base64-encoded x402 payment requirements.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequired"
                }
              }
            }
          },
          "404": {
            "description": "Not found. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An upstream service (Companies House, HMRC) is unavailable. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key from https://ukrules.dailylifeelevation.workers.dev/pricing, sent as \"Authorization: Bearer <key>\"."
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "The same API key, as an alternative header."
      },
      "x402": {
        "type": "apiKey",
        "in": "header",
        "name": "PAYMENT-SIGNATURE",
        "description": "x402 pay-per-call, no account. The first request returns 402 with a PAYMENT-REQUIRED header (base64 JSON: scheme exact, USDC on eip155:8453). Sign the transfer authorisation (for example with @x402/fetch) and retry with it in PAYMENT-SIGNATURE. The response carries a PAYMENT-RESPONSE header with the settlement. Only successful calls are charged. See https://x402.org."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      },
      "PaymentRequired": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "price_usd": {
            "type": "number"
          },
          "network": {
            "type": "string"
          },
          "pricing": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Rule": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "topic": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string"
          },
          "value": {
            "type": [
              "number",
              "null"
            ]
          },
          "value_text": {
            "type": [
              "string",
              "null"
            ]
          },
          "unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "applies_from": {
            "type": "string",
            "format": "date"
          },
          "applies_to": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "source_url": {
            "type": "string",
            "format": "uri"
          },
          "source_title": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_verified": {
            "type": "string",
            "format": "date"
          },
          "status": {
            "type": "string"
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "key",
          "label",
          "topic",
          "jurisdiction",
          "applies_from",
          "source_url",
          "last_verified"
        ]
      },
      "Deadline": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "recurrence_rule": {
            "type": [
              "string",
              "null"
            ]
          },
          "recurrence": {
            "type": [
              "string",
              "null"
            ]
          },
          "next_due": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "source_url": {
            "type": "string",
            "format": "uri"
          },
          "source_title": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_verified": {
            "type": "string",
            "format": "date"
          },
          "status": {
            "type": "string"
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "key",
          "label",
          "source_url",
          "last_verified"
        ]
      }
    }
  }
}