Gazetted API Reference
A RESTful JSON API for integrating statutory notice placement into case management systems, legal platforms, and council workflows. Bearer-token authenticated, webhook-enabled, and Stripe-billed.
Jump to section
Overview
The Gazetted API lets law firms, councils, probate registries, and case management platforms place statutory notices in UK local newspapers and the London Gazette without using the web portal. It is designed for integrations where notices are generated programmatically from structured case data.
All requests are made to https://gazetted.co.uk/api/v1. The API accepts JSON request bodies and returns JSON responses. All monetary values are integers in pence (GBP).
Supported notice types
The following notice types are supported via the API. Additional types available in the portal (including Premises Licence) require custom wording and are not yet template-driven — they will be added in a future version.
hgv
HGV Operator Licence
probate
Section 27 Probate
planning
Planning Notice
tro
Traffic Regulation Order
public_path
Public Path Order
highways
Highways Notice
Rate limits
Each API key is limited to 120 requests per minute. Exceeding this returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait.
SLA
The API targets 99.9% uptime. For status updates, see Status. Orders placed via the API are processed with the same SLA as portal orders.
Quickstart
This guide walks through placing an HGV Operator Licence notice end-to-end in under five minutes.
Get an API key
API keys are scoped to your organisation. An org admin can generate one from Settings → API Access. The key is shown once at creation — copy it to a secure secrets manager.
gz_live_ for production and gz_test_ for test mode (coming soon).Set your API key as an environment variable so the examples below work as-is:
export GAZETTED_API_KEY=gz_live_xxxxGet a quote
The quote endpoint is unauthenticated — you can use it to show pricing before the user commits to an order.
curl -X POST https://gazetted.co.uk/api/v1/quote \
-H "Authorization: Bearer $GAZETTED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "hgv",
"postcode": "SW1A 1AA"
}'Response:
{
"type": "hgv",
"postcode": "SW1A 1AA",
"newspaper": {
"name": "Evening Standard",
"rateGbpPence": 1200,
"frequency": "daily"
},
"pricing": {
"subtotalGbpPence": 11900,
"platformFeeGbpPence": 3500,
"gazetteFeeGbpPence": 0,
"vatGbpPence": 2400,
"totalGbpPence": 14400
},
"compliance": {
"minColumnsRequired": 1,
"publicationDaysRequired": 1
}
}Create an order
Submit the order with all required fields for the notice type. The API generates notice text from your structured data — no pre-formatted copy needed.
curl -X POST https://gazetted.co.uk/api/v1/orders \
-H "Authorization: Bearer $GAZETTED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "hgv",
"postcode": "SW1A 1AA",
"applicantName": "Acme Haulage Ltd",
"applicantAddress": "1 Logistics Park, London SW1A 1AA",
"contactEmail": "transport@acmehaulage.co.uk",
"publicationDate": "2026-05-15",
"licenceType": "new",
"vehicleCount": 10,
"trailerCount": 5,
"operatingCentreAddress": "Depot Road, London SW1",
"operatingCentrePostcode": "SW1A 1AA",
"trafficArea": "London"
}'Response:
{
"id": "ord_01hwx3n8k2z9m",
"reference": "GZ-2605-0042",
"status": "pending_payment",
"type": "hgv",
"quotedPriceGbpPence": 14400,
"noticeText": "Acme Haulage Ltd of 1 Logistics Park...",
"checkoutUrl": "https://checkout.stripe.com/c/pay/cs_live_...",
"paymentMethod": "stripe_checkout",
"createdAt": "2026-05-01T10:30:00.000Z"
}Complete payment
The response includes a paymentMethod field indicating how payment is handled for your organisation:
| paymentMethod | Action |
|---|---|
stripe_checkout | Redirect user to checkoutUrl |
stripe_invoice | Show invoiceUrl or send to billing contact |
purchase_order | Order is created; await PO reference. No payment URL. |
Handle lifecycle webhooks
Register a webhook URL in Settings → Webhooks to receive order.booked, order.published, and other lifecycle events. See Webhooks for full details and signature verification code.
Authentication
All endpoints except POST /v1/quote require authentication via a Bearer token in the Authorization header.
curl https://gazetted.co.uk/api/v1/orders \
-H "Authorization: Bearer $GAZETTED_API_KEY"Managing API keys
Keys are created and revoked from Settings → API Access. Keys are scoped to your organisation — all members of the org share the same key pool. You can create multiple keys (e.g. one per integration) and revoke individual keys without affecting others.
Key rotation
To rotate a key, generate a new one from the Settings page and update your integration before revoking the old key. There is no automated rotation — you control the lifecycle entirely.
Versioning
The current version is v1, indicated by the /v1/ path prefix. We follow a conservative versioning policy:
- —Non-breaking additions (new optional fields, new endpoints) are made within v1 without notice.
- —Breaking changes (removed fields, changed semantics, new required fields) are introduced as v2 with a deprecation notice and migration period.
- —The v1 base URL will remain available for at least 12 months after v2 ships.
Rate Limits
Each API key is limited to 120 requests per minute. Exceeding this limit returns an HTTP 429 response:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
Content-Type: application/json
{
"error": "Rate limit exceeded. Please try again shortly.",
"code": "rate_limit_exceeded"
}The Retry-After header contains the number of seconds until the rate limit window resets. We recommend exponential backoff with jitter:
Retry-After seconds plus a random jitter of 0–1s. For 5xx errors, retry with backoff: 1s, 2s, 4s, 8s, 16s.Errors
All error responses use a consistent shape:
{
"error": "The requested order was not found.",
"code": "order_not_found",
"details": {
"id": "ord_01hwx3n8k2z9m"
}
}4xx — caller error. Your request is invalid; fix the issue before retrying.
5xx — server error. Retry with backoff. Contact support if it persists.
Error codes
| Code | Status | Description |
|---|---|---|
unauthorized | 401 | Missing or invalid API key. |
forbidden | 403 | API key does not have the required scope. |
rate_limit_exceeded | 429 | Too many requests. Check Retry-After header. |
unsupported_type | 400 | Notice type is not supported via the API. |
validation_error | 400 | One or more request fields failed validation. See details. |
gazette_unavailable | 503 | London Gazette integration is temporarily unavailable. Try again later. |
order_not_found | 404 | Order does not exist or belongs to another organisation. |
order_not_cancellable | 409 | Order is in a status that cannot be cancelled. |
order_not_amendable | 409 | Order cannot be amended at its current status. |
size_growth_not_allowed | 409 | Amendment increases notice size. Pass acceptPriceChange: true to proceed. |
internal_error | 500 | Unexpected server error. Contact support if this persists. |
Endpoint Reference
All endpoints accept and return application/json. Monetary values are integers in pence (GBP). Dates are ISO 8601 strings.
/v1/quoteGet an instant price estimate for a notice type and postcode. No authentication required. Rate-limited to 20 requests/min per IP.
| Field | Type | Required | Description |
|---|---|---|---|
type | string | required | Notice type. One of: hgv, probate, planning, tro, public_path, highways. |
postcode | string | required | UK postcode used to identify the correct local newspaper. |
wordCount | integer | optional | Estimated word count. Used to calculate column size and media cost. |
newspaperName | string | optional | Override the newspaper selection. Must match a known newspaper name. |
curl -X POST https://gazetted.co.uk/api/v1/quote \
-H "Authorization: Bearer $GAZETTED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "probate",
"postcode": "EC2A 1AA",
"wordCount": 120
}'/v1/ordersCreate a new notice order. Scope required: orders:write.
The API generates notice wording from structured fields — you do not supply pre-formatted text. The response includes a checkoutUrl (card billing), invoiceUrl (invoice terms), or neither (purchase order).
Shared fields (all types)
| Field | Type | Required | Description |
|---|---|---|---|
type | string | required | Notice type. One of: hgv, probate, planning, tro, public_path, highways. |
postcode | string | required | Postcode for newspaper lookup. |
applicantName | string | required | Name of the applicant or organisation. |
applicantAddress | string | required | Full address of the applicant. |
contactEmail | string | required | Email address for order notifications. |
publicationDate | string | optional | Requested publication date (ISO 8601). Treated as preferred, not guaranteed. |
clientRef | string | optional | Your internal reference. Stored on the order for reconciliation. |
signOff | string | optional | Optional text appended to the end of the notice. |
licenceType, vehicleCount for HGV; deceasedName for probate) are documented in the OpenAPI spec .curl -X POST https://gazetted.co.uk/api/v1/orders \
-H "Authorization: Bearer $GAZETTED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "hgv",
"postcode": "SW1A 1AA",
"applicantName": "Acme Haulage Ltd",
"applicantAddress": "1 Logistics Park, London SW1A 1AA",
"contactEmail": "transport@acmehaulage.co.uk",
"publicationDate": "2026-05-15",
"licenceType": "new",
"vehicleCount": 10,
"trailerCount": 5,
"operatingCentreAddress": "Depot Road, London SW1",
"operatingCentrePostcode": "SW1A 1AA",
"trafficArea": "London"
}'/v1/ordersList orders for your organisation. Scope required: orders:read. Results are paginated using cursor pagination.
| Field | Type | Required | Description |
|---|---|---|---|
cursor | string | optional | Pagination cursor from previous response's pagination.nextCursor. |
limit | integer | optional | Number of results to return. Default 25, max 100. |
status | string | optional | Filter by order status (e.g. published, booked). |
type | string | optional | Filter by notice type. |
createdAfter | string | optional | ISO 8601 datetime. Return orders created after this time. |
createdBefore | string | optional | ISO 8601 datetime. Return orders created before this time. |
curl "https://gazetted.co.uk/api/v1/orders?limit=10&status=published" \
-H "Authorization: Bearer $GAZETTED_API_KEY"/v1/orders/:idGet full detail for a single order. Scope required: orders:read. Returns 404 order_not_found for orders that don't exist or belong to another organisation (the two cases are intentionally indistinguishable).
/v1/orders/:id/cancelRequest cancellation of an order. Scope required: orders:write. Triggers a Stripe refund if the order has been paid. Not all statuses are cancellable — orders after urn_received cannot be cancelled.
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | optional | Optional cancellation reason. Stored in the audit log. |
curl -X POST https://gazetted.co.uk/api/v1/orders/ord_01hwx3n8k2z9m/cancel \
-H "Authorization: Bearer $GAZETTED_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "Client withdrew instruction" }'/v1/orders/:id/amendAmend the details of a pending or booked order. Scope required: orders:write. Notice text and pricing are recomputed. If the amendment increases the notice size, the request will fail with 409 size_growth_not_allowed unless you pass acceptPriceChange: true.
| Field | Type | Required | Description |
|---|---|---|---|
acceptPriceChange | boolean | optional | Pass true to confirm you accept a price increase from the amendment. |
...fields | varies | optional | Any subset of the original order fields to update. |
/v1/orders/:id/proofDownload the proof PDF for an order. Scope required: orders:read. Returns application/pdf with a Content-Disposition: attachment header.
Webhooks
Webhooks deliver real-time notifications to your server when order statuses change. They are more reliable than polling — polling the orders list frequently may trigger rate limits.
Registering a webhook
Add a webhook URL from Settings → Webhooks. Each webhook has a signing secret shown once at creation — store it securely. You can register multiple webhooks for different event types.
Event types
Every event uses the same envelope — see Payload format for the full schema. The data.object field contains the serialized order at the time the event fired.
| Event | When it fires |
|---|---|
order.created | Order submitted via API or portal. |
order.booked | Notice confirmed with the newspaper; publication date locked in. |
order.published | Publication confirmed by the newspaper; certificate available. |
order.cancelled | Order cancelled. Any payment is refunded via Stripe. |
order.amended | Order fields updated via the amend endpoint; notice text and pricing recomputed. |
order.urn_received | London Gazette URN received (probate notices only). |
order.proof_ready | Proof PDF is ready for review; proofPdfUrl is populated on the order. |
order.delivery_failed | Artwork delivery to the newspaper failed after retries; manual intervention required. |
Payload format
POST https://your-server.com/webhooks/gazetted HTTP/1.1
Content-Type: application/json
X-Gazetted-Signature: t=1714561234,v1=3d5e2b1...
X-Gazetted-Event: order.published
{
"id": "evt_01hwx4ab2c3d",
"event": "order.published",
"createdAt": "2026-05-15T09:00:00.000Z",
"data": {
"orderId": "ord_01hwx3n8k2z9m",
"reference": "GZ-2605-0042",
"status": "published",
"type": "hgv",
"publishedAt": "2026-05-15T09:00:00.000Z",
"certificateUrl": "https://gazetted.co.uk/api/v1/orders/ord_01hwx3n8k2z9m/certificate"
}
}Signature verification
Every webhook request includes an X-Gazetted-Signature header. Verify this to confirm the payload came from Gazetted and was not tampered with.
The signature is t=<timestamp>,v1=<hmac-sha256>. The HMAC is computed over <timestamp>.<rawRequestBody>using your webhook's signing secret.
crypto.timingSafeEqual) — string comparison leaks timing information.import crypto from "crypto";
function verifyGazettedWebhook(
rawBody: string,
signature: string,
secret: string
): boolean {
const parts = Object.fromEntries(
signature.split(",").map((p) => p.split("="))
);
const timestamp = parts["t"];
const expectedSig = parts["v1"];
// Reject if timestamp older than 5 minutes
const age = Date.now() / 1000 - parseInt(timestamp, 10);
if (age > 300) return false;
const payload = `${timestamp}.${rawBody}`;
const computed = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(computed),
Buffer.from(expectedSig)
);
}Retry policy
If your endpoint returns a non-2xx status or times out, Gazetted retries up to 5 times with the following schedule:
| Attempt | Delay |
|---|---|
| 1 (initial) | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
Failed deliveries after all retries are stored as a dead-letter queue entry visible in your webhook settings. You can replay individual events from there.
Best practices
- —Respond with a 2xx status within 3 seconds. Offload processing to a background job.
- —Only return 2xx once you have persisted the event — not before.
- —Handle events idempotently. The same event may arrive multiple times.
- —Filter events by type before processing — ignore events you don't need.
SDKs & Libraries
Official SDKs are on the roadmap. For v1, the curl, Node.js, and Python examples in this reference are the recommended starting point. The API is simple enough that a thin wrapper around fetch or httpx is all you need.
Changelog
v1.0.0 — Initial release
- — POST /v1/quote (unauthenticated)
- — POST /v1/orders, GET /v1/orders, GET /v1/orders/:id
- — POST /v1/orders/:id/cancel, POST /v1/orders/:id/amend
- — GET /v1/orders/:id/proof
- — Webhook delivery with HMAC-SHA256 signing
- — Supported types: hgv, probate, planning, tro, public_path, highways
Status
Live uptime and incident history are available at status.gazetted.co.uk.
For incident alerts, subscribe to updates on the status page. Critical incidents affecting order processing are also communicated by email to affected organisations.
Support
For API integration support, contact support@gazetted.co.uk. Include your organisation name and a description of the issue.
For order-related queries (newspaper deadlines, publication dates, certificates), contact notices@gazetted.co.uk.
Ready to integrate?
API access is available to all organisation accounts. Generate your key from the portal settings.
Go to Settings