openapi: 3.0.1 info: title: Personal Account Data (PAD) APIs for touchpoints and Service Engine description: |- APIs for touchpoints and Service Engine to manage Personal Account Data (PAD) on OVpay tokens (xTATs).\ These APIs connect directly to the PADP APIs in GBO APIM and are implemented in Logic Apps in the Integration Layer. version: '1.0' servers: - url: https://api.integratielaag.nl/abt/touchpoint/1.0 tags: - name: Personal Data APIs for touchpoints description: Personal Data APIs for touchpoints, no Service Engine in between! - name: Personal Data APIs for Service Engine description: Personal Data APIs for Service Engine, not to be exposed to touchpoints! paths: /personal-data/{xtat}: post: tags: - Personal Data APIs for touchpoints summary: Add the supplied Personal Data to the given xTAT (that should not contain any Personal Data yet). description: |- - The given xTAT should not contain any Personal Data yet (the PATCH endpoint should be used in that case) - if the given xTAT already contains Personal Data, an error is thrown; - The given e-mail address will be used for future OTP challenges to manage the Personal Data in the future - this e-mail adress should therefore be validated; - If the e-mail address is not yet validated by other means (e.g. the e-mail address is used for login, or is entered twice to prevent typos), an OTP challenge for the e-mail address should be triggered and supplied to this endpoint; - xTAT and e-mail address are always required, for the Personal Data it is allowed to supply any subset, or all three data attributes; - Each of the three data attributes is validated - for the requirements per attribute, see the descriptions in the request details below; - If any attribute fails validation, none of the attributes will be added to the xTAT. operationId: CreatePersonalData parameters: - name: xtat in: path required: true example: 'c3a6c0f2-3b6a-4b9a-9c5d-5d9c6b3a4c5d' schema: type: string format: uuid requestBody: content: multipart/form-data: schema: type: object required: - email properties: email: type: string format: email description: Email address to be used for OTP challenges to prove ownership and manage the Personal Data in the future example: 8Z9dG@example.com otp: type: string pattern: ^[0-9]{6}$ description: OTP is optional, should be supplied if the e-mail address is not yet validated by other means (e.g. the e-mail address is used for login, or is entered twice to prevent typo's) example: "053395" name: type: string description: Should consist of at least two words (first name and last name) example: John Doe birthDate: type: string format: date description: Should be a date between 1900-01-01 and today, in the format `YYYY-MM-DD` example: 2000-01-01 photo: type: string description: Should be a JPG image, with a filesize of max. 512KB and resolution between 520x520 and 720x720 pixels format: binary encoding: photo: contentType: image/jpeg responses: '201': description: Created '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not Found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' get: tags: - Personal Data APIs for touchpoints summary: Retrieve the decrypted Personal Data for the given xTAT, using the OTP for verification of ownership. description: OTP challenge is required to retrieve the Personal Data. operationId: GetDecryptedPersonalData parameters: - name: xtat in: path required: true schema: type: string format: uuid example: 'c3a6c0f2-3b6a-4b9a-9c5d-5d9c6b3a4c5d' - name: otp in: query required: true description: OTP challenge code that the token owner received in their e-mail inbox. OTP is always required for managing existing Personal Data. schema: type: string pattern: ^[0-9]{6}$ example: "053395" responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/DecryptedPersonalData' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not Found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' patch: tags: - Personal Data APIs for touchpoints summary: Update the supplied personal data for the given xTAT, using the OTP for verification of ownership. description: This is a PATCH call, so only the personal data that the user desires to change need to be supplied. Integration layer supplements with any other existing personal data to be able to call GBO (PUT call). operationId: UpdatePersonalData parameters: - name: xtat in: path required: true schema: type: string format: uuid example: 'c3a6c0f2-3b6a-4b9a-9c5d-5d9c6b3a4c5d' requestBody: content: multipart/form-data: schema: type: object required: - otp properties: otp: type: string pattern: ^[0-9]{6}$ description: OTP challenge code that the token owner received in their e-mail inbox. OTP is always required for managing existing Personal Data. example: "053395" name: type: string description: Should consist of at least two words (first name and last name) example: John Doe birthDate: type: string format: date description: Should be a date between 1900-01-01 and today, in the format `YYYY-MM-DD` example: 2000-01-01 photo: type: string description: Should be a JPG image, with a filesize of max. 512KB and resolution between 520x520 and 720x720 pixels format: binary encoding: photo: contentType: image/jpeg responses: '200': description: OK /personal-data/generate-otp: get: tags: - Personal Data APIs for touchpoints summary: Trigger OTP email for the given xTAT or e-mail address, to prove ownership operationId: GenerateOtp description: |- Generate an OTP challenge e-mail to prove ownership of the given e-mail address or xTAT.\ Only one type of parameter can be supplied, either xtat or email. When both are supplied, an error is thrown. parameters: - name: xtat in: query required: false schema: type: string format: uuid example: 'c3a6c0f2-3b6a-4b9a-9c5d-5d9c6b3a4c5d' - name: email in: query required: false schema: type: string format: email example: 'sV4yj@example.com' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/OtpResponse' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not Found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /personal-data/{xtat}/administrative-data: get: tags: - Personal Data APIs for Service Engine summary: API 1211 - Get Administrative Data description: Integration Layer utilizes PAD management V2 in GBO APIM (`/pad-management/v2/..`) operationId: GetAdministrativeData parameters: - name: xtat description: xTAT to get administrative data for in: path required: true schema: type: string format: uuid example: 'c3a6c0f2-3b6a-4b9a-9c5d-5d9c6b3a4c5d' responses: "200": description: OK content: application/json: schema: $ref: "#/components/schemas/AdministrativeData" examples: Valid and complete PAD: summary: Valid and complete PAD value: name: inaccuracyFlag: false inaccuracyFlagReason: null inaccuracyFlagCounter: 0 changeCounter: 0 maxUpdatesVerificationCount: 1 lastChangeDate: "2025-03-26T10:18:42.947" isValidated: false photo: inaccuracyFlag: false inaccuracyFlagReason: null inaccuracyFlagCounter: 0 changeCounter: 0 maxUpdatesVerificationCount: 5 lastChangeDate: "2025-03-26T10:18:42.947" isValidated: false birthdate: inaccuracyFlag: false inaccuracyFlagReason: null inaccuracyFlagCounter: 0 changeCounter: 0 maxUpdatesVerificationCount: 3 lastChangeDate: "2025-03-26T10:18:42.947" isValidated: false Partially filled PAD (no photo): summary: Partially filled PAD (no photo) value: name: inaccuracyFlag: false inaccuracyFlagReason: null inaccuracyFlagCounter: 0 changeCounter: 0 maxUpdatesVerificationCount: 1 lastChangeDate: "2025-03-26T10:18:42.947" isValidated: false photo: null birthdate: inaccuracyFlag: false inaccuracyFlagReason: null inaccuracyFlagCounter: 0 changeCounter: 0 maxUpdatesVerificationCount: 3 lastChangeDate: "2025-03-26T10:18:42.947" isValidated: false Flagged PAD: summary: Flagged PAD value: name: inaccuracyFlag: true inaccuracyFlagReason: "Invalid name" inaccuracyFlagCounter: 1 changeCounter: 1 maxUpdatesVerificationCount: 1 lastChangeDate: "2025-03-26T10:18:42.947" isValidated: false photo: inaccuracyFlag: true inaccuracyFlagReason: "Invalid photo" inaccuracyFlagCounter: 1 changeCounter: 0 maxUpdatesVerificationCount: 5 lastChangeDate: "2025-03-26T10:18:42.947" isValidated: false birthdate: inaccuracyFlag: true inaccuracyFlagReason: "Invalid birthdate" inaccuracyFlagCounter: 1 changeCounter: 2 maxUpdatesVerificationCount: 3 lastChangeDate: "2025-03-26T10:18:42.947" isValidated: false "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" examples: Invalid UUID: summary: Invalid UUID value: errors: code: "0x03000103" data: [ "geen-uuid" ] message: "The provided scTat is not a valid UUID" exceptionClassName: "PadpConstraintViolationException" exceptionStackTrace: "not available because debug mode is turned off" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" examples: No PAD found for xTAT: summary: No PAD found for xTAT value: errors: code: "0x03000105" data: [] message: "Transit account not found" exceptionClassName: "PadpEntityNotFoundException" exceptionStackTrace: "not available because debug mode is turned off" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" examples: Unknown xTAT: summary: Unknown xTAT value: errors: code: "0x00000001" data: null message: "400 : \"{\"errorMessage\":{\"referenceId\":\"076f0de4-df33-42a3-add0-def971ab6679\",\"message\":\"Unknown external transit account token.\"},\"businessExceptions\":[{\"code\":\"TM0207\",\"message\":\"Unknown external transit account token.\"}]}\"" exceptionClassName: "BadRequest" exceptionStackTrace: "not available because debug mode is turned off" components: schemas: AdministrativeData: type: object properties: name: $ref: '#/components/schemas/AdministrativeDataElement' photo: $ref: '#/components/schemas/AdministrativeDataElement' birthdate: $ref: '#/components/schemas/AdministrativeDataElement' additionalProperties: false AdministrativeDataElement: type: object properties: inaccuracyFlag: type: boolean inaccuracyFlagReason: type: string nullable: true inaccuracyFlagCounter: type: integer format: int32 changeCounter: type: integer format: int32 maxUpdatesVerificationCount: type: integer format: int32 lastChangeDate: type: string format: date-time isValidated: type: boolean additionalProperties: false DecryptedData: type: object properties: name: type: string nullable: true birthdate: type: string nullable: true photo: type: string description: Base64 encoded photo format: byte nullable: true additionalProperties: false DecryptedPersonalData: type: object properties: decryptedData: $ref: '#/components/schemas/DecryptedData' additionalProperties: false Error: type: object properties: code: type: string nullable: true data: type: array items: type: string nullable: true message: type: string nullable: true additionalProperties: false ErrorResponse: type: object properties: errors: type: array items: $ref: '#/components/schemas/Error' nullable: true exceptionClassName: type: string nullable: true exceptionStackTrace: type: string nullable: true additionalProperties: false Metadata: type: object properties: encryptedEphemeralKey: type: string nullable: true additionalProperties: false OtpResponse: type: object properties: maskedEmailAddress: type: string nullable: true additionalProperties: false