{
  "openapi": "3.1.0",
  "info": {
    "title": "UK FCA Verification API",
    "version": "1.0.0",
    "description": "Look up UK firms and individuals against the FCA Financial Services Register.\nProvides a clean JSON wrapper over the FCA's official register with\ncross-referencing against the SRA register where applicable.\n",
    "contact": {
      "name": "Stratum APIs",
      "url": "https://stratumapis.com",
      "email": "support@stratumapis.com"
    },
    "termsOfService": "https://stratumapis.com/legal/terms",
    "x-logo": {
      "url": "https://stratumapis.com/icon.svg",
      "altText": "Stratum APIs"
    }
  },
  "servers": [
    {
      "url": "https://api.stratumapis.com/v1/fca",
      "description": "Production"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/firms": {
      "get": {
        "summary": "Search firms by name",
        "operationId": "searchFirms",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2
            },
            "example": "Barclays Bank",
            "description": "Name to search for. Partial matches supported."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching firms",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FirmSummary"
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "warningList": {
                      "$ref": "#/components/schemas/WarningList"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/firms/{frn}": {
      "get": {
        "summary": "Get firm details by FRN",
        "description": "Returns the full firm record. Responses are cached server-side for\n5 minutes, so repeated lookups of the same FRN are fast and don't\ncount against FCA upstream rate limits. `warningList` says whether\nthe FCA has warned about an unauthorised firm using this firm's name\n(often a clone copying a real firm's details).\n",
        "operationId": "getFirm",
        "parameters": [
          {
            "name": "frn",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+$"
            },
            "description": "Firm Reference Number"
          }
        ],
        "responses": {
          "200": {
            "description": "Firm details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmDetails"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/firms/bulk": {
      "post": {
        "summary": "Look up multiple firms in a single request",
        "description": "Send up to 100 FRNs in one POST. Each lookup runs in parallel with\nbounded concurrency. Each FRN counts as one call against your monthly\nquota. Cached results are reused across the bulk batch.\n",
        "operationId": "bulkFirms",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "frns"
                ],
                "properties": {
                  "frns": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "type": "string",
                      "pattern": "^[0-9]+$"
                    }
                  }
                },
                "example": {
                  "frns": [
                    "122702",
                    "161661",
                    "124425"
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Results, in the same order as the input",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "frn": {
                            "type": "string"
                          },
                          "found": {
                            "type": "boolean"
                          },
                          "firm": {
                            "description": "Firm details. Null when `found` is false.",
                            "nullable": true,
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/FirmDetails"
                              }
                            ]
                          },
                          "error": {
                            "type": "string",
                            "nullable": true,
                            "description": "Set on per-firm upstream errors; other firms in the same batch still succeed"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/firms/{frn}/permissions": {
      "get": {
        "summary": "Get regulated permissions granted to a firm",
        "operationId": "getFirmPermissions",
        "parameters": [
          {
            "name": "frn",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Permissions list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "frn": {
                      "type": "string"
                    },
                    "permissions": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Permission"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/individuals/{irn}": {
      "get": {
        "summary": "Get approved individual by IRN",
        "operationId": "getIndividual",
        "parameters": [
          {
            "name": "irn",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Z0-9]+$"
            },
            "description": "Individual Reference Number"
          }
        ],
        "responses": {
          "200": {
            "description": "Individual details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IndividualDetails"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Stratum-Key",
        "description": "Your Stratum API key. Find it in the dashboard at /dashboard."
      }
    },
    "schemas": {
      "FirmSummary": {
        "type": "object",
        "required": [
          "frn",
          "name",
          "status"
        ],
        "properties": {
          "frn": {
            "type": "string",
            "example": "123456"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "authorised",
              "ear",
              "unauthorised",
              "no_longer_authorised",
              "applied_to_cancel",
              "in_administration",
              "unknown"
            ]
          },
          "rawStatus": {
            "type": "string",
            "description": "The Register's own status words, e.g. 'No longer registered as an Appointed Representative'."
          },
          "matchedOn": {
            "type": "string",
            "enum": [
              "name",
              "other_name"
            ],
            "description": "Search results only. `name`: the firm's own name contains the search. `other_name`: the Register found the firm under a trading or former name. Results are ordered: the exact name first, then names that start with the search, then names that contain it (firms currently on the Register first), then other names."
          }
        }
      },
      "FirmDetails": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FirmSummary"
          },
          {
            "type": "object",
            "properties": {
              "companiesHouseNumber": {
                "type": "string",
                "nullable": true
              },
              "businessType": {
                "type": "string"
              },
              "statusEffectiveDate": {
                "type": "string",
                "format": "date"
              },
              "address": {
                "$ref": "#/components/schemas/Address"
              },
              "phone": {
                "type": "string",
                "nullable": true
              },
              "website": {
                "type": "string",
                "nullable": true
              },
              "sraCrossReference": {
                "description": "Match in the SRA register (if firm is also a regulated solicitor practice). Null when no match.",
                "nullable": true,
                "type": "object",
                "properties": {
                  "sraNumber": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  }
                }
              },
              "warningList": {
                "$ref": "#/components/schemas/WarningList"
              }
            }
          }
        ]
      },
      "WarningList": {
        "description": "FCA Warning List check: unauthorised firms the FCA has warned about whose name matches, from the FCA\nFinancial Services Register. `screened: false` means the Register could not be searched; never read it as\n\"not on the list\".\n",
        "type": "object",
        "required": [
          "screened",
          "source",
          "checkedAt",
          "matches",
          "moreAt",
          "note"
        ],
        "properties": {
          "screened": {
            "type": "boolean"
          },
          "source": {
            "type": "string",
            "enum": [
              "FCA Financial Services Register"
            ]
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "matches": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "name",
                "tier"
              ],
              "properties": {
                "name": {
                  "type": "string",
                  "example": "Vanguard Investments / Vanguard Asset Management",
                  "description": "Every name in the FCA's entry, joined by ' / '."
                },
                "postcode": {
                  "type": "string",
                  "example": "E14 5AB"
                },
                "tier": {
                  "type": "string",
                  "enum": [
                    "name_exact",
                    "alias_exact",
                    "name_part",
                    "name_fuzzy"
                  ],
                  "description": "name_exact and alias_exact are the same name; name_part (one name is the start of the other) and name_fuzzy (a similar spelling) are for a person to review."
                },
                "clone": {
                  "type": "boolean",
                  "description": "The FCA marks the entry as a clone of an authorised firm."
                },
                "similarity": {
                  "type": "number",
                  "example": 0.91
                }
              }
            }
          },
          "complete": {
            "type": "boolean",
            "description": "Present and false when the name matched more Register entries than were read."
          },
          "moreAt": {
            "type": "string",
            "format": "uri",
            "example": "https://www.fca.org.uk/consumers/warning-list-unauthorised-firms"
          },
          "note": {
            "type": "string"
          }
        }
      },
      "Permission": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "effectiveDate": {
            "type": "string",
            "format": "date"
          },
          "limitations": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "IndividualDetails": {
        "type": "object",
        "properties": {
          "irn": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "currentFirms": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "frn": {
                  "type": "string"
                },
                "firmName": {
                  "type": "string"
                },
                "role": {
                  "type": "string"
                },
                "effectiveDate": {
                  "type": "string",
                  "format": "date"
                }
              }
            }
          }
        }
      },
      "Address": {
        "type": "object",
        "properties": {
          "line1": {
            "type": "string"
          },
          "line2": {
            "type": "string",
            "nullable": true
          },
          "town": {
            "type": "string"
          },
          "postcode": {
            "type": "string"
          },
          "country": {
            "type": "string"
          }
        }
      },
      "ErrorBody": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "requestId": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Quota exceeded",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            }
          }
        }
      }
    }
  }
}