---
title: "Send a single message"
method: POST
path: "/v1/messages"
---

# Send a single message

`POST /v1/messages`

## Overview

Use this endpoint to send a single message to an NHS patient.

### References

You must provide a single reference value within the payload to this endpoint that is a message reference.

The message reference (`messageReference`) needs to be unique across all single messages you have sent. This value is used to store your reference for this specific message and can be used if you lose (or do not recieve) our unique identifier in the response.

### Personalisation

You may be required to send through specific personalisation fields based upon the routing plan (`routingPlanId`). These will have been setup during your onboarding process.

These are not validated when we store your message, but will be validated when we attempt to send the message according to the routing plan. If there are values missing from this then the message will fail to send.

### Sandbox

When sending this request on sandbox you must use one of the 6 preconfigured routing plan identifiers:

-   `b838b13c-f98c-4def-93f0-515d4e4f4ee1`
-   `49e43b98-70cb-47a9-a55e-fe70c9a6f77c`
-   `b402cd20-b62a-4357-8e02-2952959531c8`
-   `936e9d45-15de-4a95-bb36-ae163c33ae53`
-   `9ba00d23-cd6f-4aca-8688-00abc85a7980`
-   `00000000-0000-0000-0000-000000000001`

On other environments these values will be established as part of your [NHS Notify onboarding](#overview--onboarding).

Here is an example curl request which creates a message using one of these routing plan identifiers:

```
  curl -X POST \
    --header "Accept: */*" \
    --header "Content-type: application/vnd.api+json" \
    -d '{"data": {"type": "Message","attributes": {"routingPlanId": "b838b13c-f98c-4def-93f0-515d4e4f4ee1","messageReference": "da0b1495-c7cb-468c-9d81-07dee089d728","recipient": {"nhsNumber": "9990548609"},"originator": {"odsCode":"X123"},"personalisation": {},"answerOptions": {"NHSAPP":[{"code":"Yes"},{"code":"No"}]}}}}' \
    https://sandbox.api.service.nhs.uk/comms/v1/messages
```

## Headers

- `Authorization` string, ^Bearer [[:ascii:]]+$
- `X-Correlation-ID` string

## Request body

- object
  - `data` object, required
    - `type` 'Message', required
    - `attributes` object, required
      - `routingPlanId` string, uuid, required — This is the routing plan you wish your message to be sent with. The values available to you for this are setup during your [onboarding process](#overview--onboarding). There are also some global routingPlanIds available, please see the [Free-text communications documentation](#section/Free-text-communications). If you send through an invalid routing plan id you will receive a 404 response.
      - `messageReference` string, required — This is a client-supplied unique reference for this message. This value is used internally to de-duplicate messages. If you send the same value through multiple times only one of the requests will be actioned.
      - `billingReference` string — Optional reference for billing purposes. Can be any string.
      - `recipient` object, required
        - `nhsNumber` string — The [NHS number](https://digital.nhs.uk/services/nhs-number) of the recipient. Only [valid NHS Numbers](https://www.datadictionary.nhs.uk/attributes/nhs_number.html) will be accepted. This will be used to lookup the recipients details with the [Personal Demographics Service](https://digital.nhs.uk/developer/api-catalogue/personal-demographics-service-fhir). Normally a required field, unless prior agreement with the Onboarding team is in place.
        - `contactDetails` object — Overriding contact details is a sensitive action and requires explicit approval from the onboarding team.
          - `email` string — Overriding email address for recipient.
          - `sms` string — Overriding mobile number for the recipient. Must be in a valid UK format or international format with a country code. Learn more about [sending text messages to international numbers](https://notify.nhs.uk/pricing/text-messages#sending-text-messages-to-international-numbers).
          - `address` object — Overriding address.
            - `lines` string[] — Lines of overriding address.
            - `postcode` string — Postcode of overriding address. A required field when address is specified. Must be a valid UK postcode format.
          - `name` object — Overriding name fields for the recipient.
            - `prefix` string — Prefix of overriding name.
            - `firstName` string — First name of overriding name.
            - `middleNames` string — Middle names of overriding name.
            - `lastName` string — Last name of overriding name. A required field when name is specified.
            - `suffix` string — Suffix of overriding name.
      - `originator` object
        - `odsCode` string — ODS code used to identify the sender when using the NHS App channel (allowOdsOverride must be enabled on the corresponding NHS Notify client).
      - `personalisation` object — The personalisation keys and values for this message. These are linked to the routingPlanId provided and are agreed upon during [onboarding](#overview--onboarding).
      - `answerOptions` object — The answer options for this message. These are channel specific. If you provide answer options, then they will be presented to the receipient for reply options. These will then be sent back via the two-way messaging callback mechanism. This feature needs to be enabled on your account and is subject to the relevant callback integration being completed.
        - `NHSAPP` object[]
          - `code` string — This is the code that will be sent back to you in the callback when a recipient selects this option. It is for your reference to understand which option the recipient has selected. It is also the display value shown to the recipient.

## Response `201`

Your message has been created. The backend service will process the message according to the routing plan identified in the request.

The response includes both your `messageReference` and our message `id`. You should store the `id` in your database.

- object
  - `data` object
    - `type` Type, required — unresolved $ref
    - `id` Schema, required — unresolved $ref
    - `attributes` object, required
      - `messageReference` string, required — Your unique message reference, provided within the payload to create this message.
      - `messageStatus` 'created', required — The status of your message.
      - `timestamps` object, required
        - `created` string, date-time, required — The date and time that your message was created at.
      - `routingPlan` RoutingPlan, required — unresolved $ref
    - `links` object, required — Contains links to related objects.
      - `self` string, uri, required — URI of this message.

## Other responses

- `400` — A validation error has occurred with the request body sent. Up to 100 validation errors will be returned, if there are more than 100 validation errors then the first 100 will be returned. The following validation errors can occur: | Error code | Title | Description | | ---------- | ----- | ----------- | | `CM_MISSING_VALUE` | Missing property | The property at the specified location is required, but was not present in the request. | | `CM_NULL_VALUE` | Property cannot be null | The property at the specified location is required, but a null value was passed in the request. | | `CM_INVALID_VALUE` | Invalid value | The property at the specified location does not allow this value. | | `CM_INVALID_NHS_NUMBER` | Invalid nhs number | The value provided in this nhsNumber field is not a valid NHS number. | | `CM_ODS_CODE_REQUIRED` | Originator odsCode must be provided | An originator with odsCode must be provided, as your account does not have a default ODS code. | | `CM_CANNOT_SET_ODS_CODE` | Cannot set ODS code | Your account is not permitted to set originator ODS codes. | | `CM_CANNOT_SET_CONTACT_DETAILS` | Cannot set contact details | Your account is not allowed to provide alternative contact details. | Within each error is a source object which details the location of the error within your request body. This is done using a pointer that uses the [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) as per the [JSON:API Error Specification](https://jsonapi.org/format/#errors). ### Sandbox It is possible to trigger some of the errors in the sandbox by sending the header `Authorization` with certain values. Here is an example curl request to trigger a `CM_CANNOT_SET_ODS_CODE`: ``` curl -X POST \ --header "Accept: */*" \ --header "Content-type: application/vnd.api+json" \ --header "Authorization: noOdsChange" \ -d '{"data": {"type": "Message","attributes": {"routingPlanId": "b838b13c-f98c-4def-93f0-515d4e4f4ee1","messageReference": "da0b1495-c7cb-468c-9d81-07dee089d728","recipient": {"nhsNumber": "9990548609"},"originator": {"odsCode":"X123"},"personalisation": {}}}}' \ https://sandbox.api.service.nhs.uk/comms/v1/messages ``` Here is an example curl request to trigger a `CM_CANNOT_SET_CONTACT_DETAILS`: ``` curl -X POST \ --header "Accept: */*" \ --header "Content-type: application/vnd.api+json" \ --header "Authorization: notAllowedContactDetailOverride" \ -d '{"data": {"type": "Message","attributes": {"routingPlanId": "b838b13c-f98c-4def-93f0-515d4e4f4ee1","messageReference": "da0b1495-c7cb-468c-9d81-07dee089d728","recipient": {"nhsNumber": "9990548609","contactDetails": {"sms": "07777000000"}},"personalisation": {}}}}' \ https://sandbox.api.service.nhs.uk/comms/v1/messages ```
- `401` — Your request was not authorized - you need to send a `Authorization` header with a valid `Bearer` token. See the documentation on [how to generate a valid token](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/application-restricted-restful-apis-signed-jwt-authentication). ### Sandbox It is possible to trigger this error in the sandbox by sending the header `Prefer` with a value of `code=401`. Here is an example curl request to trigger a `401`: ``` curl -X GET \ --header "Accept: */*" \ --header "Prefer: code=401" \ https://sandbox.api.service.nhs.uk/comms/ ```
- `403` — Your request contained an authentic bearer token in the `Authorization` header but you are not authorized to make the request. If the error code in the response is `CM_FORBIDDEN` then this could be due to the onboarding process not having been completed. Refer to our [onboarding](#overview--onboarding) section for more information. If the response contains the error `CM_SERVICE_BAN` then there is a ban in effect on your account. ### Sandbox It is possible to trigger the `CM_FORBIDDEN` error in the sandbox by sending the header `Prefer` with a value of `code=403`. Here is an example curl request to trigger a `CM_FORBIDDEN`: ``` curl -X GET \ --header "Accept: */*" \ --header "Prefer: code=403" \ https://sandbox.api.service.nhs.uk/comms/ ``` To trigger the `CM_SERVICE_BAN` error in the sandbox by sending the header `Prefer` with a value of `code=403.1`. Here is an example curl request to trigger a `CM_SERVICE_BAN`: ``` curl -X GET \ --header "Accept: */*" \ --header "Prefer: code=403.1" \ https://sandbox.api.service.nhs.uk/comms/ ```
- `404` — The routing plan identifier passed in the body has not been found. When you [onboarded](#overview--onboarding) onto the service a number of valid routing plan identifiers were issued to you. You must use one of these valid routing plan identifiers when requesting for a message to be sent. ### Sandbox On the sandbox environment there are 5 valid routing plan identifiers that can be used by anybody calling the API. These are: * `b838b13c-f98c-4def-93f0-515d4e4f4ee1` * `49e43b98-70cb-47a9-a55e-fe70c9a6f77c` * `b402cd20-b62a-4357-8e02-2952959531c8` * `936e9d45-15de-4a95-bb36-ae163c33ae53` * `9ba00d23-cd6f-4aca-8688-00abc85a7980` If you use a routing plan id that is not in this list then a `404 Not Found` error response will be triggered. On other environments these values will be established as part of your [NHS Notify onboarding](#overview--onboarding). Here is an example curl request to trigger a `404`: ``` curl -X POST \ --header "Accept: */*" \ --header "Content-type: application/vnd.api+json" \ -d '{"data": {"type": "Message","attributes": {"routingPlanId": "868796f9-7ce3-4730-9f1e-23aa766edea3","messageReference": "da0b1495-c7cb-468c-9d81-07dee089d728","recipient": {"nhsNumber": "9990548609"},"originator": {"odsCode":"X123"},"personalisation": {}}}}' \ https://sandbox.api.service.nhs.uk/comms/v1/messages ```
- `405` — Your request specified a method that was not allowed on this endpoint. Endpoints only allow certain methods to be called on them. If your method was not one of the allowed ones it will be rejected with this status code.
- `406` — The request did not contain a valid `Accept` header value. Valid values are: * `*/*` * `application/json` * `application/vnd.api+json` * `application/json; charset=utf-8` * `application/vnd.api+json; charset=utf-8` Where no `Accept` header is present, this will default to `application/vnd.api+json`
- `408` — There has been a client side issue reading your request. This can occur when there are networking issues between your application and our service. There may also be an issue within our backend where a `408` has been bubbled up and exposed. This could be indicative of an ongoing infrastructure issue that is out of our (or your) control. ### Sandbox It is possible to simulate this error response by sending a request with a header of `Prefer` set to the value `code=408`. Here is an example curl request to simulate this response: ``` curl -X GET --header "Prefer: code=408" https://sandbox.api.service.nhs.uk/comms/ ```
- `415` — The `Content-Type` of the request is not supported. This endpoint supports: * `application/json` * `application/vnd.api+json` * `application/json; charset=utf-8` * `application/vnd.api+json; charset=utf-8`
- `422` — Request already received and it will be ignored. Note that NHS Notify retains details of your original request for up to 9 months. Duplicate submissions received after this period will still be accepted. ### Sandbox It is possible to trigger this on the sandbox by using the `Prefer` header with a value of `code=422_message`. Here is an example curl request to trigger a `422`: ``` curl -X GET --header "Prefer: code=422_message" https://sandbox.api.service.nhs.uk/comms/ ```
- `425` — You have retried this request too early, the previous request is still being processed. Re-send the request after the time (in seconds) specified in the `Retry-After` header. ### Sandbox It is possible to trigger this on the sandbox by using the `Prefer` header with a value of `code=425`. Here is an example curl request to trigger a `425`: ``` curl -X GET --header "Prefer: code=425" https://sandbox.api.service.nhs.uk/comms/ ```
- `429` — You have made too many requests too quickly, you must send requests at a slower rate. If you have a retry mechanism in your HTTP client you may want to look at implementing an [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) or you can use the `Retry-After` response header to determine when you should retry your request. ### Sandbox It is possible to trigger this on the sandbox by using the `Prefer` header with a value of `code=429`. Here is an example curl request to trigger a `429`: ``` curl -X GET --header "Prefer: code=429" https://sandbox.api.service.nhs.uk/comms/ ```
- `500` — An error has occured that is stopping your request from being processed. These errors may be thrown while the system is still being configured for your use, or a misconfiguration has occurred. The following errors can occur: | Error code | Title | Description | | ---------- | ----- | ----------- | | `CM_MISSING_ROUTING_PLAN_TEMPLATE` | Templates missing | The templates required to use the routing plan were not found. | | `CM_ROUTING_PLAN_DUPLICATE_TEMPLATES` | Duplicate templates | The routing plan specified contains duplicate templates. | | `CM_INTERNAL_SERVER_ERROR` | Error processing request | There was an internal error whilst processing this request. | Within each error is a source object which details the location of the error within your request body. Certain errors may include an extra set of metadata to assist you with resolving the problem. This is done using a pointer that uses the [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) as per the [JSON:API Error Specification](https://jsonapi.org/format/#errors). ### Sandbox It is possible to simulate these errors by sending requests with specific routing plan identifiers. To trigger the `CM_MISSING_ROUTING_PLAN_TEMPLATE` error use routing plan id `c8857ccf-06ec-483f-9b3a-7fc732d9ad48` or `aeb16ab8-cb9c-4d23-92e9-87c78119175c`. Here is an example curl request to simulate the response: ``` curl -X POST \ --header "Accept: */*" \ --header "Content-type: application/vnd.api+json" \ -d '{"data": {"type": "Message","attributes": {"routingPlanId": "c8857ccf-06ec-483f-9b3a-7fc732d9ad48","messageReference": "da0b1495-c7cb-468c-9d81-07dee089d728","recipient": {"nhsNumber": "9990548609"},"originator": {"odsCode":"X123"},"personalisation": {}}}}' \ https://sandbox.api.service.nhs.uk/comms/v1/messages ``` To trigger the `CM_ROUTING_PLAN_DUPLICATE_TEMPLATES` error use routing plan id `a3a4e55d-7a21-45a6-9286-8eb595c872a8`. Here is an example curl request to simulate the response: ``` curl -X POST \ --header "Accept: */*" \ --header "Content-type: application/vnd.api+json" \ -d '{"data": {"type": "Message","attributes": {"routingPlanId": "a3a4e55d-7a21-45a6-9286-8eb595c872a8","messageReference": "da0b1495-c7cb-468c-9d81-07dee089d728","recipient": {"nhsNumber": "9990548609"},"originator": {"odsCode":"X123"},"personalisation": {}}}}' \ https://sandbox.api.service.nhs.uk/comms/v1/messages ``` It is possible to trigger the `CM_INTERNAL_SERVER_ERROR` on the sandbox by using the `Prefer` header with a value of `code=500`. Here is an example curl request to trigger a `500`: ``` curl -X GET --header "Prefer: code=500" https://sandbox.api.service.nhs.uk/comms/ ```
- `503` — The service is currently not accepting requests, This error can occur if any part of the system has gone offline. ### Sandbox It is possible to simulate this error response by sending a request with a header of `Prefer` set to the value `code=503`. Here is an example curl request to simulate this response: ``` curl -X GET --header "Prefer: code=503" https://sandbox.api.service.nhs.uk/comms/ ```
- `504` — There is an issue communicating to our backend services. If this occurs it is a good idea to back off and retry the request at a later time - see the [Circuit Breaker pattern](https://microservices.io/patterns/reliability/circuit-breaker.html). This error can occur if there is an issue with a dependent service and so may be bubbled up from a 3rd party HTTP call. ### Sandbox It is possible to simulate this error response by sending a request with a header of `Prefer` set to the value `code=504`. Here is an example curl request to simulate this response: ``` curl -X GET --header "Prefer: code=504" https://sandbox.api.service.nhs.uk/comms/ ``` To simulate a backend `504` exception bubbling upwards you can send this request: ``` curl -X GET https://sandbox.api.service.nhs.uk/comms/_timeout_504 ```

---

[API](https://skmtc.dev/nhs/apis/communications-manager-api.md) · [All operations](https://skmtc.dev/nhs/apis/communications-manager-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/nhs/communications-manager-api/revisions/286b22343680/schema)
