VellumKite / API v1
A quiet contract for live data.
A compact, OpenAPI-aligned reference for querying VellumKite’s refreshed, normalized public-register snapshot. Start with a bearer key, then search or look up records with predictable JSON.
/api/vellumkite-registerv1Bearer vk_live_…100 requests / minute01 / Authenticate
One header, every request.
Create and manage keys in the API keys dashboard. Keep the secret server-side and send it as a bearer token.
Missing, invalid, and revoked keys return 401 before rate limiting or register lookup begins.
Authorization: Bearer vk_live_…02 / Endpoint reference
Two reads. Stable shapes.
/api/vellumkite-register/{registrationId}Parameters
| Parameter | In | Required | Description |
|---|---|---|---|
| registrationId | path | yes | The normalized registration identifier, for example 08209948. |
200 response
application/json{
"id": "normalized-record-id",
"sourceRecordId": "08209948",
"operatorName": "Example Operator Ltd",
"registrationId": "08209948",
"status": "active",
"sourceUrl": "https://download.companieshouse.gov.uk/BasicCompanyData-2026-09-01-part1_7.zip",
"refreshedAt": "2026-09-14T02:00:19.365Z",
"licenseNote": "Companies House register data provenance.",
"schemaVersion": "v1"
}Status responses
200Normalized record returned.401Bearer key missing, invalid, or revoked.404No record exists for this registration ID.429The key has exhausted its minute window.500The register record could not be read./api/vellumkite-registerParameters
| Parameter | In | Required | Description |
|---|---|---|---|
| q | query | no | Optional keyword, trimmed and matched case-insensitively against normalized operatorName and registrationId. Blank input is ignored. |
| page | query | no | One-based positive integer page number. Default: 1. |
| pageSize | query | no | Integer records per page. Default: 100. Allowed range: 1–100. |
200 response
application/json{
"items": [
{
"id": "normalized-record-id",
"sourceRecordId": "08209948",
"operatorName": "Example Operator Ltd",
"registrationId": "08209948",
"status": "active",
"sourceUrl": "https://download.companieshouse.gov.uk/BasicCompanyData-2026-09-01-part1_7.zip",
"refreshedAt": "2026-09-14T02:00:19.365Z",
"licenseNote": "Companies House register data provenance.",
"schemaVersion": "v1"
}
],
"pagination": {
"page": 1,
"pageSize": 25,
"total": 1,
"totalPages": 1,
"hasNextPage": false
},
"sourceUrl": "https://download.companieshouse.gov.uk/BasicCompanyData-2026-09-01-part1_7.zip",
"licenseNote": "Companies House register data provenance.",
"refreshedAt": "2026-09-14T02:00:19.365Z",
"schemaVersion": "v1"
}Status responses
200Paginated register envelope returned.400A query parameter failed validation.401Bearer key missing, invalid, or revoked.429The key has exhausted its minute window.500The register snapshot could not be read.03 / Response schemas
Designed to be parsed once.
| id | string | Normalized record ID. |
| sourceRecordId | string | ID from the source register. |
| operatorName | string | Registered operator name. |
| registrationId | string | Normalized registration identifier. |
| status | string | null | Current register status, when available. |
| sourceUrl | uri | Source snapshot URL. |
| refreshedAt | date-time | Record refresh timestamp. |
| licenseNote | string | Data provenance and licensing note. |
| schemaVersion | "v1" | Contract version literal. |
items is an array of records. pagination.page starts at 1; pageSize defaults to 100 and is capped at 100.
The envelope also includes sourceUrl, licenseNote, schemaVersion: "v1", and a nullable refreshedAt.
Results are ordered by registrationId ascending, then id ascending, so moving between pages is deterministic. totalPages is 0 for no matches, and hasNextPage tells you whether another page exists.
{
"page": 1,
"pageSize": 25,
"total": 1,
"totalPages": 1,
"hasNextPage": false
}04 / Rate limits
100 requests per key, per minute.
Authentication failures happen first. Once a key is authenticated, every response carries the current quota headers—even validation, not-found, and read-failure responses.
| Header | Example | Meaning |
|---|---|---|
| X-RateLimit-Limit | 100 | Requests permitted in the current one-minute window. |
| X-RateLimit-Remaining | 99 | Requests remaining for this key in the current window. |
| X-RateLimit-Reset | Unix timestamp | When the current one-minute window resets. |
An exhausted key receives Retry-After in seconds and a body with the same retryAfter value.
HTTP/1.1 429 Too Many Requests
Retry-After: 42
{"error":"Rate limit exceeded.","retryAfter":42}05 / Common errors
Errors stay small and actionable.
| Status | Meaning | Example body |
|---|---|---|
| 400 | Validation error | {"errors":{"page":"Number must be greater than or equal to 1."}} |
| 401 | Authentication failure | {"error":"A valid API key is required."} |
| 404 | Lookup miss | {"error":"Register record not found."} |
| 429 | Quota exhausted | {"error":"Rate limit exceeded.","retryAfter":42} |
| 500 | Read failure | {"error":"Unable to read the register record."} |
06 / Quick start
Search the live register in one request.
This example is generated from the current origin in your browser, so the copied command targets the deployed API you are viewing.
curl --request GET \
--url '/api/vellumkite-register?q=northline&page=1&pageSize=25' \
--header 'Authorization: Bearer vk_live_your_api_key'