The Pillar2 stubs service provides stubs for the GRS systems to mock the responses.
- pillar2-stubs
- Table of Contents
- Running Pillar 2 Stubs Locally
- Running with Service Manager
- Developing Locally
- Testing
- Endpoints
- Create a Registration Request
- Create a Subscription Request
- Retrieve Subscription Details
- Retrieve Subscription Details (Cache)
- Amend Existing Subscription
- Retrieve Enrolment Store Response
- Business Bank Account Reputation Service (BARS)
- Financial Data - Get Financial Test Data
- Obligations and Submissions API
- Submit UKTR (Liability Detail Submission)
- Amend UKTR
- Below-Threshold Notification (BTN)
- License
Compile the project with:
sbt clean update compileRun the project locally with:
sbt runBy default, the service runs on port 10052.
To use test-only route locally, run the below:
sbt 'run -Dplay.http.router=testOnlyDoNotUseInAppConf.Routes 10052'Use Service Manager to start all the services required to run and test Pillar 2 locally. Start the PILLAR2_ALL profile, responsible for starting up all the services required by Pillar 2, with:
sm2 --start PILLAR2_ALLHead to the Authority Wizard to sign in and create a session for a user with your choice of enrolments and IDs.
When you sign in with, provide the following details:
- Redirect URL: http://localhost:10050/report-pillar2-top-up-taxes
- Affinity Group: Organisation
To stop all services, run:
sm2 --stop PILLAR2_ALLStart all the Pillar 2 services as mentioned above:
sm2 --start PILLAR2_ALLStop the PILLAR_2_STUBS service with:
sm2 --stop PILLAR_2_STUBSConfirm that all dependent services but the PILLAR_2_STUBS are running with:
sm2 --statusRun Pillar 2 Stubs locally with:
sbt runHead to the Authority Wizard to sign in and create a session for a user with your choice of enrolments and IDs.
When you sign in with the Authority Wizard, provide the following details:
- Redirect URL: http://localhost:10050/report-pillar2-top-up-taxes
- Affinity Group: Organisation
Run unit tests with:
sbt testRun integration tests with:
sbt it/testCheck code coverage with:
sbt clean coverage test it/test coverageReportEndpoint: POST /registration/02.00.00/organisation
Description: Creates a Registration request without passing ID
To trigger the happy path, ensure you provide a valid request body:
{
"regime": "PLR",
"acknowledgementReference": "d31186c7412e4823897ecc7ee339545c",
"isAnAgent": false,
"isAGroup": true,
"organisation": {
"organisationName": "Stark Corp"
},
"address": {
"addressLine1": "100",
"addressLine3": "Newyork",
"postalCode": "10052",
"countryCode": "US"
},
"contactDetails": {
"emailAddress": "[email protected]"
}
}- Response status:
200 - Response body: N/A
To trigger the unhappy paths, ensure you provide a valid request body.
The below error responses can be expected:
{
"errorDetail": {
"timestamp": "2016-08-23T18:15:41Z",
"correlationId": "c182e731-2386-4359-8ee6-f911d6e5f4bc",
"errorCode": "500",
"errorMessage": "Internal error",
"source": "Internal Server error"
}
}- Response status:
500 - Response body: N/A
{
"errorDetail": {
"timestamp" : "2023-02-14T12:58:44Z",
"correlationId": "c182e731-2386-4359-8ee6-f911d6e5f4bc",
"errorCode": "400",
"errorMessage": "Invalid ID",
"source": "Back End",
"sourceFaultDetail": {
"detail": [
"001 - Invalid Regime"
]
}
}
}- Response status:
400 - Response body: N/A
{
"errorDetail": {
"timestamp": "2016-08-23T18:15:41Z",
"correlationId": "",
"errorCode": "503",
"errorMessage": "Send timeout",
"source": "Back End",
"sourceFaultDetail": {
"detail": ["101504 - Timeout "]
}
}
}- Response status:
503 - Response body: N/A
{
"errorDetail": {
"source": "Back End",
"timestamp": "2020-11-11T13:19:52.307Z",
"errorMessage": "Request could not be processed",
"errorCode": "503",
"correlationId": "c182e731-2386-4359-8ee6-f911d6e5f4bc",
"sourceFaultDetail": {
"detail": [
"001 - Request Cannot be processed"
]
}
}
}- Response status:
503 - Response body: N/A
{
"errorDetail": {
"source": "Back End",
"timestamp": "2020-11-23T13:19:52.307Z",
"errorMessage": "Record not found",
"errorCode": "404",
"correlationId": "36147652-e594-94a4-a229-23f28e20e841",
"sourceFaultDetail": {
"detail": [
"Detail cannot be found"
]
}
}
}- Response status:
404 - Response body: N/A
Endpoint: POST /pillar2/subscription
Description: Creates a Subscription request
For testing the registration in progress feature, use specific organisation names OR UPE contact names to trigger different polling behaviors:
| Test Trigger | PLR Reference Returned | Polling Behavior |
|---|---|---|
| UPE Contact Name: "Quick Processing" OR "Quick Processing Corp" | XEPLR0000000001 | Returns 422 for first 3 polls (6 seconds), then returns 200 success |
| UPE Contact Name: "Medium Processing" OR "Medium Processing Corp" | XEPLR0000000002 | Returns 422 for first 8 polls (16 seconds), then returns 200 success |
Note: The UPE contact name is read from primaryContactDetails.name in the request body. If both organisation name and UPE contact name match test triggers, UPE contact name takes precedence.
To trigger the happy path, ensure you provide a valid request body:
{
"upeDetails": {
"safeId": "XE6666666666666",
"organisationName": "Stark Corp",
"registrationDate": "2023-12-08",
"domesticOnly": false,
"filingMember": true
},
"accountingPeriod": {
"startDate": "2024-01-01",
"endDate": "2025-01-01"
},
"upeCorrespAddressDetails": {
"addressLine1": "100",
"addressLine3": "Newyork",
"postCode": "10052",
"countryCode": "US"
},
"primaryContactDetails": {
"name": "Tony Stark",
"emailAddress": "[email protected]"
}
}- Response status:
200 - Response body: N/A
To trigger the unhappy paths, ensure you provide a valid request body. The below error responses can be expected:
{
"errorDetail": {
"timestamp" : "2023-03-11T08:20:44Z",
"correlationId": "c182e731-2386-4359-8ee6-f911d6e5f4bc",
"errorCode": "409",
"errorMessage": "Duplicate submission",
"source": "Back End",
"sourceFaultDetail": {
"detail": [
"Duplicate submission"
]
}
}
}- Response status:
409 - Response body: N/A
{
"errorDetail": {
"timestamp": "2016-08-23T18:15:41Z",
"correlationId": "",
"errorCode": "503",
"errorMessage": "Send timeout",
"source": "Back End",
"sourceFaultDetail": {
"detail": ["101504 - Timeout "]
}
}
}- Response status:
503 - Response body: N/A
{
"errorDetail": {
"source": "Back End",
"timestamp": "2020-11-23T13:19:52.307Z",
"errorMessage": "Record not found",
"errorCode": "404",
"correlationId": "36147652-e594-94a4-a229-23f28e20e841",
"sourceFaultDetail": {
"detail": [
"Detail cannot be found"
]
}
}
}- Response status:
404 - Response body: N/A
Endpoint: GET /pillar2/subscription/:plrReference
Description: Retrieves the Subscription details for the specific plrReference
| plrReference | Status Code | Status | Description |
|---|---|---|---|
| XEPLR0000000001 | 422/200 | VARIABLE | Registration in progress test - Returns 422 for first 3 polls, then 200 success |
| XEPLR0000000002 | 422/200 | VARIABLE | Registration in progress test - Returns 422 for first 8 polls, then 200 success |
| XEPLR0123456400 | 400 | BAD_REQUEST | Submission has not passed validation. Invalid plrReference. |
| XEPLR0123456404 | 404 | NOT_FOUND | Submission has not passed validation. Record not found. |
| XEPLR0123456422 | 422 | CANNOT_COMPLETE_REQUEST | Request could not be completed because the subscription is being created or amended. |
| XEPLR0123456500 | 500 | INTERNAL_SERVER_ERROR | Internal Server error. |
| XEPLR0123456503 | 503 | SERVICE_UNAVAILABLE | Dependent systems are currently not responding. |
| XEPLR5555555555 | 200 | OK | Returns read success response with accountStatus.inactive set to true. |
| XEPLR6666666666 | 200 | OK | Returns read success response with upe registration year of 2011. |
| XEPLR1066196600 | 200 | OK | Returns read success response with domesticOnly set to true. Use this for one AP in obligation data |
| XEPLR1066196602 | 200 | OK | Returns read success response with domesticOnly set to true. Use this for two AP's in obligation data |
| XEPLR2000000109 | 200 | OK | Returns read success response with accountStatus.inactive set to true. |
| XEPLR2000000110 | 200 | OK | Returns read success response with accountStatus.inactive set to true. |
| XEPLR2000000111 | 200 | OK | Returns read success response with accountStatus.inactive set to true. |
| XEPLR__________ | 200 | OK | Returns read success response . |
To trigger the happy path, ensure you provide a valid plrReference. The below is the expected success response:
{
"success": {
"plrReference": "[pillar2Reference]",
"processingDate": "2010-12-12",
"formBundleNumber": "119000004320",
"upeDetails": {
"domesticOnly": false,
"organisationName": "International Organisation Inc.",
"customerIdentification1": "12345678",
"customerIdentification2": "12345678",
"registrationDate": "2022-01-31",
"filingMember": false
},
"upeCorrespAddressDetails": {
"addressLine1": "1 High Street",
"addressLine2": "Egham",
"addressLine3": "Surrey",
"postCode": "HP13 6TT",
"countryCode": "GB"
},
"primaryContactDetails": {
"name": "Fred Flintstone",
"telepphone": "0115 9700 700",
"emailAddress": "[email protected]"
},
"secondaryContactDetails": {
"name": "Donald Trump",
"telepphone": "0115 9700 700",
"emailAddress": "[email protected]"
},
"filingMemberDetails": {
"safeId": "XL6967739016188",
"organisationName": "Domestic Operations Ltd",
"customerIdentification1": "1234Z678",
"customerIdentification2": "1234567Y"
},
"accountingPeriod": {
"startDate": "2024-01-06",
"endDate": "2025-04-06",
"duetDate": "2024-04-06"
},
"accountStatus": {
"inactive": true
}
}
}- Response status:
200 - Response body:
To trigger the unhappy paths, ensure you provide a valid request body. The below error responses can be expected:
{
"errorDetail": {
"timestamp": "2016-08-23T18:15:41Z",
"correlationId": "c182e731-2386-4359-8ee6-f911d6e5f4bc",
"errorCode": "500",
"errorMessage": "Internal error",
"source": "Internal Server error"
}
}- Response status:
500 - Response body: N/A
{
"errorDetail": {
"timestamp" : "2023-02-14T12:58:44Z",
"correlationId": "c182e731-2386-4359-8ee6-f911d6e5f4bc",
"errorCode": "400",
"errorMessage": "Invalid ID",
"source": "Back End",
"sourceFaultDetail": {
"detail":[
"001 - Invalid Regime"
]
}
}
}- Response status:
400 - Response body: N/A
{
"errorDetail": {
"timestamp": "2016-08-23T18:15:41Z",
"correlationId": "",
"errorCode": "503",
"errorMessage": "Send timeout",
"source": "Back End",
"sourceFaultDetail": {
"detail": ["101504 - Timeout"]
}
}
}- Response status:
503 - Response body: N/A
{
"errorDetail": {
"source": "Back End",
"timestamp": "2020-11-11T13:19:52.307Z",
"errorMessage": "Request could not be processed",
"errorCode": "503",
"correlationId": "c182e731-2386-4359-8ee6-f911d6e5f4bc",
"sourceFaultDetail": {
"detail": [
"001 - Request Cannot be processed"
]
}
}
}- Response status:
503 - Response body: N/A
{
"errorDetail": {
"source": "Back End",
"timestamp": "2020-11-23T13:19:52.307Z",
"errorMessage": "Record not found",
"errorCode": "404",
"correlationId": "36147652-e594-94a4-a229-23f28e20e841",
"sourceFaultDetail": {
"detail": [
"Detail cannot be found"
]
}
}
}- Response status:
404 - Response body: N/A
Endpoint: GET /pillar2/subscription/read-subscription/:id/:plrReference
Description: Reads the Subscription details and caches them for the specific PLR reference and ID. This endpoint is used by the DashboardController for testing registration in progress scenarios.
| plrReference | Status Code | Status | Description |
|---|---|---|---|
| XEPLR0000000001 | 404/200 | VARIABLE | Registration in progress test - Returns 404 for first 3 polls, then 200 success |
| XEPLR0000000002 | 404/200 | VARIABLE | Registration in progress test - Returns 404 for first 8 polls, then 200 success |
| Any other PLR | 200 | OK | Returns read success response for any other valid PLR reference |
To trigger the happy path, provide a valid id and plrReference.
The response format is identical to the GET /pillar2/subscription/:plrReference endpoint.
Endpoint: PUT /pillar2/subscription
Description: Amends an existing Subscription. The outcome of the request can be controlled by the name field within the primaryContactDetails of the request body.
| primaryContactDetails.name | Status Code | Status | Description |
|---|---|---|---|
| "400" | 400 | BAD_REQUEST | Triggers a Bad Request response. |
| "409" | 409 | CONFLICT | Triggers a Duplicate Submission error. |
| "422" | 422 | UNPROCESSABLE_ENTITY | Triggers an Unprocessable Entity error. |
| "500" | 500 | INTERNAL_SERVER_ERROR | Triggers an Internal Server Error. |
| "503" | 503 | SERVICE_UNAVAILABLE | Triggers a Service Unavailable error. |
| "10 seconds" | 200 | OK | Returns a success response after a 10-second delay. |
| "timeout" | 200 | OK | Returns a success response after a 30-second delay (will induce a client-side timeout). |
| Any other value | 200 | OK | Returns a success response. |
To trigger the happy path, provide a valid request body with a primaryContactDetails.name that does not match any of the error triggers (e.g., "Default Contact Name").
Example Request Body:
{
"upeDetails": {
"safeId": "XE6666666666666",
"organisationName": "Stark Corp",
"registrationDate": "2023-12-08",
"domesticOnly": false,
"filingMember": true
},
"accountingPeriod": {
"startDate": "2024-01-01",
"endDate": "2025-01-01"
},
"upeCorrespAddressDetails": {
"addressLine1": "100",
"addressLine3": "Newyork",
"postCode": "10052",
"countryCode": "US"
},
"primaryContactDetails": {
"name": "Default Contact Name",
"emailAddress": "[email protected]"
}
}- Response status:
200 - Response body:
{ "success": { "processingDate": "2024-01-31T09:26:17Z", "plrReference": "XMPLR0012345674", "formBundleNumber": "119000004320", "customerIdentification1": "XACBC0000123456", "customerIdentification2": "XACBC0000123457" } }
Endpoint: GET /enrolment-store-proxy/enrolment-store/enrolments/:serviceName/groups
Description: Retrieves the Enrolment Store Response with and without groupId.
To trigger the happy path, ensure you provide a valid plrReference.
The below is the expected success response:
- Response status:
200 - Response body:
{ "principalGroupIds": [ "GHIJKLMIN1234567", "GHIJKLMIN1234568" ], "delegatedGroupIds": [ "GHIJKLMIN1234567", "GHIJKLMIN1234568" ] }
- Response status:
200 - Response body:
{}
To trigger the unhappy paths, use XEPLR0444444400.
- Response status:
204 - Response body:
NoContent
Endpoint: POST /verify/business
Description: This endpoint checks the likely correctness of a given business bank account, and it's likely connection to the given business.
| Sort code | Account number | Company Name | Valid | Error Returned |
|---|---|---|---|---|
| 206705 | 86473611 | Epic Adventure Inc | Yes | Successful Response "Epic Adventure Inc" returns nameMatches = Yes "Foo" returns nameMatches = No "Epic" returns nameMatches = Partial |
| 206705 | 86563612 | Sanguine Skincare | Yes | accountNumberIsWellFormatted = No |
| 206705 | 76523611 | Vortex Solar | Yes | accountExists = No |
| 206705 | 56523611 | Innovation Arch | Yes | accountExists = inapplicable |
| 206705 | 56945688 | Eco Focus | Yes | accountExists = indeterminate |
| 207102 | 86473611 | Flux Water Gear | Yes | accountExists = error |
| 207102 | 86563611 | Lambent Illumination | Yes | nameMatches = No |
| 207102 | 76523611 | Boneféte Fun | Yes | nameMatches = inapplicable |
| 207102 | 56523611 | Cogent-Data | Yes | nameMatches = indeterminate |
| 207102 | 74597611 | Cipher Publishing | Yes | nameMatches = error |
| 207106 | 86473611 | Security Engima | Yes | sortCodeIsPresentOnEISCD = no |
| 207106 | 86563611 | Megacorp | Yes | sortCodeIsPresentOnEISCD = error |
| 207106 | 76523611 | Genomics Inc | Yes | nonStandardAccountDetailsRequiredForBacs = Yes |
| 207106 | 56523611 | Full Force Futures | Yes | sortCodeSupportsDirectCredit = error |
| 207106 | 74597611 | Resource Refresh | Yes | sortCodeIsPresentOnEISCD = No, nameMatches = No, accountExists = No |
| 609593 | 96863604 | O'Connor Construction | Yes | accountNumberIsWellFormatted = indeterminate, but accountExists = Yes |
| 609593 | 96113600 | Candyland Consulting | Yes | accountNumberIsWellFormatted = indeterminate, but accountExists = No |
Endpoint: GET /enterprise/financial-data/ZPLR/:idNumber/PLR
Description: This endpoint provides the ability to get financial data (charges, estimates and payments).
| idNumber (PLR Reference Number) | Response Returned |
|---|---|
| XEPLR4000000000 | INVALID_IDNUMBER Error Response |
| XEPLR4040000000 | NOT_FOUND Error Response |
| XEPLR5000000000 | SERVER_ERROR Error Response |
| XEPLR5030000000 | SERVICE_UNAVAILABLE Error Response |
| XMPLR0000000(Last three digits are the number of transactions displayed) | For example - XMPLR0000000022 will display 22 transactions 12 refund and 12 payments. - XMPLR0000000122 will display 122 transactions 61 refunds and 61 payments Please note - Use even numbers since 13 will default to 6 refund and 6 payment - All returned values are randomised so figures won't be consistent Please note a user must be able to see only last 7 years of transactions on their account, to test read note below |
| XEPLR2000000000 | Outstanding payments (ETMP QA Test Data) |
| XEPLR2000000001 | Outstanding payments - UKTR single AP |
| XEPLR2000000002 | Outstanding payments - UKTR two APs |
| XEPLR2000000010 | Repayment Interest (RPI) |
| XEPLR2000000101 | Overdue DTT charge |
| XEPLR2000000102 | Overdue DTT charge plus interest charge |
| XEPLR2000000103 | Overdue DTT charge |
| XEPLR2000000104 | Overdue DTT charge plus interest charge |
| XEPLR2000000105 | Overdue DTT charge plus interest charge |
| XEPLR2000000106 | Overdue DTT charge plus interest charge |
| XEPLR2000000107 | Overdue DTT charge |
| XEPLR2000000108 | One accounting period with a paid charge |
| XEPLR2000000109 | No transactions |
| XEPLR2000000110 | Overdue DTT charge |
| XEPLR2000000111 | Overdue DTT charge |
| Any valid ID | Will return 10 transactions these values are consistent |
As it currently stands the end date is always set to today's date, this means that it will generate transactions from the registration date to today's date.
In the stubs the registration date is always 2024-01-31 therefore to override this date you need to override the config value set in the pillar2-frontend service.
Example:
sbt "-Dapplication.router=testOnlyDoNotUseInAppConf.Routes" "-Dfeatures.transactionHistoryEndDate=2044-01-31" runThis will set the end date to 2044-01-31 and generate transactions from 2037-01-31 to 2044-01-31. The last seven years.
Worth noting this won't happen in any other environment unless you override the config.
For now this API has not been developed by ETMP therefore we are making assumptions in order to provide test data and satisfy the requirements of the frontend.
| idNumber (PLR Reference Number) | Response Returned |
|---|---|
| XEPLR1000000000 | Obligation with Fulfilled status |
| XEPLR4040000000 | NOT_FOUND Error Response |
| Any valid ID | Will return a response with Open status |
Endpoint: GET /RESTAdapter/plr/obligations-and-submissions?fromDate={fromDate}&toDate={toDate}
Description: This API retrieves obligations and submissions for a given period based on the Pillar2 ID. The fromDate and toDate parameters are required and must be valid date strings in the format YYYY-MM-DD. The toDate must be after the fromDate, or the API will return an error.
The API returns different responses based on the Pillar2 ID provided in the X-Pillar2-Id header:
| Pillar2 ID | Response Type | Description |
|---|---|---|
| XEPLR1111111111 | Multiple Accounting Periods all open | Returns 4 accounting periods with different dates, obligation types, and statuses |
| XMPLR0012345675 | UKTR Due | Returns two accounting periods with UKTR and GIR obligations (due and overdue periods) |
| XMPLR0012345676 | UKTR Overdue | Returns two accounting periods (one due, one overdue) with both UKTR and GIR obligations - should trigger Overdue banner despite having due items |
| XMPLR0012345677 | UKTR Incomplete | Returns two accounting periods matching prototype - Period 1: both UKTR/GIR with UKTR submitted, Period 2: only GIR with no submissions |
| XEPLR2222222222 | No Accounting Periods | Returns a success response with no accounting periods |
| XEPLR3333333333 | Single Accounting Period | Returns a single accounting period (same as default) |
| XEPLR4444444444 | All Fulfilled | Returns Multiple accounting periods with all obligations fulfilled |
| XEPLR4444444445 | All Fulfilled with Received Flag | Returns Multiple accounting periods with all obligations fulfilled with received flag |
| XEPLR5555555555 | Multiple accounting periods with some fulfilled | Returns Multiple accounting periods with some obligations fulfilled |
| XEPLR9999999991 | Single active accounting period with no submission | Returns a single active accounting period with no submission |
| XEPLR9999999992 | Two active accounting periods with no submissions | Returns two active accounting periods with no submissions |
| XEPLR9999999993 | Three active accounting periods with different scenarios | Returns three active accounting periods with UKTR and two no submission scenarios |
| XEPLR9999999994 | Four active accounting periods with different scenarios | Returns four active accounting periods with UKTR, BTN and two no submission scenarios |
| XEPLR9999999995 | BTN under enquiry scenario | Returns two active accounting periods with UKTR obligations - one under enquiry (canAmend=false) and one not under enquiry (canAmend=true) |
| XEPLR1066196602 | Two active accounting periods with no submissions | Returns two active accounting periods with no submission. Use this for UK only in subscription data |
| XEPLR2000000101 | No accounting periods | Returns no active accounting periods. |
| XEPLR2000000102 | No accounting periods | Returns no active accounting periods. |
| XEPLR2000000103 | UKTR Due | Returns two accounting periods with UKTR and GIR obligations (due and overdue periods) |
| XEPLR2000000104 | UKTR Overdue | Returns two accounting periods (one due, one overdue) with both UKTR and GIR obligations - should trigger Overdue banner despite having due items |
| XEPLR2000000105 | Single Accounting Period | Returns a single accounting period (same as default) |
| XEPLR2000000106 | UKTR Overdue | Returns two active accounting periods with no submission. Use this for UK only in subscription data |
| XEPLR2000000107 | All Fulfilled with Received Flag | Returns Multiple accounting periods with all obligations fulfilled with received flag |
| XEPLR2000000108 | No accounting periods | Returns no active accounting periods. |
| XEPLR2000000109 | No accounting periods | Returns no active accounting periods. |
| XEPLR2000000110 | UKTR Overdue | Returns two accounting periods (one due, one overdue) with both UKTR and GIR obligations - should trigger Overdue banner despite having due items |
| XEPLR2000000111 | No accounting periods | Returns no active accounting periods. |
| XEPLR0200000422 | Error - Missing/Invalid Pillar2 ID | Returns a 422 error with code 002 |
| XEPLR0300000422 | Error - Request Processing Failure | Returns a 422 error with code 003 |
| XEPLR0300000404 | Error - Record Not Found | Returns a 404 error with code 004 |
| XEPLR0300000499 | Error - Request Timeout | Returns a 499 error with code 499 after 20 seconds |
| XEPLR0400000422 | Error - Duplicate Submission | Returns a 422 error with code 004 |
| XEPLR2500000422 | Error - No Data Found | Returns a 422 error with code 025 |
| XEPLR0000000400 | Error - Invalid JSON | Returns a 400 error |
| XEPLR0000000500 | Error - Internal Server Error | Returns a 500 error |
| Any other valid ID | Single Accounting Period (Default) | Returns a single accounting period for the current tax year |
Note: All successful responses require valid date parameters. If the toDate is not after the fromDate, a 422 error with code 001 will be returned regardless of which Pillar2 ID is used.
{
"success": {
"processingDate": "2024-07-03T12:34:56Z",
"accountingPeriodDetails": [
{
"startDate": "2024-01-01",
"endDate": "2024-12-31",
"dueDate": "2025-01-31",
"underEnquiry": false,
"obligations": [
{
"obligationType": "Pillar2TaxReturn",
"status": "Open",
"canAmend": true,
"submissions": [
{
"submissionType": "UKTR",
"receivedDate": "2024-07-03T12:34:56Z",
"country": null
}
]
}
]
},
{
"startDate": "2023-01-01",
"endDate": "2023-12-31",
"dueDate": "2024-01-31",
"underEnquiry": true,
"obligations": [
{
"obligationType": "Pillar2TaxReturn",
"status": "Fulfilled",
"canAmend": false,
"submissions": [
{
"submissionType": "UKTR",
"receivedDate": "2024-07-03T12:34:56Z",
"country": null
}
]
}
]
},
{
"startDate": "2022-01-01",
"endDate": "2022-12-31",
"dueDate": "2023-01-31",
"underEnquiry": false,
"obligations": [
{
"obligationType": "GlobeInformationReturn",
"status": "Fulfilled",
"canAmend": false,
"submissions": [
{
"submissionType": "GIR",
"receivedDate": "2024-07-03T12:34:56Z",
"country": null
}
]
}
]
},
{
"startDate": "2021-01-01",
"endDate": "2021-12-31",
"dueDate": "2022-01-31",
"underEnquiry": false,
"obligations": [
{
"obligationType": "Pillar2TaxReturn",
"status": "Fulfilled",
"canAmend": true,
"submissions": [
{
"submissionType": "UKTR",
"receivedDate": "2024-07-03T12:34:56Z",
"country": null
},
{
"submissionType": "BTN",
"receivedDate": "2024-07-03T12:34:56Z",
"country": "FR"
}
]
}
]
}
]
}
}{
"success": {
"processingDate": "2024-07-03T12:34:56Z",
"accountingPeriodDetails": []
}
}{
"errors": {
"processingDate": "2024-07-03T12:34:56Z",
"code": "001",
"text": "Invalid date range: toDate must be after fromDate"
}
}{
"errors": {
"processingDate": "2024-07-03T12:34:56Z",
"code": "002",
"text": "Pillar2 ID is missing or invalid"
}
}Endpoint: POST /RESTAdapter/plr/uk-tax-return
Description: This endpoint allows submission of liability details based on a provided idNumber (PLR Reference Number). There are two main types of submissions supported:
- Liability Submission: A detailed submission of liability amounts.
- Nil Return Submission: A minimal submission indicating no liability for the period.
A valid liability submission includes details about the total liabilities and entities liable for the tax period. Here's the expected structure for a successful liability submission:
{
"accountingPeriodFrom": "2024-08-14",
"accountingPeriodTo": "2024-12-14",
"qualifyingGroup": true,
"obligationDTT": true,
"obligationMTT": true,
"electionUKGAAP": true,
"liabilities": {
"totalLiability": 10000.99,
"totalLiabilityDTT": 5000.99,
"totalLiabilityIIR": 4000,
"totalLiabilityUTPR": 10000.99,
"liableEntities": [
{
"ukChargeableEntityName": "Newco PLC",
"idType": "CRN",
"idValue": "12345678",
"amountOwedDTT": 5000,
"electedDTT": true,
"amountOwedIIR": 3400,
"amountOwedUTPR": 6000.5,
"electedUTPR": true
}
]
}
}A Nil Return submission is used when there is no liability for the specified period. The returnType field in liabilities should be set to "NIL_RETURN":
{
"accountingPeriodFrom": "2024-08-14",
"accountingPeriodTo": "2024-09-14",
"qualifyingGroup": true,
"obligationDTT": true,
"obligationMTT": true,
"electionUKGAAP": true,
"liabilities": {
"returnType": "NIL_RETURN"
}
}| Status | Description |
|---|---|
| 201 CREATED | Success response for a valid liability or Nil Return submission when idNumber is correct. |
| 400 BAD_REQUEST | Submission did not pass validation (e.g., invalid JSON format or required fields missing). |
| 400 BAD_REQUEST | Non-JSON data received, expecting a valid JSON object. |
| 404 NOT_FOUND | No liabilities found for the provided idNumber (PLR Reference Number is incorrect). |
A request with invalid JSON syntax will return a 400 BAD_REQUEST response:
{
"accountingPeriod": "2024-08-1",
"accountingPeriod": "2024-12-14"
}If a non-JSON body is submitted, a 400 BAD_REQUEST response will be returned:
- Response status:
400 - Response body:
This is not a JSON body
Details of Expected Fields
- idNumber (PLR Reference Number): Only the idNumber "XTC01234123412" will result in a successful 201 CREATED response.
- Valid idNumber: Returns 201 CREATED with the liability success details for valid liability submissions.
- Invalid idNumber: Returns 404 NOT_FOUND, indicating no matching liability data for other idNumbers.
- Liability Fields: In a liability submission, totalLiability, totalLiabilityDTT, totalLiabilityIIR, and totalLiabilityUTPR are expected fields. Additionally, liableEntities should be a non-empty array.
- Nil Return Field: In a Nil Return submission, liabilities.returnType should be "NIL_RETURN", indicating no liability.
If the idNumber is valid and the payload is correct, a 201 CREATED response will be returned with liability details:
{
"success": {
"processingDate": "2024-08-14T09:26:17Z",
"formBundleNumber": "119000004320",
"chargeReference": "XTC01234123412"
}
}If the idNumber is valid and the payload indicates a Nil Return, a 201 CREATED response will be returned with the Nil Return details:
{
"success": {
"processingDate": "2024-08-14T09:26:17Z",
"message": "Nil return received and processed successfully"
}
}Endpoint: PUT /RESTAdapter/plr/uk-tax-return
Description: The request format is the same as the UKTaxReturn POST request, but it uses a PUT method instead. In the real world this would be used to amend a UKTR that has already been submitted, but we are not implementing this functionality in the stubs.
| PLR Reference Number | Response |
|---|---|
| XEPLR0422044000 | 422 Error - Tax obligation already met |
| XEPLR0400000000 | 400 Error - Bad Request |
| XEPLR0500000000 | 500 Error - Internal Server Error |
| Any other valid ID | 200 Success - Returns successful amendment response |
{
"success": {
"processingDate": "2024-01-31T12:00:00Z",
"formBundleNumber": "119000004320",
"chargeReference": "XTC01234123412"
}
}- Response status:
200 - Response body: N/A
To trigger the unhappy paths, ensure you provide a valid request body. The below error responses can be expected:
{
"errors": {
"processingDate": "2024-01-31T12:00:00Z",
"code": "044",
"text": "Tax obligation already met"
}
}{
"error": {
"code": "400",
"message": "Invalid request format",
"LogID": "C0000AB8190C8E1F000000C700006836"
}
}{
"errors": {
"processingDate": "2024-01-31T12:00:00Z",
"code": "500",
"text": "Internal server error"
}
}Endpoint: POST /RESTAdapter/plr/below-threshold-notification
Description: This endpoint allows submission of a Below-Threshold Notification (BTN), which defines an organisation as earning below the threshold that makes them eligible for submitting Pillar2 UKTR.
For this API, the payload is rather simple, so responses are limited in their scope.
| Pillar2Id | Response Returned |
|---|---|
| XEPLR4000000000 | BadRequest response |
| XEPLR5000000000 | InternalServerError response |
| Any valid ID | Successful response |
This code is open source software licensed under the Apache 2.0 License.