Skip to main content

Overview

Callback endpoints allow services to register webhooks that GOV.UK Notify will call when specific events occur (delivery receipts, inbound SMS, returned letters). Base URL: /service/{service_id}/callback-api

Callback Types

  • delivery_status - Delivery receipt callbacks
  • inbound_sms - Inbound SMS callbacks
  • returned_letter - Returned letter callbacks
  • complaint - Email complaint callbacks

Create Callback

Endpoint: POST /service/{service_id}/callback-api Register a new callback URL for a service.

Path Parameters

  • service_id (UUID, required) - Service identifier

Request Body

{
  "url": "https://example.com/callbacks/notify",
  "bearer_token": "your-bearer-token-min-10-chars",
  "updated_by_id": "6ce466d0-fd6a-11e5-82f5-e0accb9d11a6",
  "callback_type": "delivery_status"
}
Fields:
  • url (string, required) - HTTPS callback URL
  • bearer_token (string, required) - Bearer token (minimum 10 characters)
  • updated_by_id (UUID, required) - User who created the callback
  • callback_type (string, optional) - Type of callback

Response

Status: 201 Created
{
  "data": {
    "id": "1234abcd-5678-90ef-ghij-klmnopqrstuv",
    "service_id": "6ce466d0-fd6a-11e5-82f5-e0accb9d11a6",
    "url": "https://example.com/callbacks/notify",
    "bearer_token": "your-bearer-token-min-10-chars",
    "callback_type": "delivery_status",
    "created_at": "2026-03-03T10:30:00.000000Z",
    "updated_at": null,
    "updated_by_id": "6ce466d0-fd6a-11e5-82f5-e0accb9d11a6"
  }
}

Error Responses

Status: 400 Bad Request
{
  "result": "error",
  "message": {
    "name": ["You can only have one URL and bearer token for your service."]
  }
}
Returned when a callback of the same type already exists for this service. Status: 404 Not Found
{
  "result": "error",
  "message": "No result found"
}
Returned when the service_id doesn’t exist.

Update Callback

Endpoint: POST /service/{service_id}/callback-api/{callback_api_id} Update an existing callback configuration.

Path Parameters

  • service_id (UUID, required) - Service identifier
  • callback_api_id (UUID, required) - Callback API identifier

Request Body

{
  "url": "https://example.com/callbacks/notify-v2",
  "bearer_token": "new-bearer-token-value",
  "updated_by_id": "6ce466d0-fd6a-11e5-82f5-e0accb9d11a6",
  "callback_type": "delivery_status"
}
Fields:
  • updated_by_id (UUID, required) - User making the update
  • callback_type (string, required) - Type of callback
  • url (string, optional) - New callback URL
  • bearer_token (string, optional) - New bearer token

Response

Status: 200 OK
{
  "data": {
    "id": "1234abcd-5678-90ef-ghij-klmnopqrstuv",
    "service_id": "6ce466d0-fd6a-11e5-82f5-e0accb9d11a6",
    "url": "https://example.com/callbacks/notify-v2",
    "bearer_token": "new-bearer-token-value",
    "callback_type": "delivery_status",
    "created_at": "2026-03-03T10:30:00.000000Z",
    "updated_at": "2026-03-03T14:15:00.000000Z",
    "updated_by_id": "6ce466d0-fd6a-11e5-82f5-e0accb9d11a6"
  }
}

Get Callback

Endpoint: GET /service/{service_id}/callback-api/{callback_api_id} Retrieve a callback configuration.

Path Parameters

  • service_id (UUID, required) - Service identifier
  • callback_api_id (UUID, required) - Callback API identifier

Query Parameters

  • callback_type (string, optional) - Type of callback to retrieve

Response

Status: 200 OK
{
  "data": {
    "id": "1234abcd-5678-90ef-ghij-klmnopqrstuv",
    "service_id": "6ce466d0-fd6a-11e5-82f5-e0accb9d11a6",
    "url": "https://example.com/callbacks/notify",
    "bearer_token": "your-bearer-token-min-10-chars",
    "callback_type": "delivery_status",
    "created_at": "2026-03-03T10:30:00.000000Z",
    "updated_at": null,
    "updated_by_id": "6ce466d0-fd6a-11e5-82f5-e0accb9d11a6"
  }
}

Delete Callback

Endpoint: DELETE /service/{service_id}/callback-api/{callback_api_id} Delete a callback configuration.

Path Parameters

  • service_id (UUID, required) - Service identifier
  • callback_api_id (UUID, required) - Callback API identifier

Query Parameters

  • callback_type (string, optional) - Type of callback to delete

Response

Status: 204 No Content No response body on successful deletion.

Error Responses

Status: 404 Not Found
{
  "errors": [
    {
      "error": "InvalidRequest",
      "message": "Service delivery receipt API not found"
    }
  ]
}
Error messages vary by callback type:
  • delivery_status: “Service delivery receipt API not found”
  • inbound_sms: “Service inbound API not found”
  • returned_letter: “Service returned letter API not found”

Implementation Notes

Security

  • Bearer tokens are encrypted before storage (see /home/daytona/workspace/source/app/models.py:886)
  • All callback URLs must use HTTPS
  • Bearer token minimum length is 10 characters

Constraints

  • Each service can only have one callback URL per callback type
  • The service_id and callback_type combination must be unique
  • Database constraint: uix_service_callback_type

Source Code References

  • Endpoints: /home/daytona/workspace/source/app/service/callback_rest.py
  • Schema validation: /home/daytona/workspace/source/app/service/service_callback_api_schema.py
  • Model: /home/daytona/workspace/source/app/models.py:886
  • DAO operations: /home/daytona/workspace/source/app/dao/service_callback_api_dao.py

Build docs developers (and LLMs) love