CTC Traders API
Date | Amount |
---|---|
Version and status | |
Available in Sandbox | Yes |
Sandbox base URL | https://test-api.service.hmrc.gov.uk |
Available in Production | Yes |
Production base URL | https://api.service.hmrc.gov.uk |
Overview
This API will allow you to send departure and arrival movement notifications to the New Computerised Transit System (NCTS). It will also let you retrieve messages sent from the offices of departure and destination.
We have now released the API with working arrivals and departures endpoints for Great Britain and Northern Ireland. You can now also run tests for Great Britain and Northern Ireland movements in HMRC's sandbox environment.
- Read our Roadmap for important dates and service updates
- Read our Service Guide to the CTC Traders API
- Read our step by step Testing Guide to learn how to test your software and ensure it is compatible
Further details of the User Restricted Authentication are given on the Authorisation page.
For more information about how to develop your own client applications, including example clients for this API, see Tutorials.
Versioning
When an API changes in a way that is backwards-incompatible, we increase the version number of the API. See our reference guide for more on versioning.
Percent-encoding of parameters in request URLs
When writing code to use date filters in request URLs, you must always use percent-encoding. This is because some common characters used in dates and timestamps are not allowed to be used in URLs.
If you do not use percent-encoding you will get a 400 Bad Request as a default response.
For example:
- the timestamp
2021-06-21T09:00+00:00
should be encoded as2021-06-21T09%3A00%2B00%3A00
When formatting query parameters into the request URL for date and time filtering functionality, you must only use the date and time format as specified in Developer Hub. You’ll then be using the common ISO 8601 standard 2021-06-21T09:00+00:00
that is compatible with our CTC Traders API.
Here are more examples in different programming languages:
Java
java.net.URLEncoder.encode("2021-04-30T16:08:31+00:00");
Python:
from urllib.parse import quote
quote('2021-04-30T16:08:31+00:00')
C#:
Uri.EscapeDataString("2021-04-30T16:08:31+00:00");
When sending requests to HMRC APIs you must always use percent-encoding within the URL to avoid getting any 400 Bad Requests.
You should also note:
- some common data types described in the Reference Guide on Developer Hub contain characters that are not valid for use in URLs
- some software libraries do the percent-encoding for you automatically when you develop software using their facilities. Your web framework might also do this automatically for you
Find out more
There are many frameworks and libraries that can handle percent-encoding for you. For background information about percent-encoding, we recommend you read (all links open in a new window):
Push Pull notifications
You can use our Push Pull Notification Service to receive notifications of new messages from NCTS.
- if your endpoint is hosted by Amazon Web Services (AWS) then you must either use edge-optimised custom domain names or regional custom domain names
- this new functionality will send you a notification each time there is a new message for you to read
- for messages less than 100KB the Push Notification will contain the message body
- the Push Notification will have a field containing the messageURI
- you can then use this URI to download the XML message from the CTC Traders API
Using this functionality will save you time and resources by not having to poll for new messages.
Errors
Here is the list of error codes that we will keep updating. We use standard HTTP status codes to show whether an API request has succeeded or not:
POST
400 BadRequest: XML has failed validation - see response body for details
401 Unauthorized: If client passes invalid auth credentials
403 Forbidden: If supplied auth token doesn't contain valid enrolment
404 Not Found: If no object with specified ID found in database
415 Unsupported Media Type: If the client specified an invalid Content-Type
header
500 Internal Server Error: If exception in code occurs
501 Not Implemented: If user attempts to POST
a message and the message type isn't currently supported
PUT
400 BadRequest: If XML message is invalid
401 Unauthorized: If client passes invalid auth credentials
403 Forbidden: If supplied auth token doesn't contain valid enrolment
404 Not Found: If no object with specified ID found in database
415 Unsupported Media Type: If the client specified an invalid Content-Type
header
500 Internal Server Error: If exception in code occurs
GET
401 Unauthorized: If client passes invalid auth credentials
403 Forbidden: If supplied auth token doesn't contain valid enrolment
404 Not Found: If no object with specified ID found in database. Or if client passes in an Accept
header which contains the wrong API version number. We have only released version 1.0 of the API
415 Unsupported Media Type: If Accept
header contains invalid type
500 Internal Server Error: If exception in code occurs
Errors specific to each API are shown in the Endpoints section, under Response. See our reference guide for more on errors.
Endpoints
/customs/transits/movements/arrivals
Get all Movement Arrivals
GET
Get all Movement Arrivals.
You may opt to filter this list of Arrivals so that you only receive Movement Arrivals that have been updated since a specified date and time.
Any Movement Arrivals more than 28 days old will have been archived along with their related messages. Archived movements will return an HTTP 404 Not Found status. You will only be able to retrieve these messages if you have the correct Economic Operator Registration and Identification (EORI) number for that Movement Arrival.
Query parameters
Name | Description |
---|---|
updatedSince
datetime
optional
|
This is an optional filtering parameter. It allows you to request only the Movement Arrivals which have been updated since the date and time you have given us.
For example: |
Request headers
Name | Description |
---|---|
Accept
required
|
Specifies the response format, which must be JSON, and the version of the API to be used. application/vnd.hmrc.1.0+json
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 200 (OK)
{ "_links": { "self": { "href": "/customs/transits/movements/arrivals" } }, "_embedded": { "arrivals": [ { "id": "1", "created": "2020-02-02T02:02:02", "updated": "2020-02-02T02:02:02", "movementReferenceNumber": "MRN", "_links": { "self": { "href": "/customs/transits/movements/arrivals/1" }, "messages": { "href": "/customs/transits/movements/arrivals/1/messages" } } }, { "id": "2", "created": "2020-02-04T02:02:02", "updated": "2020-02-04T02:02:02", "movementReferenceNumber": "MRN", "_links": { "self": { "href": "/customs/transits/movements/arrivals/2" }, "messages": { "href": "/customs/transits/movements/arrivals/2/messages" } } } ], "retrievedArrivals": 2, "totalArrivals": 2 } }
Error scenarios
Scenario | HTTP status | Code |
---|---|---|
The accept header is missing or invalid |
406 (Not Acceptable) |
ACCEPT_HEADER_INVALID |
For error scenarios that are common across all APIs, and for error formats, see our reference guide.
Close Section
/customs/transits/movements/arrivals
Send an Arrival Notification message
POST
Send a notification to let the office at destination know that the goods have arrived.
This notification will be sent when the goods reach their final destination. It is also called an E_ARR_NOT (IE007).
The response will contain a URI and arrival ID for the Arrival Notification. This will allow you to get the message status.
The response will also contain an embedded requestId, boxId and boxName which will allow you to match this movement to any messages received via the Push Pull Notifications Service.
If the user is not enrolled for an Economic Operator Registration and Identification number, they will receive an HTTP 403 Forbidden status.
Request headers
Name | Description |
---|---|
Content-Type
required
|
Specifies the format of the request body, which must be XML. application/xml
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 202 (Accepted)
{ "_links": { "self": { "href": "/customs/transits/movements/arrivals/1" } }, "arrivalId": "1", "messageType": "IE007", "body": "<CC007A>...</CC007A>", "_embedded": { "notifications":{ "boxId":"1234-5678-abcd-def", "requestId":"/customs/transits/movements/arrivals/1", "boxName":"customs/transits##1.0##notificationUrl" } } }
Close Section
/customs/transits/movements/arrivals/{arrivalId}
Get a Movement Arrival for an arrival ID
GET
Get a specific Movement Arrival. Any Movement Arrivals more than 28 days old will be haven archived along with their related messages. Archived movements will return an HTTP 404 Not Found status.
You will only be able to retrieve these messages if you have the correct Economic Operator Registration and Identification (EORI) number for that Movement Arrival.
Path parameters
Name | Description |
---|---|
arrivalId
string
required
|
The arrival ID specifying the arrival to return
For example: |
Request headers
Name | Description |
---|---|
Accept
required
|
Specifies the response format, which must be JSON, and the version of the API to be used. application/vnd.hmrc.1.0+json
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 200 (OK)
{ "id": "1", "created": "2020-10-10T10:10:10", "updated": "2020-12-12T12:12:12", "movementReferenceNumber": "MRN", "_links": { "self": { "href": "/customs/transits/movements/arrivals/1" }, "messages": { "href": "/customs/transits/movements/arrivals/1/messages" } } }
Error scenarios
Scenario | HTTP status | Code |
---|---|---|
The accept header is missing or invalid |
406 (Not Acceptable) |
ACCEPT_HEADER_INVALID |
For error scenarios that are common across all APIs, and for error formats, see our reference guide.
Close Section
/customs/transits/movements/arrivals/{arrivalId}
Resubmit an Arrival Notification message
PUT
Resubmit an Arrival Notification to let the office at destination know that the goods have arrived. This message will be sent when the goods reach their final destination. It is also called an E_ARR_NOT (IE007).
The response will contain an arrival ID for the Arrival Notification. This will allow you to get the message status.
If the user is not enrolled for an Economic Operator Registration and Identification number, they will receive an HTTP 403 Forbidden status.
Path parameters
Name | Description |
---|---|
arrivalId
string
required
|
The arrival ID specifying the arrival to return
For example: |
Request headers
Name | Description |
---|---|
Content-Type
required
|
Specifies the format of the request body, which must be XML. application/xml
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 202 (Accepted)
{ "_links": { "self": { "href": "/customs/transits/movements/arrivals/1" } }, "arrivalId": "1", "messageType": "IE007", "body": "<CC007A>...</CC007A>" }
Close Section
/customs/transits/movements/arrivals/{arrivalId}/messages
Get all messages that relate to a Movement Arrival
GET
Get all the messages to do with a Movement Arrival. Any Movement Arrivals more than 28 days old will have been archived along with their related messages. Archived movements will return an HTTP 404 Not Found status.
You may opt to filter this list of messages so that you only receive messages that have been received since a specified date and time.
You will only be able to retrieve these messages if you have the correct Economic Operator Registration and Identification (EORI) number for that Movement Arrival.
Path parameters
Name | Description |
---|---|
arrivalId
string
required
|
The arrival ID specifying the arrival to return
For example: |
Query parameters
Name | Description |
---|---|
receivedSince
datetime
optional
|
This is an optional filtering parameter. It allows you to request only the messages relating to a Movement Arrival which have been received since the date and time you have given us.
For example: |
Request headers
Name | Description |
---|---|
Accept
required
|
Specifies the response format, which must be JSON, and the version of the API to be used. application/vnd.hmrc.1.0+json
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 200 (OK)
{ "_links": { "self": { "href": "/customs/transits/movements/arrivals/1/messages" } }, "_embedded": { "messages": [ { "_links": { "self": { "href": "/customs/transits/movements/arrivals/1/messages/1" }, "arrival": { "href": "/customs/transits/movements/arrivals/1" } }, "arrivalId": "1", "messageId": "1", "received": "2020-12-12T12:12:15", "messageType": "IE007", "body": "<CC007A>...</CC007A>" } ], "arrival": { "id": "1", "created": "2020-10-10T10:10:10", "updated": "2020-12-12T12:12:12", "movementReferenceNumber": "MRN", "_links": { "self": { "href": "/customs/transits/movements/arrivals/1" }, "messages": { "href": "/customs/transits/movements/arrivals/1/messages" } } } } }
Error scenarios
Scenario | HTTP status | Code |
---|---|---|
The accept header is missing or invalid |
406 (Not Acceptable) |
ACCEPT_HEADER_INVALID |
For error scenarios that are common across all APIs, and for error formats, see our reference guide.
Close Section
/customs/transits/movements/arrivals/{arrivalId}/messages
/customs/transits/movements/arrivals/{arrivalId}/messages/{messageId}
Get a message relating to a Movement Arrival and message ID
GET
Get all messages relating to a specific Movement Arrival and message ID. For example, this could include messages about route diversions or unloading permissions. Any Movement Arrivals more than 28 days old will have been archived along with their related messages. Archived movements will return an HTTP 404 Not Found status.
You will only be able to retrieve these messages if you have the correct Economic Operator Registration and Identification (EORI) number for that Movement Arrival.
Path parameters
Name | Description |
---|---|
arrivalId
string
required
|
The arrival ID specifying the arrival to return
For example: |
messageId
string
required
|
The message ID specifying the message to return
For example: |
Request headers
Name | Description |
---|---|
Accept
required
|
Specifies the response format, which must be JSON, and the version of the API to be used. application/vnd.hmrc.1.0+json
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 200 (OK)
{ "_links": { "self": { "href": "/customs/transits/movements/arrivals/1/messages/1" }, "arrival": { "href": "/customs/transits/movements/arrivals/1" } }, "arrivalId": "1", "messageId": "1", "received": "2020-10-10T10:10:10", "messageType": "IE007", "body": "<CC007A>...</CC007A>" }
Error scenarios
Scenario | HTTP status | Code |
---|---|---|
The accept header is missing or invalid |
406 (Not Acceptable) |
ACCEPT_HEADER_INVALID |
For error scenarios that are common across all APIs, and for error formats, see our reference guide.
Close Section
/customs/transits/movements/departures
Get all Movement Departures
GET
You may opt to filter this list of Departures so that you only receive Movement Departures that have been updated since a specified date and time.
Get all Movement Departures sent to the office at departure within 28 days of the goods being released at their final destination. Any movement more than 28 days old will have been archived along with their related messages. Archived Movements will return an HTTP 404 Not Found status.
You will only be able to retrieve these messages if you have the correct Economic Operator Registration and Identification (EORI) number for that Movement Departure.
Note: The 'movementReferenceNumber' field will only be populated when an MRN is allocated.
Query parameters
Name | Description |
---|---|
updatedSince
datetime
optional
|
This is an optional filtering parameter. It allows you to request only the Movement Departures which have been updated since the date and time you have given us.
For example: |
Request headers
Name | Description |
---|---|
Accept
required
|
Specifies the response format, which must be JSON, and the version of the API to be used. application/vnd.hmrc.1.0+json
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 200 (OK)
{ "_links": { "self": { "href": "/customs/transits/movements/departures" } }, "_embedded": { "departures": [ { "id": "1", "created": "2020-02-02T02:02:02", "updated": "2020-02-02T02:02:02", "movementReferenceNumber": "MRN", "_links": { "self": { "href": "/customs/transits/movements/departures/1" }, "messages": { "href": "/customs/transits/movements/departures/1/messages" } } }, { "id": "2", "created": "2020-02-04T02:02:02", "updated": "2020-02-04T02:02:02", "movementReferenceNumber": "MRN", "_links": { "self": { "href": "/customs/transits/movements/departures/2" }, "messages": { "href": "/customs/transits/movements/departures/2/messages" } } } ], "retrievedDepartures": 2, "totalDepartures": 2 } }
Error scenarios
Scenario | HTTP status | Code |
---|---|---|
The accept header is missing or invalid |
406 (Not Acceptable) |
ACCEPT_HEADER_INVALID |
For error scenarios that are common across all APIs, and for error formats, see our reference guide.
Close Section
/customs/transits/movements/departures
Send a Declaration Data message
POST
Send a Declaration Data message, to let the office at destination know that the goods are on their way. This notification will be sent when the goods leave the Office of Departure. It is also called an E_DEC_DAT (IE015).
The response will contain a URI and departure ID for the Declaration Data. This will allow you to retrieve the submission status.
The response will also contain an embedded requestId, boxId and boxName which will allow you to match this movement to any messages received via the Push Pull Notifications Service.
If the user is not enrolled for an EORI number, they will receive an HTTP Forbidden Status.
Request headers
Name | Description |
---|---|
Content-Type
required
|
Specifies the format of the request body, which must be XML. application/xml
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 202 (Accepted)
{ "_links": { "self": { "href": "/customs/transits/movements/departures/1" } }, "departureId": "1", "messageType": "IE015", "body": "<CC015B>...</CC015B>", "_embedded": { "notifications":{ "boxId":"1234-5678-abcd-def", "requestId":"/customs/transits/movements/departures/1", "boxName":"customs/transits##1.0##notificationUrl" } } }
Close Section
/customs/transits/movements/departures/{departureId}
Get a Movement Departure for a departure ID
GET
Get a specific Movement Departure which was sent to the office at departure within 28 days of the goods being released at their final destination. Any Movements that are more than 28 days old will have been archived. Archived notifications will be return an HTTP 404 Not Found status.
You will only be able to retrieve these messages if you have the EORI number associated with the Movement Departure.
Note: The 'movementReferenceNumber' field will only be populated when an MRN is allocated.
Request headers
Name | Description |
---|---|
Accept
required
|
Specifies the response format, which must be JSON, and the version of the API to be used. application/vnd.hmrc.1.0+json
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 200 (OK)
{ "id": "1", "created": "2020-10-10T10:10:10", "updated": "2020-12-12T12:12:12", "movementReferenceNumber": "MRN", "_links": { "self": { "href": "/customs/transits/movements/departures/1" }, "messages": { "href": "/customs/transits/movements/departures/1/messages" } } }
Error scenarios
Scenario | HTTP status | Code |
---|---|---|
The accept header is missing or invalid |
406 (Not Acceptable) |
ACCEPT_HEADER_INVALID |
For error scenarios that are common across all APIs, and for error formats, see our reference guide.
Close Section
/customs/transits/movements/departures/{departureId}/messages
Get all messages relating to a Movement Departure
GET
Get all messages sent within 28 days of the goods being released relating to a Movement Departure. Any Movements that are more than 28 days old will have been archived. Archived notifications will be return an HTTP 404 Not Found status.
You may opt to filter this list of messages so that you only receive messages that have been received since a specified date and time.
You will only be able to retrieve these messages if you have the EORI number associated with the Movement Departure.
Note: The 'movementReferenceNumber' field will only be populated when an MRN is allocated.
Query parameters
Name | Description |
---|---|
receivedSince
datetime
optional
|
This is an optional filtering parameter. It allows you to request only the messages relating to a Movement Departure which have been received since the date and time you have given us.
For example: |
Request headers
Name | Description |
---|---|
Accept
required
|
Specifies the response format, which must be JSON, and the version of the API to be used. application/vnd.hmrc.1.0+json
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 200 (OK)
{ "_links": { "self": { "href": "/customs/transits/movements/departures/1/messages" } }, "_embedded": { "messages": [ { "_links": { "self": { "href": "/customs/transits/movements/departures/1/messages/1" }, "departure": { "href": "/customs/transits/movements/departures/1" } }, "departureId": "1", "messageId": "1", "received": "2020-12-12T12:12:15", "messageType": "IE015", "body": "<CC015B>...</CC015B>" } ], "departure": { "id": "1", "created": "2020-10-10T10:10:10", "updated": "2020-12-12T12:12:12", "movementReferenceNumber": "MRN", "_links": { "self": { "href": "/customs/transits/movements/departures/1" }, "messages": { "href": "/customs/transits/movements/departures/1/messages" } } } } }
Error scenarios
Scenario | HTTP status | Code |
---|---|---|
The accept header is missing or invalid |
406 (Not Acceptable) |
ACCEPT_HEADER_INVALID |
For error scenarios that are common across all APIs, and for error formats, see our reference guide.
Close Section
/customs/transits/movements/departures/{departureId}/messages
/customs/transits/movements/departures/{departureId}/messages/{messageId}
Get a message relating to a Movement Departure and message ID
GET
Get all messages relating to a specific Movement Departure and message ID. For example, this could include declaration rejected or Movement Reference Number (MRN) allocated messages. Any messages more than 28 days old will be archived. Archived notifications will be return an HTTP 404 Not Found status.
You will only be able to retrieve these messages if you have the EORI number associated with the Movement Departure.
Request headers
Name | Description |
---|---|
Accept
required
|
Specifies the response format, which must be JSON, and the version of the API to be used. application/vnd.hmrc.1.0+json
|
Authorization
required
|
An
OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer bb7fed3fe10dd235a2ccda3d50fb
|
See also fraud prevention.
Responses
HTTP status 200 (OK)
{ "_links": { "self": { "href": "/customs/transits/movements/departures/1/messages/1" }, "departure": { "href": "/customs/transits/movements/departures/1" } }, "departureId": "1", "messageId": "1", "received": "2020-10-10T10:10:10", "messageType": "IE015", "body": "<CC015B>...</CC015B>" }
Error scenarios
Scenario | HTTP status | Code |
---|---|---|
The accept header is missing or invalid |
406 (Not Acceptable) |
ACCEPT_HEADER_INVALID |
For error scenarios that are common across all APIs, and for error formats, see our reference guide.
Close Section
/customs/transits/movements/push-pull-notifications/box
Get Box Info
GET
Get Box Information for the application if there is a push-pull-notification box
Request headers
Name | Description |
---|---|
Accept
required
|
Specifies the response format, which must be JSON, and the version of the API to be used. application/vnd.hmrc.1.0+json
|
Authorization
required
|
An OAuth 2.0 Bearer Token
with the common-transit-convention-traders scope.
For example: Bearer 59fc92c1cdf0b8ef1f138a702effdbd2
|
See also fraud prevention.
Responses
HTTP status 200 (OK)
{ "boxId": "5fb4b568-b5ff-4475-bd29-0a3e70abb6d6", "boxName": "customs/transits##1.0##notificationUrl", "_links": { "self": { "href": "/customs/transits/movements/push-pull-notifications/box" } } }
Error scenarios
Scenario | HTTP status | Code |
---|---|---|
The accept header is missing or invalid |
406 (Not Acceptable) |
ACCEPT_HEADER_INVALID |
For error scenarios that are common across all APIs, and for error formats, see our reference guide.
Close Section