openapi: 3.0.4
info: 
  title: APICUNIA GATEWAY - Confirmation of Payee (COP) Scheme
  version: 1.0.0
  description: | 
    Technical specification for Application Programming Interfaces (API's) from regulatory service provider [Apicunia](https://www.apicunia.com/). 
    
  contact:
    name: Apicunia Support
    url: https://www.apicunia.com/
    email: support@apicunia.com
externalDocs:
  description: Find out more about the UK Confirmation Of Payee Scheme
  url: https://www.wearepay.uk/what-we-do/overlay-services/confirmation-of-payee/
servers:
  - url: https://test-apigw.apicunia.com
    description: COP Gateway (Test)
tags:
  - name: Confirm Payee
    description: Apicunia COP API (Reachability and Requesting Service)
    externalDocs:
      description: Find out more
      url: https://www.apicunia.com/
paths:
  /copgateway/v1.0/confirmation-payee/name-verification:
    post:
      summary: Confirmation of Payee Details
      description: |
        Confirmation of Payee (COP) is an account name-checking service designed to help reduce misdirected payments and provide greater assurance that payments are being sent, and collected from, the intended account holder for UK domestic payments.
        
        Returns a **Standard COP Response** indicating if the supplied Payee details are a match or otherwise.

        **As Requestor:** The endpoint will validate and route an incoming COP request to the applicable COP Responder and relay the COP response back to the calling application.
      tags:
        - Confirm Payee
      operationId: postConfirmationOfPayeeRequests
      parameters:
      - name: x-fapi-interaction-id
        description: An RFC4122 UUID used as a correlation id by the Requesting PSP
        in: header
        schema:
          type: string
          format: uuid
        example: 'd9923871-e2a4-4d6d-b7d6-4d822a99b812'
        required: true
      - name: X-Request-Timestamp
        description: |
          Timestamp of the COP Request in ISO 8601 UTC format (YYYY-MM-DDThh:mm:ss.sssZ).
        in: header
        schema:
          type: string
          format: date-time
        example: '2026-06-01T11:09:26.581Z'
        required: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NameVerificationRequest'
            examples:
              Personal Account (NatWest - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Personal
                      identification: '60000190000001'
                      name: John Smith
              Personal Account (Barclays - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Personal
                      identification: '20454590000002'
                      name: Robert Jones
              Personal Account (RBS - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Personal
                      identification: '16522190000003'
                      name: Stephen Brown
              Personal Account (Lloyds - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Personal
                      identification: '30000290000004'
                      name: Sarah Thomas
              Personal Account (Halifax - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Personal
                      identification: '11000190000005'
                      name: Susan White
              Personal Account (include SecondaryIdentification - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Personal
                      identification: '60000190000001'
                      name: John Smith
                      secondaryIdentification: Test
              Business Account (HSBC - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Business
                      identification: '40051580000001'
                      name: Oak Accounting
              Business Account (TSB - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Business
                      identification: '77010180000002'
                      name: Beacon Estates
              Business Account (Clydesdale - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Business
                      identification: '82200080000003'
                      name: Simon Cycles Ltd
              Business Account (Nationwide - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Business
                      identification: '07011680000004'
                      name: Fienix Solutions
              Business Account (Bank of Scotland - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Business
                      identification: '80226080000005'
                      name: Northbridge Consulting
              Business Account (include SecondaryIdentification - Match):
                  value:
                    data:
                      schemeName: SortCodeAccountNumber
                      accountType: Business
                      identification: '40051580000001'
                      name: Oak Accounting
                      secondaryIdentification: Test
      responses:
        '200':
          description: A **Standard COP response** indicating matched status and reason codes when not a full match
          headers:
            x-fapi-interaction-id:
              schema:
                type: string
                format: uuid
              required: true
              description: An RFC4122 UUID used as a correlation id by the Requesting PSP
            X-Response-Timestamp:
              schema:
                type: string
                format: date-time
              example: '2026-06-01T11:09:26.581Z'
              required: true
              description: Timestamp of the COP Response in ISO 8601 UTC format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NameVerificationResponse'
              examples:
                Match :
                    value:
                      data:
                        verificationReport:
                          matched: true
                ANNM - Account Name does not match:
                    value:
                      data:
                        verificationReport:
                          matched: false
                          reasonCode: ANNM
                MBAM - There May be a Match on the Account Name:
                    value:
                      data:
                        verificationReport:
                          matched: false
                          reasonCode: MBAM
                          name: John Smith
                AC01 - Unknown Account Number, Matching Not Possible:
                    value:
                      data:
                        verificationReport:
                          matched: false
                          reasonCode: AC01
        '400':
          description: Bad/Malformed VOP Request. The request body is malformed.
          headers:
            x-fapi-interaction-id:
              schema:
                type: string
                format: uuid
              required: true
              description: An RFC4122 UUID used as a correlation id by the Requesting PSP
            X-Response-Timestamp:
              schema:
                type: string
                format: date-time
              example: '2026-06-01T11:09:26.581Z'
              required: true
              description: Timestamp of the COP Response in ISO 8601 UTC format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConfirmationOfPayeeError'
              examples:
                Format Error (Sort and Account):
                  value:
                    type: https://example.com/probs/FORMAT_ERROR
                    code: FORMAT_ERROR
                    title: Validation of COP Request failed. See Detail
                    status: 400
                    detail: Invalid Sort Code and Account format.
                    instance: /copgateway/v1.0/confirmation-payee/name-verification
                Format Error (Scheme):
                  value:
                    type: https://example.com/probs/FORMAT_ERROR
                    code: FORMAT_ERROR
                    title: Validation of COP Request failed. See Detail
                    status: 400
                    detail: Invalid Scheme Name - must be 'SortCodeAccountNumber'
                    instance: /copgateway/v1.0/confirmation-payee/name-verification
                Format Error (Account Type):
                  value:
                    type: https://example.com/probs/FORMAT_ERROR
                    code: FORMAT_ERROR
                    title: Validation of COP Request failed. See Detail
                    status: 400
                    detail: Invalid Account Type - must be one of 'Personal' or 'Business'
                    instance: /copgateway/v1.0/confirmation-payee/name-verification
                Timestamp Error (Not ISO 8601 format):
                  value:
                    type: https://example.com/probs/TIMESTAMP_INVALID
                    code: TIMESTAMP_INVALID
                    title: "Invalid timestamp format: X-Request-Timestamp"
                    status: 400
                    detail: "Invalid timestamp format: X-Request-Timestamp"
                    instance: /copgateway/v1.0/confirmation-payee/name-verification
        '401':
          description: Invalid Requesting PSP. The Requesting PSP is **not authorised** to perform the request.  
          headers:
            x-fapi-interaction-id:
              schema:
                type: string
                format: uuid
              required: true
              description: An RFC4122 UUID used as a correlation id by the Requesting PSP
            X-Response-Timestamp:
              schema:
                type: string
                format: date-time
              example: '2026-06-01T11:09:26.581Z'
              required: true
              description: Timestamp of the COP Response in ISO 8601 UTC format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConfirmationOfPayeeError'
              examples:
                Invalid Client 1:
                  value:
                    type: https://example.com/probs/CLIENT_INVALID
                    code: CLIENT_INVALID
                    title: Validating the client failed. See Detail
                    status: 401
                    detail: Invalid Client, no permission to access resource.
                    instance: /copgateway/v1.0/confirmation-payee/name-verification
                Invalid Client 2:
                  value:
                    type: https://example.com/probs/CLIENT_INVALID
                    code: CLIENT_INVALID
                    title: Unknown Requestor/Responder. See Detail
                    status: 401
                    detail: One or both of the Responding/Requesting party is not recognised or not currently adherent to the COP Scheme.
                    instance: /copgateway/v1.0/confirmation-payee/name-verification
        '500':
          description: Internal Server Error. This code is used whenever a technical problem occurred in the application code or application server that prevented the execution of the request.
          headers:
            x-fapi-interaction-id:
              schema:
                type: string
                format: uuid
              required: true
              description: An RFC4122 UUID used as a correlation id by the Requesting PSP
            X-Response-Timestamp:
              schema:
                type: string
                format: date-time
              example: '2026-06-01T11:09:26.581Z'
              required: true
              description: Timestamp of the COP Response in ISO 8601 UTC format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConfirmationOfPayeeError'
              examples:
                Internal Server Error:
                  value:
                    type: https://example.com/probs/SERVER_ERROR
                    code: SERVER_ERROR
                    title: Encountered an unexpected error/condition
                    status: 500
                    detail: Encountered an unexpected error/condition.
                    instance: /copgateway/v1.0/confirmation-payee/name-verification
        '502':
          description: Bad Gateway Error. This code is used whenever a technical problem occurred and the server acted as a gateway or proxy and received an invalid response from an upstream server.
          headers:
            x-fapi-interaction-id:
              schema:
                type: string
                format: uuid
              required: true
              description: An RFC4122 UUID used as a correlation id by the Requesting PSP
            X-Response-Timestamp:
              schema:
                type: string
                format: date-time
              example: '2026-06-01T11:09:26.581Z'
              required: true
              description: Timestamp of the COP Response in ISO 8601 UTC format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConfirmationOfPayeeError'
              examples:
                Bad Gateway Error:
                  value:
                    type: https://example.com/probs/SSL_ERROR
                    code: SSL_ERROR
                    title: SSL/TLS handshake failed
                    status: 502
                    detail: SSL/TLS handshake failed.
                    instance: /copgateway/v1.0/confirmation-payee/name-verification
      security:
        - gateway_auth:
            - default
components:
  schemas:
    NameVerificationRequest:
      description: The Confirmation of Payee POST request.
      type: object
      properties:
        data:
          $ref: '#/components/schemas/RequestData'
      required:
        - data
    NameVerificationResponse:
      description: The Confirmation of Payee POST response.
      type: object
      properties:
        data:
          $ref: '#/components/schemas/ResponseData'
      required:
        - data
    RequestData:
      description: The data model which contains and defines the structure for a Confirmation of Payee POST request.
      type: object
      properties:
        schemeName:
          description: Used within ISO 20022 to indicate the format of the Identification field. For CoP, this will always be “SortCodeAccountNumber”
          allOf: 
            - $ref: '#/components/schemas/SchemeName'
        accountType: 
          description: This is used to indicate whether the Payer or Payee is intending to pay/debit a personal or business account type. The two options are either:“Personal” or “Business”.
          allOf: 
            - $ref: '#/components/schemas/AccountType'
        identification:
          description: This is the 6-digit Sort Code followed by the 8-digit Account Number of the Payee (Account Numbers that contain less than 8-digits should be padded with preceding zeros to make 8-digits), which is used by the CoP Responder to identify the account records. There must be no spaces between them, and it must always be included.
          allOf: 
            - $ref: '#/components/schemas/Identification'
        name:
          description: This is the name as input by the Payment initiator, without truncation, that the CoP Responder will perform the matching against. This field is mandatory as there will always need to be a name passed to the CoP Responder.
          allOf: 
            - $ref: '#/components/schemas/Name'
        secondaryIdentification:
          description: This is for any Secondary Reference Data (SRD) that is input by the Payer when the CoP check is being made on an SRD account.
          allOf: 
            - $ref: '#/components/schemas/SecondaryIdentification'
      required:
        - schemeName
        - accountType
        - identification
        - name
    ResponseData:
      type: object
      properties:
        verificationReport:
          $ref: '#/components/schemas/VerificationReport'
      required:
        - verificationReport
    VerificationReport:
      description: The data model which contains and defines the structure for a Confirmation of Payee POST response.
      type: object
      properties:
        matched:
          description: Matched returns true for a match and false for all other outcomes.
          allOf: 
            - $ref: '#/components/schemas/Matched'
        reasonCode: 
          description: Valid Reason Codes for details of applicable codes. A code is returned when the verification did not result in a full match outcome.
          allOf: 
            - $ref: '#/components/schemas/ReasonCode'
        name:
          description: Returns the account name, in the event of a close match, in an unstructured string.
          allOf: 
            - $ref: '#/components/schemas/Name'
      required:
        - matched
    SchemeName:
      type: string
      enum: [SortCodeAccountNumber]
      example: 'SortCodeAccountNumber'
    AccountType:
      type: string
      enum: [Personal, Business] 
      example: 'Personal'
    Identification: 
      type: string
      pattern: '^[0-9]{14}$'
      example: '12345612345678'
    Name:
      type: string
      minLength: 1
      maxLength: 140
      example: 'John Smith'
    SecondaryIdentification:
      type: string
      minLength: 1
      maxLength: 140
      example: 'ABC-123456'
    Matched:
      type: boolean
      enum: [true, false]
      example: false
    ReasonCode:
      description: Specifies the regulated reason code giving context to the negative match result/outcome (Matched=false) for Confirmation of Payee.
      type: string
      enum: [ANNM, AC01, MBAM, OPTO, ACNS, IVCR, BANM, PANM, BAMM, PAMM, CASS, SCNS]
      example: 'ANNM'
    ConfirmationOfPayeeError:
      type: object
      properties:
        type: 
          $ref: '#/components/schemas/Max70Text'
        code:
          description: An entry provided by an external ISO code list.
          allOf:
            - $ref: '#/components/schemas/MessageCode'
        title:
          $ref: '#/components/schemas/Max70Text'
        status:
          type: integer
          enum: [400,401,500,502]
        detail:
          $ref: '#/components/schemas/Max500Text'
        instance:
          $ref: '#/components/schemas/Max256Text'
      required:
        - type
        - code
    MessageCode:
      type: string
      enum: [FORMAT_ERROR, CLIENT_INVALID, CLIENT_INCONSISTENT, TIMESTAMP_INVALID]
    Max70Text:
      type: string
      minLength: 0
      maxLength: 70
    Max256Text:
      type: string
      minLength: 0
      maxLength: 256
    Max500Text:
      type: string
      minLength: 0
      maxLength: 500
  securitySchemes:
    gateway_auth:
      type: oauth2
      description: |
        **OAuth 2.0 Client Credential Flow**

        **cURL Code Snippet**
        ```
        curl --location --request GET 'https://login.microsoftonline.com/{tenant_Id}/oauth2/v2.0/token' \
        --header 'Content-Type: application/x-www-form-urlencoded' \
        --data-urlencode 'grant_type=client_credentials' \
        --data-urlencode 'client_id={client_Id}' \
        --data-urlencode 'client_secret={client_Secret}' \
        --data-urlencode 'scope={scope_Id}/.default'
        ```
        <pre>
        - Values enclosed within the curly brackets "{}" shown above indicates a parameter and it should be replaced with your own values when executing.
        - Parameter values are "supplied on request".
        - Access Token Lifetime: 1 hour (3600 seconds)
        - Client Credential flow does not issue a refresh token, you must request a new access token when the current token expires.
        </pre>
      flows:
        clientCredentials:
          scopes:
            default: "{scope_Id}/.default"
