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

Premises Licence notices are not supported via the API. They require custom wording per application and cannot be safely template-generated. Use the portal to place Premises Licence notices.

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.

1

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.

API keys begin with 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_xxxx
2

Get 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
  }
}
3

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"
}
4

Complete payment

The response includes a paymentMethod field indicating how payment is handled for your organisation:

paymentMethodAction
stripe_checkoutRedirect user to checkoutUrl
stripe_invoiceShow invoiceUrl or send to billing contact
purchase_orderOrder is created; await PO reference. No payment URL.
5

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.

API keys provide full access to your organisation's orders. Store them in environment variables or a secrets manager. Never commit them to source control or expose them in client-side code.

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:

Recommended retry strategy: On 429, wait 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

CodeStatusDescription
unauthorized401Missing or invalid API key.
forbidden403API key does not have the required scope.
rate_limit_exceeded429Too many requests. Check Retry-After header.
unsupported_type400Notice type is not supported via the API.
validation_error400One or more request fields failed validation. See details.
gazette_unavailable503London Gazette integration is temporarily unavailable. Try again later.
order_not_found404Order does not exist or belongs to another organisation.
order_not_cancellable409Order is in a status that cannot be cancelled.
order_not_amendable409Order cannot be amended at its current status.
size_growth_not_allowed409Amendment increases notice size. Pass acceptPriceChange: true to proceed.
internal_error500Unexpected 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.

POST/v1/quote

Get an instant price estimate for a notice type and postcode. No authentication required. Rate-limited to 20 requests/min per IP.

FieldTypeRequiredDescription
typestringrequiredNotice type. One of: hgv, probate, planning, tro, public_path, highways.
postcodestringrequiredUK postcode used to identify the correct local newspaper.
wordCountintegeroptionalEstimated word count. Used to calculate column size and media cost.
newspaperNamestringoptionalOverride 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
  }'
POST/v1/orders

Create 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)

FieldTypeRequiredDescription
typestringrequiredNotice type. One of: hgv, probate, planning, tro, public_path, highways.
postcodestringrequiredPostcode for newspaper lookup.
applicantNamestringrequiredName of the applicant or organisation.
applicantAddressstringrequiredFull address of the applicant.
contactEmailstringrequiredEmail address for order notifications.
publicationDatestringoptionalRequested publication date (ISO 8601). Treated as preferred, not guaranteed.
clientRefstringoptionalYour internal reference. Stored on the order for reconciliation.
signOffstringoptionalOptional text appended to the end of the notice.
Type-specific fields (e.g. 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"
  }'
GET/v1/orders

List orders for your organisation. Scope required: orders:read. Results are paginated using cursor pagination.

FieldTypeRequiredDescription
cursorstringoptionalPagination cursor from previous response's pagination.nextCursor.
limitintegeroptionalNumber of results to return. Default 25, max 100.
statusstringoptionalFilter by order status (e.g. published, booked).
typestringoptionalFilter by notice type.
createdAfterstringoptionalISO 8601 datetime. Return orders created after this time.
createdBeforestringoptionalISO 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"
GET/v1/orders/:id

Get 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).

POST/v1/orders/:id/cancel

Request 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.

FieldTypeRequiredDescription
reasonstringoptionalOptional 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" }'
POST/v1/orders/:id/amend

Amend 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.

FieldTypeRequiredDescription
acceptPriceChangebooleanoptionalPass true to confirm you accept a price increase from the amendment.
...fieldsvariesoptionalAny subset of the original order fields to update.
GET/v1/orders/:id/proof

Download 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.

EventWhen it fires
order.createdOrder submitted via API or portal.
order.bookedNotice confirmed with the newspaper; publication date locked in.
order.publishedPublication confirmed by the newspaper; certificate available.
order.cancelledOrder cancelled. Any payment is refunded via Stripe.
order.amendedOrder fields updated via the amend endpoint; notice text and pricing recomputed.
order.urn_receivedLondon Gazette URN received (probate notices only).
order.proof_readyProof PDF is ready for review; proofPdfUrl is populated on the order.
order.delivery_failedArtwork 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.

Reject webhooks with a timestamp older than 5 minutes to prevent replay attacks. Always use a timing-safe comparison function (e.g. 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:

AttemptDelay
1 (initial)Immediate
21 minute
35 minutes
430 minutes
52 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.

If you build an unofficial SDK or integration and would like it listed here, contact support@gazetted.co.uk.

Changelog

2026-05-01

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