- Copyright and Liability Disclaimer
- Version Comments
- Profile - Services
  - get Get SP services list
  - get Get SP service info
  - post Link service authorization authority
  - del Unlink service authorization authority
  - post Set service host
  - del Delete service host
- Profile - Authorization Authorities
  - get Get authorization authorities list
  - post Create authorization authority
  - get Get authorization authority
  - post Patch authorization authority
  - del Delete authorization authority
  - post Add authorization authority key
  - del Delete authorization authority key
- Service Provider Registry
  - get Get service providers list
  - get Get service provider
- Services Registry
  - get Get flow types list
  - get Get payer registry services list
  - get Get payer registry service
  - get Download payer registry cache
  - get Get payee registry services list
  - get Get payee registry service
  - get Download payee registry cache
- Implementation Requirements
- Glossary

API docs by Redocly

# QR+ Service Provider Registry API (1.2.0)

Download OpenAPI specification:

The Paylink Registry service is used by Service Providers to manage their QR+ services and as an authoritative reference to build local, cached service registries for use during QR+ enrichment flows.

The high level entity relationships exposed by this interface are:

The api exposes the following perspectives:

- Service Administration: The `/profile` endpoints expose functionality for an authorized user to administer Service Provider services. This includes setting up Authorization Authorities and linking these authorities to Payer- and Payee- services.
- Service Registry: The `/service-providers` and `/flow-types` endpoints expose a registry of all service providers and registered services. This enables service provider infrastructure to create local mapping tables to derive host location and authorization authorities during QR+ flows.

## Copyright and Liability Disclaimer

Full Copyright and Liability Disclaimer

The QR+ Standard has been developed by the South African Reserve Bank for use by participants in the National Payment System. All intellectual property rights, including copyright and any related rights in and to the QR+ Standard, are owned by, or vest in, the South African Reserve Bank. No participant or other person acquires any ownership right, title or interest in the QR+ Standard by virtue of its access to, implementation of or use of the QR+ Standard. The QR+ Standard may not be copied, reproduced, adapted, amended, transferred, ceded, assigned, sublicensed, published, distributed or otherwise made available to any third party, in whole or in part, without the prior written consent of the South African Reserve Bank, except to the extent expressly permitted by the South African Reserve Bank.

Participants are responsible for developing, implementing, maintaining and operating their own systems, processes and controls to ensure compliance with the QR+ Standard and with all applicable laws, regulatory requirements and industry standards. The South African Reserve Bank does not warrant that the QR+ Standard, or any implementation thereof by a participant, will be error-free, uninterrupted, fit for any particular purpose or suitable for any participant’s specific operational or commercial requirements.

To the fullest extent permitted by law, the South African Reserve Bank shall not be liable for any loss, damage, claim, cost or expense, whether direct, indirect, special, incidental or consequential, arising from or in connection with a participant’s access to, reliance on, implementation of, or use of the QR+ Standard, including any failure by a participant to comply with the QR+ Standard or any applicable legal or regulatory requirement.

## Version Comments

Version: 1.2.0 (2026-06-05)

Release candidate 1.2.0-rc3 approved for publication

## Profile - Services

As a Service Provider, use these endpoints to manage your services.

## Get SP services list

As SP Administrator, use this endpoint to retrieve a list of all services configured for your Service Provider.

##### Authorizations:

bearerAuth

### Responses

http://localhost:3000/profile/services

### Response samples

- 200
- default

Content type
application/json
`
[

- {
  - "kind": "PAYEE",
  - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  - "spId": "north-big-bank",
  - "flowType": "pep-general",
  - "alias": "Payer presented offline service B"
  }

]`

## Get SP service info

As SP Administrator, use this endpoint to retrieve detailed information about a specific service configured for your Service Provider.

##### Authorizations:

bearerAuth

##### path Parameters

serviceId required | string <uuid> (ServiceId) Service Id

### Responses

http://localhost:3000/profile/services/{serviceId}

### Response samples

- 200
- default

Content type
application/json
Example
PAYEE
`
{

- "kind": "PAYEE",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "spId": "north-big-bank",
- "flowType": "pep-general",
- "alias": "Payer presented offline service B",
- "indicatorMappings":
  [
  - {
    - "encoding": "URI_ENCODED",
    - "flowTypeIndicator": "general",
    - "spIndicator": "xmpl"
    }
  ],
- "host": "https://best-link-provider.com/paylink/payer",
- "authzAuthorities":
  [
  - {
    - "kind": "SIGNED_BEARER_TOKEN",
    - "id": "c4dbf68e-9be0-4780-9e30-08d5414f3467",
    - "keys":
      [
      - {
        - "kty": "EC",
        - "alg": "ES256",
        - "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
        - "use": "sig",
        - "crv": "P-256",
        - "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
        - "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"
        }
      ]
    }
  ]

}`

## Link service authorization authority

As SP Administrator, use this endpoint to link an authorization authority to a service, enabling token-based authentication for that service.

##### Authorizations:

bearerAuth

##### path Parameters

serviceId required | string <uuid> (ServiceId) Service Id

##### Request Body schema: application/json
required

authorityId required | string <uuid> (AuthzAuthorityId) Authorization Authority Identifier

### Responses

http://localhost:3000/profile/services/{serviceId}/authz-authorities

### Request samples

- Payload

Content type
application/json
`
{

- "authorityId": "c4dbf68e-9be0-4780-9e30-08d5414f3467"

}`

### Response samples

- default

Content type
application/json
`
{

- "statusCode": 403,
- "title": "Forbidden: The client does not have access rights to the content or functionality.",
- "detail": "You do not have permission to access this resource",
- "instance": "0540fa0f-ccfa-4625-b006-725b4b580879",
- "extensions":
  [
  - {
    - "requiredPermission": "profile:read"
    }
  ]

}`

## Unlink service authorization authority

As SP Administrator, use this endpoint to unlink an authorization authority from a service, removing its ability to authorize token-based authentication for that service.

##### Authorizations:

bearerAuth

##### path Parameters

serviceId required | string <uuid> (ServiceId) Service Id
authzAuthorityId required | string <uuid> (AuthzAuthorityId) Example: c4dbf68e-9be0-4780-9e30-08d5414f3467 Authorization Authority Id

### Responses

http://localhost:3000/profile/services/{serviceId}/authz-authorities/{authzAuthorityId}

### Response samples

- default

Content type
application/json
`
{

- "statusCode": 403,
- "title": "Forbidden: The client does not have access rights to the content or functionality.",
- "detail": "You do not have permission to access this resource",
- "instance": "0540fa0f-ccfa-4625-b006-725b4b580879",
- "extensions":
  [
  - {
    - "requiredPermission": "profile:read"
    }
  ]

}`

## Set service host

As SP Administrator, use this endpoint to configure the host URL for a service where API calls should be directed.

##### Authorizations:

bearerAuth

##### path Parameters

serviceId required | string <uuid> (ServiceId) Service Id

##### Request Body schema: application/json
required

host required | string <uri> (ServiceHost) <= 128 characters The https url where the service is hosted.

### Responses

http://localhost:3000/profile/services/{serviceId}/host

### Request samples

- Payload

Content type
application/json
`
{

- "host": "https://best-link-provider.com/paylink/payer"

}`

### Response samples

- 200
- default

Content type
application/json
`
{

- "host": "https://best-link-provider.com/paylink/payer"

}`

## Delete service host

As SP Administrator, use this endpoint to remove the configured host URL for a service. This effectively decommissions the service from the network.

##### Authorizations:

bearerAuth

##### path Parameters

serviceId required | string <uuid> (ServiceId) Service Id

### Responses

http://localhost:3000/profile/services/{serviceId}/host

### Response samples

- default

Content type
application/json
`
{

- "statusCode": 403,
- "title": "Forbidden: The client does not have access rights to the content or functionality.",
- "detail": "You do not have permission to access this resource",
- "instance": "0540fa0f-ccfa-4625-b006-725b4b580879",
- "extensions":
  [
  - {
    - "requiredPermission": "profile:read"
    }
  ]

}`

## Profile - Authorization Authorities

As a Service Provider, use these endpoints to manage your authorization authorities.

## Get authorization authorities list

As SP Administrator, use this endpoint to retrieve a list of all authorization authorities configured for your Service Provider.

##### Authorizations:

bearerAuth

### Responses

http://localhost:3000/profile/authz-authorities

### Response samples

- 200
- default

Content type
application/json
`
[

- {
  - "kind": "SIGNED_BEARER_TOKEN",
  - "id": "c4dbf68e-9be0-4780-9e30-08d5414f3467",
  - "createdAt": "2026-07-02T17:32:26.581Z",
  - "isRegistryAuthority": false,
  - "alias": "Paylink Auth Key 2025-06"
  }

]`

## Create authorization authority

As SP Administrator, use this endpoint to create a new authorization authority for your Service Provider to manage API token authentication.

##### Authorizations:

bearerAuth

##### Request Body schema: application/json
required

kind required | string SIGNED_BEARER_TOKEN Value: "SIGNED_BEARER_TOKEN"
isRegistryAuthority | boolean Default: false Stipulates whether this authority can authorize registry updates
alias | string (AuthzAuthorityAlias) <= 128 characters A Member recognizable name for the authorization authority

### Responses

http://localhost:3000/profile/authz-authorities

### Request samples

- Payload

Content type
application/json
`
{

- "kind": "SIGNED_BEARER_TOKEN"

}`

### Response samples

- 201
- default

Content type
application/json
`
{

- "kind": "SIGNED_BEARER_TOKEN",
- "id": "c4dbf68e-9be0-4780-9e30-08d5414f3467",
- "linkedPayerServices":
  [
  - {
    - "kind": "PAYER",
    - "serviceId": "8f8bb40f-b96b-40fe-9064-5031fbe483f9",
    - "flowType": "pep-general"
    }
  ],
- "linkedPayeeServices":
  [
  - {
    - "kind": "PAYEE",
    - "serviceId": "8f8bb40f-b96b-40fe-9064-5031fbe483f9",
    - "flowType": "pep-general"
    }
  ],
- "createdAt": "2026-07-02T17:32:26.581Z",
- "alias": "Paylink Auth Key 2025-06",
- "isRegistryAuthority": false,
- "keys":
  [
  - {
    - "kty": "EC",
    - "alg": "ES256",
    - "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
    - "use": "sig",
    - "crv": "P-256",
    - "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
    - "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"
    }
  ]

}`

## Get authorization authority

As SP Administrator, use this endpoint to retrieve detailed information about a specific authorization authority.

##### Authorizations:

bearerAuth

##### path Parameters

authzAuthorityId required | string <uuid> (AuthzAuthorityId) Example: c4dbf68e-9be0-4780-9e30-08d5414f3467 Authorization Authority Id

### Responses

http://localhost:3000/profile/authz-authorities/{authzAuthorityId}

### Response samples

- 200
- default

Content type
application/json
`
{

- "kind": "SIGNED_BEARER_TOKEN",
- "id": "c4dbf68e-9be0-4780-9e30-08d5414f3467",
- "linkedPayerServices":
  [
  - {
    - "kind": "PAYER",
    - "serviceId": "8f8bb40f-b96b-40fe-9064-5031fbe483f9",
    - "flowType": "pep-general"
    }
  ],
- "linkedPayeeServices":
  [
  - {
    - "kind": "PAYEE",
    - "serviceId": "8f8bb40f-b96b-40fe-9064-5031fbe483f9",
    - "flowType": "pep-general"
    }
  ],
- "createdAt": "2026-07-02T17:32:26.581Z",
- "alias": "Paylink Auth Key 2025-06",
- "isRegistryAuthority": false,
- "keys":
  [
  - {
    - "kty": "EC",
    - "alg": "ES256",
    - "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
    - "use": "sig",
    - "crv": "P-256",
    - "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
    - "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"
    }
  ]

}`

## Patch authorization authority

As SP Administrator, use this endpoint to update specific fields of an authorization authority configuration.

##### Authorizations:

bearerAuth

##### path Parameters

authzAuthorityId required | string <uuid> (AuthzAuthorityId) Example: c4dbf68e-9be0-4780-9e30-08d5414f3467 Authorization Authority Id

##### Request Body schema: application/json
required

kind required | string Value: "SIGNED_BEARER_TOKEN"
isRegistryAuthority | boolean Default: false Stipulates whether this authority can authorize registry updates
| AuthzAuthorityAlias (string) or null

### Responses

http://localhost:3000/profile/authz-authorities/{authzAuthorityId}

### Request samples

- Payload

Content type
application/json
`
{

- "kind": "SIGNED_BEARER_TOKEN"

}`

### Response samples

- 200
- default

Content type
application/json
`
{

- "kind": "SIGNED_BEARER_TOKEN",
- "id": "c4dbf68e-9be0-4780-9e30-08d5414f3467",
- "linkedPayerServices":
  [
  - {
    - "kind": "PAYER",
    - "serviceId": "8f8bb40f-b96b-40fe-9064-5031fbe483f9",
    - "flowType": "pep-general"
    }
  ],
- "linkedPayeeServices":
  [
  - {
    - "kind": "PAYEE",
    - "serviceId": "8f8bb40f-b96b-40fe-9064-5031fbe483f9",
    - "flowType": "pep-general"
    }
  ],
- "createdAt": "2026-07-02T17:32:26.581Z",
- "alias": "Paylink Auth Key 2025-06",
- "isRegistryAuthority": false,
- "keys":
  [
  - {
    - "kty": "EC",
    - "alg": "ES256",
    - "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
    - "use": "sig",
    - "crv": "P-256",
    - "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
    - "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"
    }
  ]

}`

## Delete authorization authority

As SP Administrator, use this endpoint to delete an authorization authority.

##### Authorizations:

bearerAuth

##### path Parameters

authzAuthorityId required | string <uuid> (AuthzAuthorityId) Example: c4dbf68e-9be0-4780-9e30-08d5414f3467 Authorization Authority Id

### Responses

http://localhost:3000/profile/authz-authorities/{authzAuthorityId}

### Response samples

- default

Content type
application/json
`
{

- "statusCode": 403,
- "title": "Forbidden: The client does not have access rights to the content or functionality.",
- "detail": "You do not have permission to access this resource",
- "instance": "0540fa0f-ccfa-4625-b006-725b4b580879",
- "extensions":
  [
  - {
    - "requiredPermission": "profile:read"
    }
  ]

}`

## Add authorization authority key

As SP Administrator, use this endpoint to add a cryptographic public key (JWK) to an authorization authority for token verification.

##### Authorizations:

bearerAuth

##### path Parameters

authzAuthorityId required | string <uuid> (AuthzAuthorityId) Example: c4dbf68e-9be0-4780-9e30-08d5414f3467 Authorization Authority Id

##### Request Body schema: application/json
required

kty required | string Key Type EC Value: "EC"
alg required | string Enum: "ES256" "ES384" "ES512" ECDSA Algorithm
kid required | string (Kid) [ 36 .. 128 ] characters ^[A-Za-z0-9_-]+$ Cryptographic key identifier - UUID or base64url-encoded thumbprint (min 36 chars for collision resistance)
use required | string Public key use - signature verification only Value: "sig"
crv required | string Enum: "P-256" "P-384" "P-521" NIST P-curve (FIPS 186-4 compliant)
x required | string <= 128 characters ^[A-Za-z0-9_-]+$ X Coordinate - Base64Url encoded
y required | string <= 128 characters ^[A-Za-z0-9_-]+$ Y Coordinate - Base64Url encoded

### Responses

http://localhost:3000/profile/authz-authorities/{authzAuthorityId}/keys

### Request samples

- Payload

Content type
application/json
Example
EC
`
{

- "kty": "EC",
- "alg": "ES256",
- "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
- "use": "sig",
- "crv": "P-256",
- "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
- "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"

}`

### Response samples

- 201
- default

Content type
application/json
Example
EC
`
{

- "kty": "EC",
- "alg": "ES256",
- "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
- "use": "sig",
- "crv": "P-256",
- "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
- "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"

}`

## Delete authorization authority key

As SP Administrator, use this endpoint to remove a cryptographic key from an authorization authority.

##### Authorizations:

bearerAuth

##### path Parameters

authzAuthorityId required | string <uuid> (AuthzAuthorityId) Example: c4dbf68e-9be0-4780-9e30-08d5414f3467 Authorization Authority Id
kid required | string (Kid) [ 36 .. 128 ] characters ^[A-Za-z0-9_-]+$ Example: bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU Key Id

### Responses

http://localhost:3000/profile/authz-authorities/{authzAuthorityId}/keys/{kid}

### Response samples

- default

Content type
application/json
`
{

- "statusCode": 403,
- "title": "Forbidden: The client does not have access rights to the content or functionality.",
- "detail": "You do not have permission to access this resource",
- "instance": "0540fa0f-ccfa-4625-b006-725b4b580879",
- "extensions":
  [
  - {
    - "requiredPermission": "profile:read"
    }
  ]

}`

## Service Provider Registry

Use the `/service-providers` endpoints to discover the owners of services.

## Get service providers list

As SP Operator, use this endpoint to retrieve a list of all Service Providers registered in the QR+ network.

##### Authorizations:

bearerAuth

### Responses

http://localhost:3000/service-providers

### Response samples

- 200
- default

Content type
application/json
`
[

- {
  - "id": "north-big-bank",
  - "companyName": "Big Company Pty Ltd"
  }

]`

## Get service provider

As SP Operator, use this endpoint to retrieve detailed information about a specific Service Provider.

##### Authorizations:

bearerAuth

##### path Parameters

spId required | string (ServiceProviderId) [ 5 .. 36 ] characters ^[a-z]+(?:-[a-z]+)*$ Example: north-big-bank Unique service provider id

### Responses

http://localhost:3000/service-providers/{spId}

### Response samples

- 200
- default

Content type
application/json
`
{

- "id": "north-big-bank",
- "name": "Big Company Pty Ltd",
- "serviceSupportPhone": "+27821234567",
- "serviceSupportEmail": "email@example.com",
- "payerServices":
  [
  - {
    - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    - "flowType": "pep-general"
    }
  ],
- "payeeServices":
  [
  - {
    - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    - "flowType": "pep-general"
    }
  ]

}`

## Services Registry

Use these endpoints to create a local cache of QR+ services.

### For Payer Service Providers (PrSP)

As PrSP you will create a local Registry Cache to:

- Do a lookup to find the PeSP service host address corresponding to the spIndicator extracted from a scanned Paylink
- Authenticate PeSP calls to your API and confirm their rights to execute specific QR+ flow types.

Building Payee Services Registry:

1. Get flow types: `GET /flow-types`
2. Retrieve all services by:
   1. Either, retrieving the service list by flow type `GET /flow-types/{flowType}/payee-services` and then, for each service, doing `GET /flow-types/{flowType}/payee-services/{serviceId}`
   2. Or, downloading the full registry `GET /flow-types/{flowType}/payee-registry-cache`
3. Build a local cache for:
   1. Paylink service provider host resolution `(encoding, flowTypeIndicator, spIndicator) → {host}`
   2. JWT validation `(iss, sub, aud) → {authzAuthority keys}`

### For Payee Service Providers (PeSP)

As a PeSP you will create a local Payer Services Registry to:

- Do a lookup to find the PrSP service host address corresponding to the spIndicator extracted from a scanned Paylink
- Authenticate PrSP calls to your API and confirm their rights to execute specific QR+ flow types.

Building Payer Services Registry:

1. Get flow types: `GET /flow-types`
2. Retrieve all services by:
   1. Either, retrieving the service list by flow type `GET /flow-types/{flowType}/payer-services` and then, for each service, doing `GET /flow-types/{flowType}/payer-services/{serviceId}`
   2. Or, downloading the full registry `GET /flow-types/{flowType}/payer-registry-cache`
3. Build a local cache for:
   1. Paylink service provider host resolution `(encoding, flowTypeIndicator, spIndicator) → {host}`
   2. JWT validation `(iss, sub, aud) → {authzAuthority keys}`

## Get flow types list

As SP Operator, use this endpoint to retrieve the list of supported flow types in the QR+ network.

##### Authorizations:

bearerAuth

### Responses

http://localhost:3000/flow-types

### Response samples

- 200
- default

Content type
application/json
`
[

- "pep-general",
- "pep-shortcode",
- "prp-connected",
- "prp-disconnected"

]`

## Get payer registry services list

As SP Operator, use this endpoint to retrieve a list of all Payer services for a specific flow type to build your local registry cache.

##### Authorizations:

bearerAuth

##### path Parameters

flowType required | string (FlowType) [ 2 .. 32 ] characters ^[a-zA-Z0-9-._~]*$ Example: pep-general Flow type

### Responses

http://localhost:3000/flow-types/{flowType}/payer-services

### Response samples

- 200
- default

Content type
application/json
`
[

- {
  - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  - "flowType": "pep-general",
  - "spId": "north-big-bank"
  }

]`

## Get payer registry service

As SP Operator, use this endpoint to retrieve detailed information about a specific Payer service supporting a flow type.

##### Authorizations:

bearerAuth

##### path Parameters

flowType required | string (FlowType) [ 2 .. 32 ] characters ^[a-zA-Z0-9-._~]*$ Example: pep-general Flow type
serviceId required | string <uuid> (ServiceId) Service id

### Responses

http://localhost:3000/flow-types/{flowType}/payer-services/{serviceId}

### Response samples

- 200
- default

Content type
application/json
`
{

- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "flowType": "pep-general",
- "spId": "north-big-bank",
- "authzAuthorities":
  [
  - {
    - "kind": "SIGNED_BEARER_TOKEN",
    - "id": "c4dbf68e-9be0-4780-9e30-08d5414f3467",
    - "keys":
      [
      - {
        - "kty": "EC",
        - "alg": "ES256",
        - "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
        - "use": "sig",
        - "crv": "P-256",
        - "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
        - "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"
        }
      ]
    }
  ],
- "indicatorMappings":
  [
  - {
    - "encoding": "URI_ENCODED",
    - "flowTypeIndicator": "general",
    - "spIndicator": "xmpl"
    }
  ],
- "host": "https://best-link-provider.com/paylink/payer"

}`

## Download payer registry cache

As SP Operator, use this endpoint as an alternative to download a complete registry cache of all Payer services for a specific flow type. The cache is a JSON document that conforms to the published Payer Registry Cache schema. Response includes ETag header for efficient conditional updates.

##### Authorizations:

bearerAuth

##### path Parameters

flowType required | string (FlowType) [ 2 .. 32 ] characters ^[a-zA-Z0-9-._~]*$ Example: pep-general Flow type

##### header Parameters

If-None-Match | string Conditional request header containing ETag value from previous response. If the cache has not changed (ETag matches), server returns 304 Not Modified with no body.

### Responses

http://localhost:3000/flow-types/{flowType}/payer-registry-cache

### Response samples

- 200
- default

Content type
application/json
`
{

- "serviceType": "PAYER",
- "createdAt": "2026-07-02T17:32:26.581Z",
- "flowType": "pep-general",
- "services":
  [
  - {
    - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    - "flowType": "pep-general",
    - "spId": "north-big-bank",
    - "authzAuthorities":
      [
      - {
        - "kind": "SIGNED_BEARER_TOKEN",
        - "id": "c4dbf68e-9be0-4780-9e30-08d5414f3467",
        - "keys":
          [
          - {
            - "kty": "EC",
            - "alg": "ES256",
            - "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
            - "use": "sig",
            - "crv": "P-256",
            - "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
            - "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"
            }
          ]
        }
      ],
    - "indicatorMappings":
      [
      - {
        - "encoding": "URI_ENCODED",
        - "flowTypeIndicator": "general",
        - "spIndicator": "xmpl"
        }
      ],
    - "host": "https://best-link-provider.com/paylink/payer"
    }
  ]

}`

## Get payee registry services list

As SP Operator, use this endpoint to retrieve a list of all Payee services supporting a specific flow type to build your local registry cache.

##### Authorizations:

bearerAuth

##### path Parameters

flowType required | string (FlowType) [ 2 .. 32 ] characters ^[a-zA-Z0-9-._~]*$ Example: pep-general Flow type

### Responses

http://localhost:3000/flow-types/{flowType}/payee-services

### Response samples

- 200
- default

Content type
application/json
`
[

- {
  - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  - "flowType": "pep-general",
  - "spId": "north-big-bank"
  }

]`

## Get payee registry service

As SP Operator, use this endpoint to retrieve detailed information about a specific Payee service supporting a flow type.

##### Authorizations:

bearerAuth

##### path Parameters

flowType required | string (FlowType) [ 2 .. 32 ] characters ^[a-zA-Z0-9-._~]*$ Example: pep-general Flow type
serviceId required | string <uuid> (ServiceId) Payee service id

### Responses

http://localhost:3000/flow-types/{flowType}/payee-services/{serviceId}

### Response samples

- 200
- default

Content type
application/json
`
{

- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "flowType": "pep-general",
- "spId": "north-big-bank",
- "authzAuthorities":
  [
  - {
    - "kind": "SIGNED_BEARER_TOKEN",
    - "id": "c4dbf68e-9be0-4780-9e30-08d5414f3467",
    - "keys":
      [
      - {
        - "kty": "EC",
        - "alg": "ES256",
        - "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
        - "use": "sig",
        - "crv": "P-256",
        - "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
        - "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"
        }
      ]
    }
  ],
- "indicatorMappings":
  [
  - {
    - "encoding": "URI_ENCODED",
    - "flowTypeIndicator": "general",
    - "spIndicator": "xmpl"
    }
  ],
- "host": "https://best-link-provider.com/paylink/payer"

}`

## Download payee registry cache

As SP Operator, use this endpoint as an alternative to download a complete registry cache of all Payee services for a specific flow type. The cache is a JSON document that conforms to the published Payee Registry Cache schema. Response includes ETag header for efficient conditional updates.

##### Authorizations:

bearerAuth

##### path Parameters

flowType required | string (FlowType) [ 2 .. 32 ] characters ^[a-zA-Z0-9-._~]*$ Example: pep-general Flow type

##### header Parameters

If-None-Match | string Conditional request header containing ETag value from previous response. If the cache has not changed (ETag matches), server returns 304 Not Modified with no body.

### Responses

http://localhost:3000/flow-types/{flowType}/payee-registry-cache

### Response samples

- 200
- default

Content type
application/json
`
{

- "serviceType": "PAYEE",
- "createdAt": "2026-07-02T17:32:26.581Z",
- "flowType": "pep-general",
- "services":
  [
  - {
    - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    - "flowType": "pep-general",
    - "spId": "north-big-bank",
    - "authzAuthorities":
      [
      - {
        - "kind": "SIGNED_BEARER_TOKEN",
        - "id": "c4dbf68e-9be0-4780-9e30-08d5414f3467",
        - "keys":
          [
          - {
            - "kty": "EC",
            - "alg": "ES256",
            - "kid": "bq2wK4mVA6ahC1aUooSHO7i5PO_gbIkOQ5U2cYg5mnU",
            - "use": "sig",
            - "crv": "P-256",
            - "x": "f83OJ3D2xF4a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l",
            - "y": "x_FEzRu9u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5lFh9a8u5l"
            }
          ]
        }
      ],
    - "indicatorMappings":
      [
      - {
        - "encoding": "URI_ENCODED",
        - "flowTypeIndicator": "general",
        - "spIndicator": "xmpl"
        }
      ],
    - "host": "https://best-link-provider.com/paylink/payer"
    }
  ]

}`

## Implementation Requirements

### Registry Cache Refresh

A key responsibility of the QR+ Registry is to enable Clients to refresh their local Registry Cache.

- Clients MUST NOT initiate a cache refresh request more than once in any 30 minute period
- Clients SHOULD initiate a cache refresh request every 3 hours
- Clients MUST initiate a cache refresh request at least once every 24 hours. If a Client has not executed a successful cache refresh request within this period, it should consider the cache stale and NOT execute QR+ flows using the configuration data.

#### Registry Config Data Migration

Client implementations of the Registry API must take care to assure system configuration integrity over the cache refresh cycles described above. All configuration changes must assure secure and functional operation of all current Registry Cache versions. To achieve this:

- When updating the service `host` address, the service MUST be available at both old and new address for the next 24 hours
- When associating a new Authorization Authority public key with a service (either by linking a Authorization Authority to a service or by adding a new key) the key MUST only enter use 24 hours after the update
- When deploying a new Authorization Authority key for authentication, the related public key MUST be associated with the service for at least 24 hours.
- When disassociating an Authorization Authority public key from a service (either by unlinking a Authorization Authority from a service or by deleting a key) the key MUST NOT be in use and the alternative MUST have been configured for at least 24 hours

### Bearer Token Validation

This API uses a JWT based (RFC7519), http bearer token security scheme. The JWT MUST be signed by an authorization authority registered to the QR+ Registry against a Service Provider profile. The API user identity is derived from the JWT issuer and key id.

### JWT claims

The JWT MUST contain the following Claims:

- `iss` : Issuer Claim containing the `authzAuthorityId` as allocated by the QR+ Registry
- `sub` : The Service Provider's `spId` as allocated by the QR+ Registry.
- `aud` : Audience Claim containing the value `registry`
- `exp` : Expiration time Claim defining a time of expiry for this token
- `permissions` : An array of permissions for authorization from:
  - `view:profile` - Can view SP registry profile,
  - `update:profile` - Can update SP registry profile,
  - `view:registry` - Can view registry and build local cache

### JWT header

The JWT header must contain the following parameters:

- `alg` : The JOSE algorithm used for JWT generation
- `kid` : The key id of the authorization authority key used to generate the JWT

### JWT Validation

Implementers of this API must satisfy the following minimum requirements when validating a presented JWT:

- Best Practice: Follow best practices as outlined in RFC8725 and related standards
- User Identity: The API user identity MUST be determined as the Service Provider (`sub`) only when (i) the Issuer claim (`iss`) matches an Authorization Authority belonging to the Service Provider and (ii) The key id of the key used is linked to the Authorization Authority
- Algorithms: JWT MUST fail if the `alg` property in the header is set to 'none' or if it does not align with the key type of the referenced kid
- Audience validation: The `aud` Claim MUST be `registry` to access Registry functionality.
- Registry authority validation: The referenced issuer Authorization Authority MUST have its `isRegistryAuthority` flag on the Registry set to `true`.

## Glossary

Term | Description
--- | ---
Acceptance Option | A payload specifying a payment rail supported by a Payee for payment. (Option Payload)
Anchor Domain | The common domain used for all Paylink web URIs, allowing deep linking through officially registered mobile applications.
Authorization Authority | An entity, managed on the QR+ Registry, which represents a Service Provider IdP that issues bearer tokens to authenticate API calls. A Service Provider manages Authorization Authorities according to their governance and security policies.
Extended Number Encoded Paylink | A 27-character alphanumeric Paylink format (ZA-FTI-SPII-PLV) optimized for Code128 barcode scanning with extended PLV namespace for medium lifespan experiences.
Facilitated Experience | The experience where the Scanner uses a Paylink Facilitator Application to start a QR+ Flow.
Flow | A Flow is the set of actions executed between a PrSP and PeSP as part of one QR+ session.
Flow Record | An audit trail record, created by both PrSP and PeSP, capturing all Service Provider Interactions exchanged as part of a unique Flow.
Flow Session | A time-bound session that tracks the lifecycle of a Flow with states OPEN, TERMINATED, or EXPIRED. A PrSP only process PeSP Requests while a Flow Session is OPEN.
Flow Tracker | A structured object within Service Provider Interactions containing Flow identifiers and Message Sequence Numbers to coordinate and track messages within a Flow.
Flow Type | A classification of QR+ Flows which govern use case requirements, Paylink lifespan constraints, supported encodings, and security requirements (e.g., pep-general, pep-shortcode, prp-connected, prp-disconnected). Service Providers are licensed for individual Flow Types.
Flow Type Indicator | An encoding-specific identifier that indicates which Flow Type is being used (e.g., 'general' representing the pep-general Flow Type in URI encoded Paylinks and '1' representing the prp-shortcode Flow TYpe in number encoded Paylinks).
Identity Request | A QR+ Request for Payer identity information initiated by the PeSP on behalf of the Payee.
Loyalty Request | A QR+ Request for Payer loyalty membership information initiated by the PeSP on behalf of the Payee.
Message Sequence Number | An incrementing counter maintained by each Service Provider to track the ordering and uniqueness of messages sent within a Flow. Used for audit, idempotency and replay detection.
Number Encoded Paylink | A 13-digit numeric Paylink format (FTI-SPII-PLV-Luhn) optimized for human reproduction via voice or manual keypad entry with built-in error detection.
Payee (actor) | A party who interacts with a Paylink with the intention of receiving payment. The Payee can be either a Scanner or a Presenter depending on the use case.
Payee Service Provider (PeSP) | A registered organization that executes QR+ enrichment flows on behalf of a Payee. The PeSP may deploy Paylink Provider and/or Paylink Facilitator functionality depending on its supported experiences.
Payer (actor) | A party who interacts with a Paylink with intention to pay. The Payer can be either a Scanner or a Presenter depending on the use case.
Payer Service Provider (PrSP) | A registered organization that executes QR+ enrichment flows on behalf of a Payer. The PrSP may deploy Paylink Provider and/or Paylink Facilitator functionality depending on its supported experiences.
Paylink | A structured identifier, encoded and presented in various formats, used by Payers and Payees to initiate a financial interaction.
Paylink actioning | The Scanner scanning the Paylink and submitting it to its Service Provider for processing.
Paylink Encoding Format | A Paylink Encoding Format is a specific way the Paylink attributes are encoded. For example, URI encoded format.
Paylink Facilitator (role) | A PrSP or PeSP organization registered to process Paylinks for Scanners.
Paylink generation | An exchange between the Presenter (Payee or Payer) and the Service Provider (PeSP or PrSP) to generate a new Paylink.
Paylink presentment | The Presenter presenting the Paylink to the Scanner for scanning.
Paylink Presentment Format | A Paylink presentment format specifies the technology used to present the Paylink for scanning. For example, QR code, Barcode and web click.
Paylink Provider (role) | A PrSP or PeSP registered to create Paylinks for Presenters.
Paylink Quarantine Period | The period, after a Paylink has been cancelled, during which the PLV must not be used for a new Paylink.
Paylink resolution | The Paylink Facilitator presenting the Paylink to the Paylink Provider to initiate a QR+ flow.
Paylink Value (PLV) | The cryptographically secure random identifier component within a Paylink that uniquely identifies a specific Paylink instance.
Payment Confirmation | A rail-specific payload passed by the PrSP to the PeSP confirming successful initiation of a Push Payment, without claiming settlement status.
Payment Conclusion | A rail-specific payload passed by the PeSP to the PrSP to provide its view on the outcome of a Payment Request.
Payment Delegation | A rail-specific payload passed by the PrSP to the PeSP containing Pull Payment credentials and transaction details, delegating payment initiation to the PeSP.
Payment Request | A QR+ Request for payment initiated by the PeSP on behalf of the Payee.
Presenter (role) | A Payer or Payee who presents a Paylink to a Scanner party to action. The Presenter interacts with her Service Provider to create the Paylink according to her requirements.
Pull Payment | A payment mechanism that is initiated by a PeSP.
Push Payment | A payment mechanism that is initiated by a PrSP.
QR+ Flow Orchestration | The process of coordinating actions between the PrSP, PeSP, Payer and Payee to achieve a successful transaction outcome.
QR+ Registry Service | A service operated by NPU to enable service discovery of registered Service Providers and Services.
QR+ Service Provider | An organization registered to take part in QR+ flows on behalf of Payers and/or Payees.
Scanner (role) | A party who actions a Paylink by submitting it to their chosen Paylink Facilitator.
Service Provider Indicator | An encoding-specific identifier, assigned by SARB to a registered Service Provider, which allows all Service Providers to identify them as the creator of a Paylink.
Service Provider Interaction | A request and response exchange between a PrSP and a PeSP during a Flow, captured for audit trail, Flow analysis, and idempotency purposes.
Signed CBOR Encoded Paylink | A cryptographically signed Concise Binary Object Representation (CBOR) Paylink format using ECDSA signatures for high-security use cases requiring cryptographic attestation.
URI Encoded Paylink | A non-URL, RFC3986-compliant URI format for Paylinks (`qr-plus://<anchor domain>/v1/<flowTypeIndicator>/<spIndicator>/<plv>`) supporting deep linking and extended lifespans.