FINI API User Guide

 

  Index      Manuals 

 

Search            copyright infringement  

    

 

   

 

   

 

 

 

 

 

FINI API User Guide

 

 

Fast Interface for New Issuance (FINI)
FINI API User Guide
Contents
1
Introduction
5
2
Connectivity Setup
6
2.1
Create Agent Profile
6
2.2
Create Machine Profile
7
2.3
Obtain FINI API JWT Access Token
8
2.4
Invoke FINI APIs
15
3
End-to-End Encryption
16
3.1
Obtaining Crypto Metadata for Encryption
16
3.2
Encrypting API Requests
17
3.3
Decrypting API Responses
22
3.4
End-to-End Encryption Error Codes and Messages
23
4
Formats and Conventions
24
4.1
Identifiers
24
4.2
Data Formats
25
4.3
Request Field Conventions
27
4.4
Response Field Conventions
31
5
API Endpoints
35
5.1
Overview
35
5.2
Throttles
35
6
IPO Reference Data
36
6.1
Enquire IPO List
36
6.2
Enquire IPO Reference Data
38
7
EIPO Subscription
52
7.1
Add EIPO Subscription Entries
52
7.2
Change EIPO Subscription Entries
56
7.3
Invalidate EIPO Subscription Entries
59
7.4
Enquire EIPO Subscription Entries
61
8
EIPO Funding
65
8.1
Enquire EIPO Funding
65
8.2
Confirm EIPO Funding
70
9
FAQs for External User Testing (EUT) & Production
73
9.1
FINI API Connectivity
73
9.2
FINI API Authentication
73
9.3
EIPO Subscription Entries APIs encryption
74
9.4
FINI API endpoint validation
75
9.5
Miscellaneous
76
1
Version(s)
Publication Date
Version
25 Jul 2023
Changes:
[Current]
 Update message sample on field priceMax and poMaxValue to correct syntax (Section 8.1.2)
6 June 2023
Changes:
 Update host name of production Access Management server (Section 2.3.3)
 Update description of field “specialistTechIndicator” (Enquire IPO Reference Data Endpoint)
 Update descriptions of fields “idNum” and “fullNameChi”, field “fulNameEng” supports
alphanumeric characters (Section 7.1.1 & 7.2.1 )
 Update FAQ in Section 9
21 April 2023
Changes:
 Add field “specialistTechIndicator” (Enquire IPO Reference Data Endpoint) - available in End
User Testing environment from 8 May 2023
 Revise field length and description of “nomBankAcctNum” (Enquire EIPO Funding Endpoint)
 Add FAQ in Section 9
21 February 2023
Changes:
 Revise the request example (recordID) of Enquire EIPO Subscription Entries (see Section
7.4.1)
 Revise the request example (transactionRef) of Enquire EIPO Funding (see Section 8.1.1)
20 January 2023
Changes:
 Revise field formats for “nomCur” (and the currency code list), “clawback” and “pricingDate”
(Enquire IPO Reference Data Endpoint)
 Rename field “frcoLevy” to “afrcTransactionLevy” (Enquire IPO Reference Data Endpoint)
 Revise field length and description of “partName” and add “Not Applicable” code to
“preFundingStatus” and “settlementStatus” (Enquire EIPO Funding Endpoint)
8 November 2022
Cosmetic updates:
 Added table of contents for other FINI User Guides
 Amended references to Agent and Machine Profile setup to HKEX Access Management User
Guide (from HKEX Client Connect User Manual) (See Section 2)
9 September 2022
Changes:
 Amended Java implementation sample source code for generating X-FINI-SIGNATURE header
(See Section 3.2.3)
 Added section to explain structure of unsuccessful responses (See Section 4.4.3)
 Removed upwards price flexibility-related fields (Enquire IPO Reference Data Endpoint and
Enquire EIPO Funding Endpoint)
13 July 2022
Changes:
 "sub" field for signing Agent Profile JWT (G1) has been amended from "hkexapi" to the user’s
Company ID in Client Connect (See Section 2.3.1.2)
27 May 2022
Changes:
 Supplemented End-to-End Encryption procedures (See Section 3)
 Added warrants fields for SPACs (Enquire IPO Reference Data Endpoint)
 Renamed several adviser fields for SFC Code of Conduct (Enquire IPO Reference Data
Endpoint)
Minor formatting:
 All data payloads unified as arrays (from objects)
 IPO identifier unified as "ipoID"
 IPO Status values updated for "Suspended" and "Cancelled"
5 January 2022
Initial version released to market participants in preparation of market testing.
2
Disclaimer
HKEX and/or its subsidiaries endeavour to ensure the accuracy and reliability of the information provided, but do not
guarantee its accuracy and reliability and accept no liability (whether in tort or contract or otherwise) for any loss or
damage arising from any inaccuracy or omission or from any decision, action or non-action based on or in reliance
upon information contained in this document.
No part of this document may be copied, distributed, transmitted, transcribed, stored in a retrieval system, translated
into any human or computer language, or disclosed to third parties without written permission from HKEX.
HKEX reserves the right to amend any details in this document at any time, without notice.
3
FINI User Guides
Document
FINI user categories
User Guide for HKSCC Participants
 HKSCC Participant (“CP”)
 Designated EIPO Bank of CPs (“DB”)
User Guide for FINI Banks
 Receiving Bank of IPO Issuers (“RB”)
 Designated Sponsor
 Other Sponsor
 Sponsor Counsel
User Guide for Sponsors, Intermediaries and Legal Advisers
 Issuer Counsel
 Designated Overall Coordinator (“DOC”)
 Other Overall Coordinator
 Distributor
 All user categories above [IPO Reference Data]
API Guide [current document]
 HKSCC Participant (“CP”) [EIPO Subscription]
 Designated EIPO Bank of CPs (“DB”) [EIPO Funding]
4
1 Introduction
The FINI API Gateway offers a range of RESTful JSON endpoints for market participants to automate different types of
IPO workflows, including obtaining IPO reference data, managing EIPO subscriptions and validating EIPO funding.
This version is being released to market participants in preparation of FINI’s market-wide testing, and may be further
refined during market rehearsal and before FINI’s roll-out.
For further information on the FINI platform and testing phases, please visit the FINI website at:
https://www.hkex.com.hk/fini , or via the QR code below:
5
2 Connectivity Setup
To access the FINI API Gateway, market participants are required to create an Agent profile and at most 2 Machine
profiles under their Company profile on the HKEX Access Management Platform.
After the Agent profile and Machine profile(s) have been created, FINI API users, as OAUTH client, have to pass
2 JSON Web Tokens (JWTs1): Agent Profile JWT (G1) and Machine Profile JWT (G2), to the HKEX Access
Management (AM) server for authentication.
If authentication is successful, the AM server will return a FINI API JWT access token to API users. FINI API users
have to pass this FINI API access token in the calling FINI APIs. The integrity and validity of FINI API JWT access
token will be verified at the FINI API Gateway.
FINI API Gateway and HKEX Access Management (AM) server are assessed via Internet and TLS V1.2 will be
used for encryption.
2.1 Create Agent Profile
Each company can create at most one Agent profile for FINI API access.
To create an Agent Profile on the HKEX Access Management Platform, FINI API users have to generate JSON
Web Key (JWK2) with an expiry date. To enhance security, each agent key must be renewed every year. Therefore,
the expiry date must not be more than one year from registration time.
The following parameters are suggested for JWK generation:
Parameter
Value
Key Type
RSA
Key Size
2048
Key Use
Signature
Algorithm
RS256
Key ID
SHA-256 hash3 value of JWK
Expiry Date
Key expiration time, in Epoch time format
An example of JWK public key is shown below:
{
"keys": [
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"kid":"eNL6Vj7vwaxjtwL+5QM=",
"alg": "RS256",
"n": "i4atD3PYe8YW7v8m
",
"exp": 1618307105
}
]
}
To facilitate key renewal, API users can register at most 2 public keys for each Agent profile so that API users can
renew and register a new public key before the existing key expires. Afterwards, API users can change their system
to rotate to the new JWK in generating the G1 JWT with their own plan before the existing key expires.
1 Refer to RFC 7519 at https://tools.ietf.org/html/rfc7519.
2 Refer to RFC 7517 at https://datatracker.ietf.org/doc/html/rfc7517.
3 Refer to RFC 7638 at https://datatracker.ietf.org/doc/html/rfc7638.
6
Please refer to the 5. API PROFILE MAINTENANCE (for FINI only) section of the HKEX Access Management
User Guide for detailed steps of agent profile maintenance.
2.2 Create Machine Profile
Each company can create at most 2 Machine profiles for FINI API access. As such, API users can set up 2
machines submitting API requests to FINI concurrently for their company.
To create a Machine Profile on the HKEX Access Management Portal, FINI API users have to generate JSON
Web Key (JWK) with an expiry date. To enhance security, each machine key must be renewed every year.
Therefore, the expiry date must not be more than one year from registration time.
The following parameters are suggested for JWK generation:
Parameter
Value
Key Type
RSA
Key Size
2048
Key Use
Signature
Algorithm
RS256
Key ID
SHA-256 hash value of JWK
Expiry Date
Key expiration time, in Epoch time format
An example of JWK public key is shown below:
{
"keys": [
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"kid":"eNL6Vj7vwaxjtwL+5QM=",
"alg": "RS256",
"n": "i4atD3PYe8YW7v8m
",
"exp": 1618307105
}
]
}
To facilitate key renewal, API users can register at most 2 public keys for each Machine profile so that API users
can renew and register a new public key before the existing key expires. Afterwards, API users can change their
system to rotate to the new JWK in generating the G2 JWT with their own plan before the existing key expires.
7
2.2.1 Grant API Function to Machine Profile
Each machine profile must be granted the appropriate identities and API roles for invoking the corresponding FINI
API(s). The following FINI API Roles can be granted to a machine profile:
FINI Identity
FINI API Role
Available API Category
FINICP
 EU_finiIPORefDataAPI
 IPO Reference Data
 EU_finiPOSubAPI
 EIPO Subscriptions
FINDB
 EU_finiIPORefDataAPI
 IPO Reference Data
 EU_finiPOFundAPI
 EIPO Funding
Other FINI identities
 EU_finiIPORefDataAPI
 IPO Reference Data
 Please refer to the User Management section of the HKEX Access Management User Guide for detailed steps of
agent profile maintenance.
2.3 Obtain FINI API JWT Access Token
Before invoking FINI API, API users must call an API to obtain a FINI API JWT Access Token from the HKEX
Access Management (AM) server by passing the G1 and G2 JWT tokens. If authentication is successful, AM server
will return a FINI API JWT access token to API users.
API users have to generate the G1 and G2 JWT tokens according to their formats described as follows:
2.3.1 Prepare Agent Profile JWT (G1)
2.3.1.1 Header
#
Parameter
Type
Description
1
alg
RS256
RS256 should be used for algorithm to encrypt JWT.
2
typ
JWT
Sample Agent Profile JWT Header:
{
"alg": "RS256",
"typ": "JWT"
}
2.3.1.2 Payload
#
Parameter
Sample
Description
1
aud
https://<CCAM>/openam/oauth
Value of the <CCAM > may be different for production and test
2/eu/access_token
environments.
2
iss
<issuer>
Agent JWT Issuer value as registered in Agent Profile on the HKEX Access
Management Portal.
3
exp
1610440800
Specifies the expiration time. This is the Unix epoch time.
Must be less than 30 minutes from current system time
4
sub
CP123456
The user’s Company ID on the HKEX Access Management Portal.
Sample of Agent Profile JWT Payload:
8
{
"aud": "https://<fr am>/openam/oauth2/eu/access_token",
"exp": 1610440800,
"sub": "CP123456"
}
2.3.1.3 Sign Agent Profile JWT (G1)
Agent Profile JWT will be signed by private Agent JWK key. This value will be expected in “assertion” field in
Authentication request parameter.
2.3.2 Prepare Machine Profile JWT (G2)
2.3.2.1 Header
#
Parameter
Type
Description
1
alg
RS256
RS256 should be used for algorithm to encrypt JWT.
2
typ
JWT
Sample Machine Profile JWT Header:
{
"alg": "RS256",
"typ": "JWT"
}
2.3.2.2 Payload
#
Parameter
Sample
Description
1
aud
https://<CCAM>/openam/oauth
Value of the <CCAM > may be different for production and test
2/eu/access_token
environments.
2
iss
0fd68f99-e64d-4544-b4d6-
Machine Profile UUID. Machine Profile UUID is system generated ID of
bcc1d7c12c1e
Machine profile on the HKEX Access Management Portal.
3
exp
1610440800
Specifies the expiration time. This is the Unix epoch time.
Must be less than 30 minutes from current system time
4
sub
0fd68f99-e64d-4544-b4d6-
Machine Profile UUID. Machine Profile UUID is system generated ID of
bcc1d7c12c1e
Machine profile.
Sample of Machine Profile JWT:
{
"aud": "https://<fr am>/openam/oauth2/access_token",
"iss": "0fd68f99-e64d-4544-b4d6-bcc1d7c12c1e",
"exp": 1610440800,
"sub": "0fd68f99-e64d-4544-b4d6-bcc1d7c12c1e"
}
9
2.3.2.3 Sign Agent Profile JWT (G2)
Machine Profile JWT will be signed by private Machine JWK key. Public JWK will be imputed by user in CC IDP
while create Machine profile. This value will be expected in “client_assertion” field in request parameter.
2.3.3 Call FINI API JWT Access Token API
API users must call an API to obtain a FINI API JWT Access Token from the HKEX Access Management (AM)
server by passing the G1 (Agent profile) and G2 (Machine profile) JWT tokens being prepared as described above.
AM server will decrypt and verify the G1 JWT and G2 JWT by the using the registered Agent public key and
Machine public key respectively.
AM server will return a valid FINI API JWT access token after the G1 JWT and G2 JWT are verified.
Host Name
URI
/openam/oauth2/eu/access_token
Method
POST
Request Header
Parameter
Type
Required
Sample Value
Description
Content-Type
String
Y
application/x-www-form-urlencoded
Request Parameter
Parameter
Type
Required
Sample Value
Description
grant_type
String
Y
urn:ietf:params:oauth:grant-type:jwt-
This specifies the Agent Profile assertion grant
bearer
type.
assertion
String
Y
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVC
This specifies the signed Agent Profile (G1)
J9.eyJhdWQiOiJodH..'
JWT.
client_assertion_type
String
Y
urn:ietf:params:oauth:client-assertion-
This specifies the Machine Profile client
type:jwt-bearer
assertion type.
client_assertion
String
Y
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVC
This specifies the signed Machine Profile (G2)
J9.eyJhdWQiOiJodHRwOi8vd3d3Lmdhb
JWT.
WEtdGVjaC5jb206OTA4MC9zc28vb2F1
dGgyL2FjY2Vzc190b2tlbiIsImlzcyI6InRlc
3Rv…
Response Body
Parameter
Type
Required
Sample Value
Description
access_token
String
Y
BNwWkbMD690HKLXhh0MOaQ0o3Hc
This is a JWT Access Token. This access
token will be passed while calling FINI API.
scope
String
Y
CP00001
Company Id will be return as scope value.
token_type
String
Y
Bearer
This specify the Access Token type.
expires_in
Number
Y
30
This specify expiration of JWT Access Token
in seconds.
HTTP Status Code
ForgeRock Reference link here
Error Messages
Error
Error Description
Action
invalid_grant
JWT assertion is expired or invalid
Agent JWT (G1) expired
invalid_client
JWT has expired
Machine Profile JWT(G2) expired
invalid_request
JWT expiration time is unreasonable
Agent/Machine Profile JWT time is over 30 minutes
invalid_grant
JWT assertion is not valid
Agent Profile JWT found invalid or not able to parse
server_error
Failed to parse json: Unexpected end-of-
Machine Profile JWT could not parse
input in field name\n at […]
10
invalid_client
Client authentication failed
client_assertion_type is not valid
unsupported_grant_type
Unknown Grant Type, urn&#x3a;ietf&#x3a;params&#x3a
grant_type value is not valid
;oauth&#x3a;grant-type&#x3a;jwt-bearer
Sample Success Response (HTTP Status Code 200)
{
"access_token":
"eyJ0eXAiOiJKV1QiLCJraWQiOiI0aUNLRkIwUlhJeHl0b3IxcjNUb0JkUmlldnM9IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJoa2V4YXBpIiwiY3RzIjoiT0FVVEgyX1NUQVRFT
EVTU19HUkFOVCIsImF1ZGl0VHJhY2tpbmdJZCI6IjhkZTQ0OTdlLTMxYWItNDY3Yi1hMzU1LTlkNzE0OWExOTdhYS0xMzE2ODgiLCJpc3MiOiJodHRwczovL2Nvbm
5lY3QtYW0udTFjcC5oa2V4LmNvbS5oazo0NDMvb3BlbmFtL29hdXRoMi9ldSIsInRva2VuTmFtZSI6ImFjY2Vzc190b2tlbiIsInRva2VuX3R5cGUiOiJCZWFyZXIiLCJhdX
RoR3JhbnRJZCI6IkY0a05tTGFGYUUtellxeVpuSEZaZWl6YkgtWSIsImF1ZCI6IjE1YjIzNjljLTkyMjItNDM1Mi05ZDIzLTdjODEyYWUwNzc2ZSIsIm5iZiI6MTY0OTgzMDI
3MywiZ3JhbnRfdHlwZSI6InVybjppZXRmOnBhcmFtczpvYXV0aDpncmFudC10eXBlOmp3dC1iZWFyZXIiLCJzY29wZSI6WyJDUDAwMzk4Il0sImF1dGhfdGltZSI6LTEs
InJlYWxtIjoiL2V1IiwiZXhwIjoxNjQ5ODMzODczLCJpYXQiOjE2NDk4MzAyNzMsImV4cGlyZXNfaW4iOjM2MDAsImp0aSI6InNzZDhmZHR6VW5sMWY3aVBhVzVSczF
NUFNzQSJ9.NHu1-0bPRMpw-e6YTZYiAcvhlrL6ZIj6NMjB84BYSdpEMX_Xxw9pPgu4IazzEsyO9G1kd4A0_EHWkiU6mW00A6LmrWhvgwRC3ve7Q_QORPa--
p0MoKMlC1FQ5D7uNDd6MnlOxR04rVDGYGAON3ElTNNbxZchkQj9WhSXZlNHsVJpJKSpWcZYyinYUsLkd-xBNaEiT8hbQCwX_NqqnI-
7GaQkNEl0XdmU5YQ0cBUe1DsLXwztrv7IiwKAPrfFMqWg0heAgkbgYuIuq_OVudwMqg9SDS_whzwKEZqSKw6DCndQZbo_jbAcCFS4vqlIcc5DjVfXcSqqZ-
D3yYs9AcFy8g",
"scope": "CP00001",
"token_type": "Bearer",
"expires_in": 30
}
Sample Error Response (HTTP Status Code 400)
Sample 1: When Agent JWT found expired (G1).
{
"error_description": "JWT assertion is expired or invalid",
"error": "invalid_grant"
}
Sample 2: When Machine Profile JWT found expired (G2).
{
"error_description": "JWT has expired",
"error": "invalid_client"
}
Sample 3: When Agent/Machine Profile JWT time found.
{
"error_description": "JWT expiration time is unreasonable.",
"error": "invalid_request"
}
Sample 4: When Agent Profile JWT found invalid/Not able to parse.
{
"error_description": "JWT assertion is not valid",
"error": "invalid_grant"
}
Sample 5: When Machine Profile JWT could not parse.
{
"error_description": "Failed to parse json: Unexpected end-of-input in field name\n at […]",
"error": "server_error"
}
Sample 6: When client_assertion_type is not valid
11
{
"error_description": "Client authentication failed",
"error": "invalid_client"
}
Sample 7: When grant_type value is not valid
{
"error_description": "Unknown Grant Type, urn&#x3a;ietf&#x3a;params&#x3a;oauth&#x3a;grant-type&#x3a;jwt-beare",
"error": "unsupported_grant_type"
}
12
2.3.4 FINI API JWT Access Token
If authentication is successful, AM server will return a FINI API JWT access token to API users. Each FINI API
JWT access token has a validity of 30 seconds. Therefore, API users can reuse the same JWT access token to
invoke FINI API’s continuously until the access token expires. After the JWT access token expires, API users have
to obtain a new access token from AM server again.
The structure of the FINI API JWT access token is as follows:
2.3.4.1 Header
#
Name
Type
Sample Value
Description
1
typ
String
JWT
This specify the type of JWT.
2
kid
String
wU3ifIIaLOUAReRB/FG6eM1P1QM=
The kid of server’s public key signing the Access Token.
3
alg
String
RS256
This specifies the algorithm used for signing the Access Token.
Sample Access Token Header Example
{
"typ": "JWT",
"kid": "wU3ifIIaLOUAReRB/FG6eM1P1QM=",
"alg": "RS256"
}
2.3.4.2 Payload
Attributes defined in the FINI API JWT Access Token Payload:
#
Name
Type
Sample Value
Description
1
sub
String
CP123456
This specify “sub” field of agent JWT.
2
cts
String
OAUTH2_STATELESS_GRANT
This specify the core token service.
3
auditTrackingId
String
123e724e-68e1-45dd-bc9c-
This specify the Audit tracking id.
7757b048bc6e-3351
4
iss
String
This specify Agent issuer.Default value of “iss” will be like below.
am.hkex.com.hk:443/openam/oauth2/
http://<CCAM >/openam/oauth2/eu
eu
5
tokenName
String
access_token
This specify the token name.
6
token_type
String
Bearer
This specify the return token type.
7
authGrantId
String
30nsq6cTJZwcJ-MGKYBwCSGSRcg
This specify the authentication grant id.
8
aud
String
<Machine-UUID>
This specify subject of Machine profile JWT.
9
nbf
Number
1618307105
The "nbf" (not before) claim identifies the time before which the
JWT MUST NOT be accepted for processing.
10
grant_type
String
urn:ietf:params:oauth:grant-type:jwt-
This specify the Agent profile grant type.
bearer
11
scope
String[]
["CP00001"]
This specify scope associated with respective Machine profile.
Company Id will be set as scope value.
12
auth_time
Number
-1
Time when the authentication has been performed.
13
realm
String
/
This specify the realm path.
13
15
exp
Number
1618310705
The "exp" (expiration time) claim identifies the expiration time on
or after which the JWT MUST NOT be accepted for processing.
16
iat
Number
1618307105
The "iat" (issued at) claim identifies the time at which the JWT
was issued.
17
expires_in
Number
30
This specify maximum time (Seconds) that the access token will
be valid for use within the application.
18
jti
String
QbmfS_qm04lTprLHUtS8mVxw1Po
This specify JWT id. Each Access Token has unique jti.
Sample Access Token (decoded) Example
{
"sub": "CP123456",
"cts": "OAUTH2_STATELESS_GRANT",
"auditTrackingId": "123e724e-68e1-45dd-bc9c-7757b048bc6e-3351",
"tokenName": "access_token",
"token_type": "Bearer",
"authGrantId": "30nsq6cTJZwcJ-MGKYBwCSGSRcg",
"aud": "0fd68f99-e64d-4544-b4d6-bcc1d7c12c1e",
"nbf": 1618307105,
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"scope": [
"CP00001"
],
"auth_time": -1,
"realm": "/",
"exp": 1618310705,
"iat": 1618307105,
"expires_in": 30,
"jti": "QbmfS_qm04lTprLHUtS8mVxw1Po"
}
14
2.4 Invoke FINI APIs
2.4.1 HTTP Request
To invoke FINI APIs, API user must send a valid and active FINI API JWT access token in the “Authorization”
request header as bearer token.
API users must not modify the contents of the access token when passing it to invoke a FINI API.
Sample of FINI API JWT access token:
Bearer BNwWkbMD690HKLXhh0MOaQ0o3Hc
The HTTP Request Headers are required to be set as follows:
Name
Description
Sample Value
Method
HTTP Method of the API request
GET or POST
Accept
Content type
application/json
Authorization
FINI API JWT access token
Bearer
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NT
Y3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsI
mp0aSI6IjM5ZDg5MDc0LTI0NWQtNGQxNC04MzQ2LTI2MzQz
YjdlNTc2YyIsImlhdCI6MTYxNDA0OTg1MSwiZXhwIjoxNjE0MD
UzNDUxfQ.roqk6lSljCMDlQBBf4fd5CvTL1odneLj6LKSgHqXm8c
The production domain name of FINI API endpoints will be provided in a future iteration.
2.4.2 HTTP Status Code
FINI API Gateway will return one of the following HTTP status code after an API request is invoked:
Status Code
Status
Description
200
OK
The request has succeeded
400
Bad Request
Invalid request
401
Unauthorized
The FINI API JWT access token is invalid
403
Forbidden
The client does not have access rights to the content
404
Not Found
The server cannot find the requested resource
429
Too Many Requests
Rate limiting
500
Internal Server Error
Internal Server Error
503
Service Unavailable
API Service is not available
504
Gateway Timeout
Timeout at the API Gateway
15
3 End-to-End Encryption
API endpoints with Personal Identifiable Information (PII) must adopt end-to-end encryption for both request and
responses on a data field level. The endpoints include:
Add EIPO Subscription Entries (see Section 7.1);
Change EIPO Subscription Entries (see Section 7.2);
Invalidate EIPO Subscription Entries (see Section 7.3); and
Enquire EIPO Subscription Entries (see Section 7.4).
Only the following PII data fields have to be encrypted in the API request and response, while other fields should not be
encrypted:
 ID Type of the applicant (idType)
 Issuing authority of the applicant’s identification document (idCountryJurisdiction)
 ID number of the applicant’s identification document.(idNum)
 Full English name of the applicant (fullNameEng)
 Full Chinese or non-English name of the applicant (fullNameChi)
3.1 Obtaining Crypto Metadata for Encryption
It is required to obtain Crypto Metadata, which includes FINI public key and Timestamp, for every API encryption request
by calling Crypto Metadata Request API. The system sequence diagram below illustrates the data flow for obtaining
crypto metadata for encrypting API data fields:
3.1.1 Request
GET
/api/crypto/meta
For invoking Crypto Metadata Request API, API user must obtain and send a valid and active FINI API JWT access
token as described in Section 2.3.
16
3.1.2 Response
#
Field
Type
Length
Description
Sample
1
code
String
6
0 to indicate ‘successful response’.
0
2
message
String
100
Empty string, i.e. "" to indicate successful
response.
3
data
Object
The crypto metadata including the public key
and timestamp
3.1
publicKey
String
1000
The X.509 RSA public key to be used in FINI,
MIIBIjANBgkqhkiG9w0BAQEF
encoded in base64 format
AAOCAQ8AMIIBCgKCAQEAu
h/iUUOPQEk/2HzBNcFMprLM
mp0Z/kUj69+eP2d03gkOFSh
Ofb/wI2Nmm3m7fwI/oFfab2qQ
gj4+I0F4zJzL9pd+QXSU+dme
EokXMVZpeqCr1zDn4I66usF
NC4NWQcP9XQpVxjmTzK6e1
LOpEk3wvRyW+mGqAJqPJv
matVmYXKvpmHdaOXN9vdK
15o6cYm5aEPg1+ih05+N+UI3
QeEYjv3O/b7wpvExBr52w0Z6
MELYeOEdWrvp7U3p8eJGaa
XTLkoqemIBWKfCefxqcn/tgW
4o/X6h0J38XhrQLULSGtPUB
Al3B4mfH504HI3cdX7pqnsgik
NnwWqfjew89z+gvFQIDAQAB
3.2
serverTimestamp
Integer
13
The FINI timestamp in Epoch milliseconds
1640070861735
format
{
"code": "0",
"message": "",
"data": {
"publicKey":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuh/iUUOPQEk/2HzBNcFMprLMmp0Z/kUj69+eP2d03gkOFShOfb/w
I2Nmm3m7fwI/oFfab2qQgj4+I0F4zJzL9pd+QXSU+dmeEokXMVZpeqCr1zDn4I66usFNC4NWQcP9XQpVxjmTzK6e1LOpEk3wvRyW+mGqAJqPJvmatVmYXKvpmH
daOXN9vdK15o6cYm5aEPg1+ih05+N+UI3QeEYjv3O/b7wpvExBr52w0Z6MELYeOEdWrvp7U3p8eJGaaXTLkoqemIBWKfCefxqcn/tgW4o/X6h0J38XhrQLULSGtPUB
Al3B4mfH504HI3cdX7pqnsgikNnwWqfjew89z+gvFQIDAQAB",
"serverTimestamp": 1640070861735
}
}
Note: The publicKey and time difference (in millisecond format) between FINI server time and API machine system
time should be cached in the API machine’s memory. The time difference is calculated by subtracting the FINI
timestamp by API machine system time (in millisecond format).
3.2 Encrypting API Requests
The flowchart below illustrates the high-level workflow for encrypting API data fields:
17
A pseudorandom number generator that generates outputs from a non-deterministic source is strongly recommended
for the Data Key and Initialization Vector (IV) and encryption of the data payload.
Recommended library for Java:
Language
Library
Notes
Java
java.security.SecureRandom
In Java 8 or later, use SecureRandom.getInstanceStrong().
Meets RFC 4086’s Random Requirements for Security.
3.2.1 Generate Data Key and Initialization Vector (IV)
A 32-byte Data Key ("DataKeyBase64Str") and 12-byte IV ("IVBase64Str") must be generated on the client side to
encrypt the PII data fields in each API request and decrypt the PII data fields in the API response.
Field
Bytes
Description
Sample
DataKeyBase64Str
32
A Data Key that is cryptographically secure
IhJpZKbn9MnhWDz9UTPdNt6qllACKSWj4t1rN198QAg=
encoded in Base64 format.
IVBase64Str
12
An IV that is cryptographically secure encoded in
aSdkeptMB9NXdYJx
Base64 format.
Java implementation sample source code
int ivSize = 12;
byte[] iv = new byte[ivSize];
GCMParameterSpec ivKey;
SecretKey sKey;
// create a SecureRandom object for randomness
SecureRandom random = SecureRandom.getInstanceStrong();
// create Initialization Vector
random.nextBytes(iv);
ivKey = new GCMParameterSpec(128, iv);
String ivBas64Str = Base64.getEncoder().encodeToString(ivKey.getIV());
// create a KeyGenerator object with AES algorithm
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
18
// generate Data Key
keyGen.init(256, random);
dataKey = keyGen.generateKey();
byte[] keyData = dataKey.getEncoded();
String dataKeyBase64Str = Base64.getEncoder().encodeToString(keyData);
3.2.2 Encrypting Data Fields
The data payload should be encrypted using the Data Key / IV, based on the following settings:
Configuration
Value
Algorithm
AES
Mode
GCM
Padding
NoPadding
The prefix "%enc_%" should then be appended to the final encrypted value to indicate the value is encrypted. Empty
string (“”) is still required to be encrypted with the same algorithm, On the other hand, "null" data value does not need
to be encrypted but will be included in generating the signed signature (X-FINI-SIGNATURE) header of the message.
Unencrypted sample request from the 7.1 Add EIPO Subscription Entries API endpoint (red text = to be encrypted):
{
"data": [{
"requestID": 1,
"ipoID": "1234",
"idList": [{
"idType": "1",
"idCountryJurisdiction": "HKG",
"idNum": "M011336(5)",
"fullNameEng": "Annabelle Wang",
"fullNameChi": "汪會夢"
}],
"appQuantity": "1000",
"firmID": "00000",
"ownRef": "f992b5c2-fd16-4e57-8387-738cb7aa75fb"
}
]
}
19
Encrypted sample request from the Section 7.1 Add EIPO Subscription Entries API endpoint (red text = encrypted
fields):
{
"data": [{
"requestID":"1",
"ipoID":"1234",
"idList":[{
"idType":"%enc_%eapFkonN3fzIDdSEkiD9EQg=",
"idCountryJurisdiction":"%enc_%ACzvoa5ZmoiXFScyhNbRKtxUgw==",
"idNum":"%enc_%BVeZ9hPEphW7EeSiE2UMP6bnM/QbklYusbM=",
"fullNameEng":"%enc_%CQnGpkKS/FHrGOMgkJROsmXZe+kEXEZ61hEcNn/P",
"fullNameChi":"%enc_%rtYCIbx0dZksk9K1QLpNT3zAjRi2YaZuWQ=="
}],
"appQuantity":"1000",
"firmID":"00000",
"ownRef":"f992b5c2-fd16-4e57-8387-738cb7aa75fb"
}
]
}
Java implementation sample source code
// Encrypt data field
byte[] clean = plainTextValue.getBytes();
SecretKeySpec secretKeySpec = new SecretKeySpec(dataKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivKey);
byte[] encryptedByteArray = cipher.doFinal(clean);
String encryptedValueBase64 = "%enc_%" + Base64.getEncoder().encodeToString(encryptedByteArray);
3.2.3 Providing Encryption HTTP Request Headers
The encryption data key and signature of the API request must be prepared and sent to FINI with the following HTTP
headers and their values (red text = header value):
#
Header Key
Description
Sample
1
Authorization
FINI API JWT Access token obtained from
Bearer
the HKEX Access Management server
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM
(Section 2.3)
0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnR
ydWUsImp0aSI6IjM5ZDg5MDc0LTI0NWQtNGQxNC04MzQ
2LTI2MzQzYjdlNTc2YyIsImlhdCI6MTYxNDA0OTg1MSwiZX
hwIjoxNjE0MDUzNDUxfQ.roqk6lSljCMDlQBBf4fd5CvTL1od
neLj6LKSgHqXm8c
2
X-FINI-ENCRYPTED-KEY
Encrypted key as the concatenation of the
Step-by-step construction per below:
Data Key and IV (Section 3.2.1) with "#" as
the delimiter, encrypted under the following
Data Key
IhJpZKbn9MnhWDz9UTPdNt6ql
configurations:
lACKSWj4t1rN198QAg=
IV
aSdkeptMB9NXdYJx
Configuration
Value
Concatenation of
IhJpZKbn9MnhWDz9UTPdNt6ql
Algorithm
RSA
Data Key and IV
lACKSWj4t1rN198QAg=#aSdke
Mode
None
(delimited by #)
ptMB9NXdYJx
Padding
PKCS1Padding
Header value (after
nQdkoc21+zKTy6Ri480Wk7UF
encryption)
hku3MH6/MyyzR5XnoQ9BD0M
BGySW2KCtZ0Nv25eA/jq6FFy
+jG45NR50R/zmRSPHGUcEU4
WDOmjdVEWnf0IV2+Vpnardk
d6ONGC94LxWm2wxyE2IKl3
WhnDY7EXvB9Oj3bWZAyHdd
9fE17d5kqnvGbXpA+R5qLS9d
2WDnRa3y+JcbvoZm5Y3qBVZ
Yv7h6G99dIipiFSrWs3KZlfzMe
eQp6VaP6Hg8jZeM5sfUlh6KC
20
348wgYfXjbfQ6iV3IwjKoeUJG
O2fy15zUwTLoqhlV5cCjFA1l6
Xvko0nnQcvl4vRiUfwVQuP2ll
kO/6PVnXg==
3
X-FINI-REQUEST-ID
Unique ID generated under the GUID v4
26219512b1da421eafc8560638ff69af
standard without any hyphens. FINI will
reject any duplicate Request ID in the same
day.
4
X-FINI-TIMESTAMP
Request timestamp calculated as the sum
Step-by-step construction per below:
between:
Time difference in millisecond format
Time difference
15
between the local / server timestamps in
Local timestamp
1641264153167
the Crypto Metadata Response (Section
X-FINI-TIMESTAMP
1641264153182
3.1.2)
value
Local timestamp in millisecond format
5
X-FINI-SIGNATURE
Signed signature in base64 format, as the
Step-by-step construction per below:
concatenation of the following values:
String body of the encrypted fields
Encrypted payload
{"data":[{"requestID":"1","ipoID":"
X-FINI-REQUEST-ID
1234","idList":[{"idType":"%enc_
X-FINI-TIMESTAMP
%eapFkonN3fzIDdSEkiD9EQg=
","idCountryJurisdiction":"%enc_
The signature should then be encrypted
%ACzvoa5ZmoiXFScyhNbRKtx
under the following configurations:
Ugw==","idNum":"%enc_%BVeZ
9hPEphW7EeSiE2UMP6bnM/Q
Configuration
Value
bklYusbM=","fullNameEng":"%e
Algorithm
HMACSHA256
nc_%CQnGpkKS/FHrGOMgkJR
Signature Key
Data Key from
OsmXZe+kEXEZ61hEcNn/P","fu
Section 3.2.1
llNameChi":"%enc_%rtYCIbx0d
Zksk9K1QLpNT3zAjRi2YaZuW
Q=="}],"appQuantity":"1000","fir
mID":"00000","ownRef":"f992b5c
2-fd16-4e57-8387-
738cb7aa75fb"}]}
X-FINI-REQUEST-ID
26219512b1da421eafc8560638f
f69af
X-FINI-TIMESTAMP
1641264153182
Header value (after
JcKBK3rJwmVlqjKE7+EisQps
hasing and
u4KNtHt3Mzrwtx+0Q4E=
encryption)
6
X-FINI-ENCRYPTION-
A field to indicate the request includes an
YES
CLIENT
encrypted payload.
If the request doesn’t include an encrypted
payload, the header is not required.
Java implementation sample source code for generating X-FINI-ENCRYPTED-KEY header
//Concatenation of Data Key and IV (delimited by #), X-FINI-ENCRYPTED-KEY
String e_key_str = dataKeyBase64Str + "#" + ivBase64Str;
// Generate X-FINI-ENCRYPTED-KEY header
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKeyFINI));
byte[] eBytes = cipher.doFinal(e_key_str.getBytes());
String X_FINI_ENCRYPTED_KEY = Base64.getEncoder().encodeToString(eBytes);
Java implementation sample source code for generating X-FINI-SIGNATURE header
// Generate X-FINI-SIGNATURE header
String algorithm = "HMACSHA256";
byte[] keyBytes = Base64.getDecoder().decode(dataKeyBase64Str);
Key key = new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(key);
String X_FINI_SIGNATURE = Base64.getEncoder().encodeToString(mac.doFinal((payload + requestID + timestamp) .getBytes()));
21
3.3 Decrypting API Responses
This section covers the step-by-step workflow for decrypting API responses containing encrypted data fields
3.3.1 Verify Signature
Before decrypting any fields, you should verify signature first. Compare Local Signature ("localSignature") and
Remote Signature ("remoteSignature"), if the 2 signatures do not match, it indicates a tampered response.
Field
Description
Sample
localSignature
Computed by signing the response body using
ij0GF6CE7RK2KDPL39UxvxBMSYdQth1M5RpCihQUIm
HMACSHA256, with the Data Key (Section
k=
3.1.2) as the signature key
remoteSignature
Obtain the value from response header X-FINI-
ij0GF6CE7RK2KDPL39UxvxBMSYdQth1M5RpCihQUIm
SIGNATURE
k=
3.3.2 Decrypt Response Body
An API response with the field "X-FINI-ENCRYPTION-SERVER" implies a response body with encrypted fields.
Sample response from the 7.4 Enquire EIPO Subscription Entries API endpoint (red text = encrypted fields):
{
"code": "0",
"message": "",
"data": [{
"stkCode": "9988",
"isin": "KYG017191142",
"status": "25",
"subFlowStatus": "3",
"recordID": "2462303930948573A ",
"idList": [{
"idType": "%enc_%eapFkonN3fzIDdSEkiD9EQg=",
"idCountryJurisdiction": "%enc_%ACzvoa5ZmoiXFScyhNbRKtxUgw==",
"idNum": "%enc_%CVaa9BTCphW3EeMJV/bYQyR4JnsJbluxoAI=",
"fullNameEng": "%enc_%Cw/JqQCj8VSuddUvgb64LzNdhVcNoMVtvs2a+w==",
"fullNameChi": "%enc_%of4bIoRQdqsJKkXZ1yd4okbiVffjc4oMhg=="
}],
"appQuantity": "1000",
"allotQuantity": "100",
"firmID": "00000",
"ownRef": null,
"unsuccessfulReason": "0",
"intDuplicateIndicator": "0",
"exception": []
}
],
"totalSize": 1,
"timestamp": "2021-08-26 12:30:29",
"nextCursor": "0",
"exception":[]
}
22
Each encrypted field should have its prefix "%enc_%" removed, then decrypted using the Data Key and IV (Section
3.1.2) with the following configurations:
Configuration
Value
Algorithm
AES
Mode
GCM
Padding
NoPadding
Worked example using the "fullNameEng" field (red text = encrypted value):
Encrypted field in API response
"fullNameEng":"%enc_%Cw/JqQCj8VSuddUvgb64LzNdhVcNoMVtvs2a+w=="
Encrypted value
Cw/JqQCj8VSuddUvgb64LzNdhVcNoMVtvs2a+w==
Decrypted Value
Chan Tai Man
Java implementation sample source code
// Decrypt data field
SecretKeySpec secretKeySpec = new SecretKeySpec(dataKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivKey);
String encryptedTextValue = Base64.getDecoder().decode(encryptedTextValueBase64);
byte[] decryptedByteArray = cipher.doFinal(encryptedTextValue);
String decryptedValue = new String(decryptedByteArray);
3.4 End-to-End Encryption Error Codes and Messages
If the encryption API request is not submitted correctly with the required headers or data, errors will occur during end-
to-end encryption or decryption processing in FINI. The following is a list of error codes and messages which may be
returned in FINI API response due to incorrect encryption API request:
Code
Message
411001
Missing X-FINI-REQUEST-ID in the header
411002
Duplicate Request ID
411003
Missing X-FINI-TIMESTAMP in the header
411004
Request timestamp expired
411005
Missing X-FINI-SIGNATURE in the header
411006
Missing X-FINI-ENCRYPTED-KEY in the header
411007
Public key is wrong, FINI can't decrypt the encrypted key, please re-fetch crypto meta
411008
Signature error
411009
No such field {json_key}
411010
Cipher text format is wrong
411011
FINI can't decrypt the cipher text of the field {json_key}
411999
Crypto process exception
23
4 Formats and Conventions
4.1 Identifiers
4.1.1 IPOs
IPOs are identified using an ipoID ("ipoID"), which is different from an IPO’s Stock Code ("stkCode") or ISIN ("isin").
The design is intended to avoid situations where Stock Codes and ISINs are being reused, e.g. an IPO relaunching
under different IPO cases within a short period of time. The use of ipoIDs is unique to the FINI API Gateway, and
the identifiers can be queried through the Enquire IPO List API endpoint.
/api/ipos/refdata/v1?ipoID=1234
4.1.2 EIPO Subscriptions
EIPO subscriptions are identified using a Record ID ("recordID"), which is a globally unique reference number
generated by the system upon successful validation and submission. It contains: (i) a 16-digit integer; and (ii) a
suffix indicating the method through which the subscription is created.4
/api/eipo/subscriptions/query/v1?recordID=2486466216549731A
4.1.3 EIPO Funding
Each HKSCC Participant’s EIPO subscription list within an IPO is identified using a Transaction Reference
("transactionRef"). Each reference is a globally unique reference number generated by the system upon an HKSCC
Participant making a first subscription within an IPO. It contains a 13-digit integer.
/api/eipo/funding/query/v1?transactionRef=5224703318532
4 "O" = Online input, "B" = Bulk upload, and "A" = API.
24
4.2 Data Formats
All request and response fields are determined by a data type and max length:
Type
Length
Description
Example
String
[n]
Field with alphanumeric characters of n
Request field "fullName" has the following parameters:
characters, fully UTF-8 encoded. (1)
Format
Length
String
20
Successful examples:
 "fullName":"David Chan Tai Man"
 "fullName":"陳大文"
Unsuccessful examples:
 "fullName":"David Chan Tai Man FOO" (exceeds length)
 "fullName":"David Chan Tai Man " (invalid character)
Integer
[n]
Field with numeric characters of up to n
Request field "pageSize" has the following parameters:
digits.
Format
Length
The FINI API Gateway supports all
Integer
18
unsigned 64-bit integers, with a range
between 0 and 18446744073709551615.
Successful examples:
 "pageSize":9
Certain numeric fields are classified as
string, as their sizes may
 "pageSize":18446744073709551614
Unsuccessful examples:
 "pageSize":18446744073709551616 (overflow)
 "pageSize":-1 (underflow)
Decimal
[n1],[n2]
Field with an integer component (n1 - n2)
Request field "priceMax" has the following parameters:
and a decimal component (n2),
separated by a comma.
Format
Length
Decimal
12,3
The decimal component (n2) is the max
number of digits after the separator.
Numerical range:
 Min: 0.000
The integer component (n1) - the decimal
component (n2) is the max number of
 Max: 999999999.999
digits before the separator/
Array
[n]
Field holding n variables, separated by
Request field "idList" has the following parameters:
commas (",") and enclosed by square
brackets ("[" and "]")
#
Field
Format
Length
1
idList
Array
2
1.1
idType
String
2
1.2
idNum
String
10
25
Successful example:
"idList":[
{"idType":"2",
"idNum":"GJ377364"},
{"idType":"2",
"idNum":"RQ347486"}
]
Unsuccessful example:
"idList":[
{"idType":"2",
"idNum":"GJ377364"},
{"idType":"2",
"idNum":"RQ347486"},
{"idType":"2",
"idNum":"XX323346"}
]
(1) Unless specified, the all UTF-8 characters should be accepted, with the exception of the following characters / character sets:
Unicode
Description
1F000-1F02F
Mahjong Tiles
1F030-1F09F
Domino Tiles
1F0A0-1F0FF
Playing Cards
1F100-1F1FF
Enclosed Alphanumeric Supplement
1F200-1F2FF
Enclosed Ideographic Supplement
1F300-1F5FF
Miscellaneous Symbols and Pictographs
1F600-1F64F
Emoticons (Emoji)
1F650-1F67F
Ornamental Dingbats
1F680-1F6FF
Transport and Map Symbols
1F700-1F77F
Alchemical Symbols
1F780-1F7FF
Geometric Shapes Extended
1F800-1F8FF
Supplemental Arrows-C
1F900-1F9FF
Supplemental Symbols and Pictographs
1FA00-1FA6F
Chess Symbols
1FA70-1FAFF
Symbols and Pictographs Extended-A
1FB00-1FBFF
Symbols for Legacy Computing
E0000-E007F
Tags
E0100-E01EF
Variation Selectors Supplement
F0000-FFFFF
Supplementary Private Use Area-A
100000-10FF
FFSupplementary Private Use Area-B
005B
Left Square Bracket "["
005D
Right Square Bracket "]"
005E
Circumflex Accent "^"
26
4.3 Request Field Conventions
4.3.1 Leading/Trailing Spaces
All request fields with leading or trailing spaces are trimmed before validation and processing
Example 1: Trailing spaces exceeding field length
Request field "fullName" has the following parameters:
Type
Length
String
20
The following request would be successfully processed:
Request
"fullName":"Mary Lee Sum See "
<- field length of 21 string characters
Response
"fullName":"Mary Lee Sum See"
<- field trimmed to 16 string characters
Example 2: Matched field after trimming trailing spaces
A GET API endpoint uses "stkCode" as a primary key to enquire other fields ("priceMin", "priceMax" and
"priceFinal"), and has the following parameters:
Type
Length
String
10
The following request would be successfully processed:
Database
"stkCode":"9988"
"priceMin":1.1
"priceMax":1.5
"priceFinal":null
Request
"stkCode":"9988 "
<- matches "stkCode":"9988" after trimming
Response
"data":[
<- successful response
"stkCode":"9988",
"priceMin":1.1
"priceMax":1.5
"priceFinal":null
]
27
Example 3: Leading spaces exceeding field length
Request field "idType" uses an ID Code (digits 1-8) and has the following parameters:
Type
Length
String
2
The following request would be successfully processed:
Request
"idType":"
1"
<- field with 2 leading spaces and 1 digit
Response
"idType":"1"
<- field trimmed to 1 digit
Example 4: Matched field after trimming leading and trailing spaces
Request field "idType" uses an ID Code (digits 1-8) and has the following parameters:
Type
Length
String
2
The following request would be successfully processed:
Request
"idType":" 1 "
<- field with 2 leading/trailing spaces and 1 digit
Response
"idType":"1"
<- field trimmed to 1 digit
4.3.2 Irrelevant Fields
Irrelevant fields are ignored by the FINI API Gateway without any processing
Example:
A GET API endpoint has the following URI (assume both are mandatory fields):
GET /api/ipos/v1?size={integer}&nextCursor={string}
The following request would be successfully processed:
Request
GET /api/ipos/v1?size=10&nextCursor=abc&food=Delicious
<- redundant field food=Delicious
Outcome
 Both size and nextCursor fields are processed, ignoring food
28
4.3.3 Repeated Fields
Repeated fields will only have its first instance validated and processed by the FINI API Gateway
Example 1: All repeated fields are valid
A GET API endpoint has the following URI (assume both are mandatory fields):
GET /api/ipos/v1?size={integer}&nextCursor={string}
The following request would be successfully processed:
Request
GET /api/ipos/v1?size=10&nextCursor=abc&size=100
<- repeated size field
Outcome
 Processed as size=10, size=100 is ignored
Example 2: First instance is invalid, repeated instance(s) are valid
A GET API endpoint has the following URI (assume both are mandatory fields):
GET /api/ipos/v1?size={integer}&nextCursor={string}
The following request would be successfully processed:
Request
GET /api/ipos/v1?size=abc&nextCursor=abc&size=100
<- first repeated size field
Outcome
X Processed as size=abc, size=100 is ignored. API request is rejected for being invalid.
Example 3: First instance valid, repeated fields are invalid
A GET API endpoint has the following URI (assume both are mandatory fields):
GET /api/ipos/v1?size={integer}&nextCursor={string}
The following request would be successfully processed:
Request
GET /api/ipos/v1?size=10&nextCursor=abc&size=infinite
<- repeated size field
Outcome
 Processed as size=10, size=infinite is ignored
29
4.3.4 Optional Fields
Optional fields that are not provided will be treated as null
Example:
A POST API endpoint has the following request fields:
Field
Required?
Type
Length
fullName
Mandatory
String
20
idNum
Mandatory
String
10
ownRef
Optional
String
20
The following request would be successfully processed:
Request
"data":[{
<- ownRef not provided
"fullName":"Company ABC"
"idNum":"KM21512456"
}]
Response
"code":"0"
<- "code":"0" to indicate successful processing
"message":""
[…]
Database
"fullName":"Company ABC"
<- ownRef will be stored as null
"idNum":"KM21512456"
"ownRef":null
30
4.4 Response Field Conventions
4.4.1 Empty Fields, Arrays and Objects
Empty response fields will be treated as follows:
o
Strings, integers and decimals - null
o
Array of an object - empty array []
o
Object - empty object {}
Example:
A GET API endpoint has the following response fields:
Field
Type
Length
idList
Array
4
idNum
String
10
If both fields are blank, the following response would be provided:
Response
"data":[{
<- "idList" returns an empty array, and "idNum"
"idList":[]
returns null
"idNum":null
}]
4.4.2 Successful Responses
 All successful responses are indicated with a "0" in code ("code":"0") and empty string in message ("message":"")
Successful example:
Response
{
"code":"0",
"message":"",
"data":[{
"stkCode":"9988",
"status":"40",
"companyEngFull":"Alibaba Group Holding Limited"
}],
"totalSize": 1,
"timestamp": "2022-05-06 07:01:40",
"nextCursor":"0",
"exception":[]
}
Unsuccessful example:
Response
{
"code":"400000",
"message":"Invalid Parameters",
"data":[],
"totalSize": 0,
31
"timestamp":"2021-04-29 15:00:00",
"nextCursor": "0",
"exception":[{
"recordErrorCode":"401900",
"recordErrorMsg":"Invalid size format (must be an
unsigned 64-bit integer)"}]
}
32
4.4.3 Unsuccessful Responses
All unsuccessful responses are indicated by:
o
The "code" field with a value that is not "0" (example, "code":"400000")
o
The "message" field with a value that is non-blank (example, "message":"Invalid Parameters")
Error messages presented by the FINI API Gateway are divided into two categories:
o
Message-level error - placed outside the data payload to indicate the request has been wholly rejected
o
Entry-level error - used if the endpoint involves bulk processing, placed inside the data payload to indicate
the request has been partially or wholly rejected
Example 1: Message-level error with a request wholly rejected
Response
{
"code":"400000",
<- Indicates there is an error in the request
"message":"Invalid Parameter(s)",
<- Shows the specific error identified
"data":[],
<- Indicates there is a message-level error
"totalSize":1,
"timestamp": "2022-03-24 04:22:18",
"exception":[{
<- Shows the message-level error identified
"recordErrorCode":"405904",
"recordErrorMsg":"Invalid array size for data (must be 1 to 1000)"
}]
}
Example 2: Entry-level error with a request partially rejected
Response
{
"code":"400000",
<- Indicates there is an error in the request
"message":"Invalid Parameter(s)",
<- Shows the specific error identified
"data":[{
"requestID":"565485",
"recordID":null,
"exception":[{
<- Shows the error identified in the first entry
"recordErrorCode":"405904",
"recordErrorMsg":"Invalid array size for idList (must be 1 to 4)"
}]
},
{
"requestID":"565486",
"recordID":"6498821129182047A",
"exception":[]
<- Indicates the second entry has been accepted
}
],
"totalSize":2,
"timestamp": "2022-03-24 04:23:41",
"exception":[]
<- Indicates there is no message-level error
}
33
Example 3: Entry-level error with a request wholly rejected
Response
{
"code":"400000",
<- Indicates there is an error in the request
"message":"Invalid Parameter(s)",
<- Shows the specific error identified
"data":[{
"requestID":"565487",
"recordID":null,
"exception":[{
<- Shows the error identified in the first entry
"recordErrorCode":"405904",
"recordErrorMsg":"Invalid array size for idList (must be 1 to 4)"
}]
},
{
"requestID":"565488",
"recordID":null,
"exception":[{
<- Shows the error identified in the second entry
"recordErrorCode":"405904",
"recordErrorMsg":"Invalid array size for idList (must be 1 to 4)"
}]
}
],
"totalSize":2,
"timestamp": "2022-03-24 04:26:13",
"exception":[]
<- Indicates there is no message-level error
}
34
5 API Endpoints
5.1 Overview
The FINI API Gateway operates based on 3 main categories:
Category
Required function in ForgeRock
Description
/api/ipos/*
EU_finiIPORefDataAPI
API endpoints for all FINI users that return data on the specific IPO-related
reference data, such as the stock code, offer size and price information
/api/eipo/subscriptions/*
EU_finiPOSubAPI
API endpoints for HKSCC Participants users to operate public offer
subscriptions in the EIPO Channel, which includes add, change, invalidate
and enquire subscriptions
/api/eipo/funding/*
EU_finiPOFundAPI
API endpoints for EIPO Designated Bank users to operate EIPO funding-
related functions, such as confirm and enquire funding statuses.
The 3 main categories cover to 8 API endpoints within the FINI API Gateway:
API endpoint
Function
Method
Description
/api/ipos/list/v1
Enquire IPO List
GET
Returns a list of IPO(s) available on FINI.
/api/ipos/refdata/v1
Enquire IPO Reference Data
GET
Returns the latest full set of reference data of
a requested IPO.
/api/eipo/subscriptions/add/v1
Add EIPO Subscription Entries
POST
Allows users to add EIPO entries to IPOs that
are open for subscription.
/api/eipo/subscriptions/change/v1
Change EIPO Subscription Entries
POST
Allows users to amend existing EIPO entries
recorded on FINI.
/api/eipo/subscriptions/invalidate/v1
Invalidate EIPO Subscription Entries
Allows users to cancel existing EIPO entries
POST
recorded on FINI. No deletion is performed.
/api/eipo/subscriptions/query/v1
Enquire EIPO Subscription Entries
POST
Returns a list of EIPO subscription(s) based
on an IPO or by specific Record IDs.
/api/eipo/funding/confirm/v1
Confirm EIPO Funding
Allows users to confirm or reject the pre-
POST
funding related to an HKSCC Participant’s
EIPO subscription list.
/api/eipo/funding/query/v1
Enquire EIPO Funding
Returns a list of HKSCC Participants’ pre-
POST
funding requirements based on an IPO or by
specific Transaction References.
5.2 Throttles
The FINI API Gateway imposes request throttling with a threshold that refreshes every 60 seconds. Each company
registered on the HKEX Access Management Portal is subject to a threshold of 480 requests per 60 seconds.
A global throttle is also applied for each API endpoint, based on the expected peak traffic. It is strongly
recommended that API machines do not exceed 60 requests per 60 seconds to avoid triggering the API
Gateway’s throttles.
35
6 IPO Reference Data
6.1 Enquire IPO List
6.1.1 Request
GET
/api/ipos/list/v1
#
Field
Type
Length
Required
Description
1
size
Integer
18
No
Expected page size of the API response. Must be between 1 and 1,000. If
null or blank, default as 100.
2
nextCursor
String
20
Yes
Key reference (ipoID) from which the response message should start. "0"
should be used to start from the first index.
GET /api/ipos/listv1?size=5&nextCursor=0
6.1.2
Response
#
Field
Type
Length
Description
1
code
String
6
0 to indicate ‘successful response’.
2
message
String
100
Empty string, i.e. "" to indicate successful response.
3
data
Array
3.1
ipoID
String
20
A unique, sequentially-generated value assigned to each IPO case stored on
FINI. Used as the identifier for IPOs within the FINI API Gateway.
3.2
stkCode
String
10
The IPO’s stock code.
3.3
isin
String
12
The IPO’s ISIN.
3.4
status
String
2
The status of the IPO, expressed in status codes:
Status
Description
25
Deal Initiated
30
Public Offer Closed
35
Application Validated
45
Allotment Confirmed
50
Money Settlement
55
Allocation Confirmed
60
Placing Approved
65
Allotment Results Approved
70
Trading Started
80
Suspended
90
Cancelled
4
totalSize
Integer
18
Total size of the API response.
5
timestamp
String
19
Timestamp of the API response, in YYYY-MM-DD HH:MM:SS format.
6
nextCursor
String
20
The key reference (ipoID) immediately after the final result of response. If there
are no further records, "0" will be returned.
7
exception
Array
To indicate whether the entire request failed any validation checks:
 Empty array = no error(s) were identified across the entire request
 Non-empty array = the entire request was rejected due to a single or
multiple error(s), with each error expressed as an individual object
7.1
recordErrorCode
String
6
7.2
recordErrorMsg
String
100
36
{
"code": "0",
"message": "",
"data": [{
"ipoID": "1234",
"stkCode": "9988",
"isin": "KYG017191142",
"status": "25"
},
{
"ipoID": "1235",
"stkCode": "9633",
"isin": "CNE100004272",
"status": "30"
},
{
"ipoID": "1236",
"stkCode": "9618",
"isin": "KYG8208B1014",
"status": "45"
},
{
"ipoID": "1237",
"stkCode": "6618",
"isin": "KYG5074A1004",
"status": "60"
},
{
"ipoID": "1238",
"stkCode": "1024",
"isin": "KYG532631028",
"status": "70"
}
],
"totalSize": 5,
"timeStamp": "2021-08-25 16:22:13",
"nextCursor": "11",
"exception": []
}
37
6.2 Enquire IPO Reference Data
6.2.1 Request
GET
/api/ipos/refdata/v1
#
Field
Type
Length
Required
Description
1
ipoID
String
20
Yes
Must be a valid ipoID from the Enquire IPO List API endpoint.
GET /api/ipos/refdata/v1?ipoID=1234
6.2.2
Response
#
Field
Type
Length
Description
1
code
String
6
0 to indicate ‘successful response’.
2
message
String
100
Empty string, i.e. "" to indicate successful response.
3
data
Array
3.1
ipoID
String
20
The unique identifier assigned to the IPO case.
3.2
stkCode
String
10
The IPO’s stock code.
3.3
Status
String
2
The status of the IPO, expressed in status codes:
Status
Description
25
Deal Initiated
30
Public Offer Closed
35
Application Validated
45
Allotment Confirmed
50
Money Settlement
55
Allocation Confirmed
60
Placing Approved
65
Allotment Results Approved
70
Trading Started
80
Suspended
90
Cancelled
3.4
companyEngFull
String
80
The IPO’s company full English name.
3.5
companyEngShort
String
15
The IPO’s company short English name.
3.6
companyChiFull
String
80
The IPO’s company full Chinese name.
3.7
companyChiShort
String
8
The IPO’s company short Chinese name.
3.8
placeOfCorp
String
2
The IPO company’s place of incorporation, expressed by location codes:
Code
Description
1
Bermuda
2
Cayman Islands
3
Hong Kong, China
4
People’s Republic of China
5
Australia
6
British Virgin Islands
7
Canada - Alberta
8
Canada - British Columbia
9
Canada - Ontario
10
England
11
Israel
12
Italy
13
Japan
14
Jersey
15
Luxembourg
16
Singapore
38
17
US - Delaware
99
Others
3.9
isin
String
12
The IPO’s ISIN.
3.10
nomValue
Decimal
15,12
The nominal or par value of the IPO company’s securities.
3.11
nomCur
Integer
3
The currency denomination of the IPO company’s nominal or par value,
expressed as codes.
Code
Description
1
HKD
2
CNY
3
USD
4
EUR
5
AED
6
AFN
7
ALL
8
AMD
9
ANG
10
AOA
11
ARS
12
AUD
13
AWG
14
AZN
15
BAM
16
BBD
17
BDT
18
BGN
19
BHD
20
BIF
21
BMD
22
BND
23
BOB
24
BOV
25
BRL
26
BSD
27
BTN
28
BWP
29
BYN
30
BZD
31
CAD
32
CDF
33
CHE
34
CHF
35
CHW
36
CLF
37
CLP
38
COP
39
39
COU
40
CRC
41
CUC
42
CUP
43
CVE
44
CZK
45
DJF
46
DKK
47
DOP
48
DZD
49
EGP
50
ERN
51
ETB
52
FJD
53
FKP
54
GBP
55
GEL
56
GHS
57
GIP
58
GMD
59
GNF
60
GTQ
61
GYD
62
HNL
63
HRK
64
HTG
65
HUF
66
IDR
67
ILS
68
INR
69
IQD
70
IRR
71
ISK
72
JMD
73
JOD
74
JPY
75
KES
76
KGS
77
KHR
78
KMF
79
KPW
80
KRW
81
KWD
82
KYD
83
KZT
40
84
LAK
85
LBP
86
LKR
87
LRD
88
LSL
89
LYD
90
MAD
91
MDL
92
MGA
93
MKD
94
MMK
95
MNT
96
MOP
97
MRU
98
MUR
99
MVR
100
MWK
101
MXN
102
MXV
103
MYR
104
MZN
105
NAD
106
NGN
107
NIO
108
NOK
109
NPR
110
NZD
111
OMR
112
PAB
113
PEN
114
PGK
115
PHP
116
PKR
117
PLN
118
PYG
119
QAR
120
RON
121
RSD
122
RUB
123
RWF
124
SAR
125
SBD
126
SCR
127
SDG
128
SEK
41
129
SGD
130
SHP
131
SLL
132
SOS
133
SRD
134
SSP
135
STN
136
SYP
137
SZL
138
THB
139
TJS
140
TMT
141
TND
142
TOP
143
TRY
144
TTD
145
TWD
146
TZS
147
UAH
148
UGX
149
USN
150
UYI
151
UYU
152
UZS
153
VES
154
VND
155
VUV
156
WST
157
XAF
158
XAG
159
XAU
160
XBA
161
XBB
162
XBC
163
XBD
164
XCD
165
XDR
166
XFU
167
XOF
168
XPD
169
XPF
170
XPT
171
XSU
172
XTS
173
XUA
42
174
XXX
175
YER
176
ZAR
177
ZMW
999
Others
3.12
hkAddress
Array
4
The IPO company’s principal address in Hong Kong, expressed in a nested
format, e.g.:
“hkAddress”:[
{“id”:”1”,”line”:”26/F Tower One, Times Square” },
{“id”:”2”,”line”:”1 Matheson Street” },
{“id”:”3”,”line”:”Causeway Bay” },
{“id”:”4”,”line”:”Hong Kong” }]
3.13
warrants
Array
10
The list series of warrants to belisted by the IPO company, expressed in a
nested format.
3.13.1
warrantNameEngShort
String
15
The warrant’s full English name.
3.13.2
warrantNameEngFull
String
100
The warrant’s short English name.
3.13.3
warrantCode
String
10
The warrant’s security code.
3.13.4
isin
String
12
The warrant’s ISIN.
3.13.5
boardLot
Integer
6
The minimum trading unit of the warrant.
3.13.6
subscriptionPrice
Decimal
12,3
The subscription price of the warrant.
3.13.7
faceValue
Integer
2
To indicate the denomination method of the warrant’s face value, expressed in
codes:
Code
Description
1
Dollar Amount
2
Unit Number
3.13.8
totalWarrants
Integer
20
The number of warrants to be issued.
3.14
offerType
Integer
2
The listing method of the IPO, expressed as codes:
Code
Description
1
Global offer (placing and public offer)
2
By placing only
3
By public offer only
4
By introduction
5
Transfer from GEM
3.15
listSecurities
Integer
2
The security type of the IPO, expressed as codes:
Code
Description
1
Ordinary shares
2
Ordinary shares (H shares)
3
Ordinary shares (conversion from B to H shares)
4
Preference shares
5
Real Estate Investment Trust
6
Exchange Traded Product
7
Depositary Receipts
8
Share Stapled Units
99
Other
3.16
listPlatform
Integer
2
The listing board of the IPO, expressed as codes:
Code
Description
1
Main board
2
GEM
3.17
primaryExchange
Array of
17*2
An array listing the primary exchange(s) of the IPO company, expressed as
String
exchange codes:
Code
Description
43
0
The Stock Exchange of Hong Kong (SEHK)
1
The Amsterdam Stock Exchange (NYSE Euronext -
Amsterdam)
2
The Australian Securities Exchange (ASX)
3
The Brazilian Securities, Commodities and Futures
Exchange (BM&FBOVESPA)
4
The Frankfurt Stock Exchange (Deutsche Böurse)
5
The Italian Stock Exchange (Borsa Italiana)
6
The London Stock Exchange (LSE)
7
The Madrid Stock Exchange (Bolsa de Madrid)
8
NASDAQ OMX (US)
9
The New York Stock Exchange (NYSE Euronext (US))
10
The Paris Stock Exchange (NYSE Euronext - Paris)
11
The Singapore Exchange (SGX)
12
The Stockholm Stock Exchange (NASDAQ OMX -
Stockholm)
13
The Swiss Exchange (SIX Swiss Exchange)
14
The Tokyo Stock Exchange (TSE)
15
The Toronto Stock Exchange (TMX)
99
Other
3.18
dualPrimaryExchange
String
80
If the IPO company is operating a dual-primary listing, a list of the primary
exchanges expressed as a string separated by commas.
3.19
biotechIndicator
String
1
If the IPO company is listing as a biotech company, then "1". Else, the
response will return "0".
3.20
regsIndicator
String
1
If the IPO company is operating a "Reg-S listing", then "1". Else, the response
will return "0".
3.21
specialistTechIndicator
String
1
If the IPO company is listing as a "Specialist Technology Company", then "1".
Else, the response will return "0".
3.22
wvrRatio
String
5
If the IPO company has weighted voting rights securities, then the voting ratio
expressed in "[n],[n]", where each [n] is an integer with up to 2 digits.
If the IPO company does not have any weighted voting rights securities, the
response will return null.
3.23
tradeCurrency
String
3
The IPO’s trading currency, expressed as currency codes:
Currency
Description
HKD
Hong Kong Dollar
CNY
Chinese Yuan
USD
United States Dollar
3.24
boardLot
Integer
6
The minimum trading unit of the IPO company.
3.25
downwardPriceFlex
Decimal
3,0
The percentage at which the IPO company may price its IPO below the
minimum offer price. Example: "10" = 10%.
3.26
priceMin
Decimal
12,3
The minimum offer price of the IPO.
3.27
priceMax
Decimal
12,3
The maximum offer price of the IPO.
3.28
priceFinal
Decimal
12,3
The final offer price of the IPO.
3.29
clawback
Array
100
The thresholds for triggering a clawback and their corresponding retail
allocations expressed in percentages. Here, ratio = each threshold and
allocation = percentage allocation to the public offer (Example: "10" = 10%).
Expressed in a nested format, e.g.:
"clawback":[
{"id":"1","ratio":"1","allocation":"10"},
{"id":"2","ratio":"15","allocation":"30"},
{"id":"3","ratio":"50","allocation":"40"},
{"id":"4","ratio":"100","allocation":"100"}]
3.30
preIpoShares
String
20
The number of securities issued by the IPO company before the
commencement of the IPO.
3.31
ipoShares
String
20
The expected number of securities to be issued by the IPO company following
the completion of the IPO.
3.32
poSharesInitial
String
20
The number of securities initially allocated to the public offer.
3.33
poApplicationQuantity
String
20
Number of securities validly subscribed by the public offer.
3.34
poOversubscriptionRatio
Decimal
9,2
poApplicationQuantity divided by poSharesInitial.
44
3.35
poSharesFinal
String
20
The final number of securities allocated to the public offer.
3.36
ioSharesInitial
String
20
The number of securities initially allocated to the institutional offer.
3.37
ioApplicationQuantity
String
20
Number of securities validly subscribed by the institutional offer.
3.38
ioOversubscriptionRatio
Decimal
9,2
ioApplicationQuantity divided by ioSharesInitial.
3.39
ioOfferSharesFinal
String
20
The final number of securities allocated to the institutional offer.
3.40
poReallocationCap
Decimal
5,2
The percentage cap at which the IPO company may allocate its securities to
the public offer at its own discretion.
3.41
upsizeOption
Decimal
5,2
The IPO’s offer size adjustment option, expressed in percentage terms
(Example: "10" = 10%).
3.42
upsizePoShares
String
20
The additional number of securities issued to the public offer using the IPO’s
offer size adjustment option.
3.43
upsizeIoShares
String
20
The additional number of securities issued to the institutional offer using the
IPO’s offer size adjustment option.
3.44
overallotOption
Decimal
5,2
The IPO’s over-allotment option, expressed in percentage terms (Example:
"10" = 10%).
3.45
overallotPoShares
String
20
The additional number of securities issued to the public offer using the IPO’s
over-allotment option.
3.46
overallotIoShares
String
20
The additional number of securities issued to the institutional offer using the
IPO’s over-allotment option.
3.47
overallPoShares
String
20
The final size of the public offer, calculated as poSharesFinal +
upsizePoShares + overallotPoShares.
3.48
overallIoShares
String
20
The final size of the institutional offer, calculated as ioSharesFinal +
upsizeIoShares + overallotIoShares.
3.49
overallIpoShares
String
20
The final size of the IPO, calculated as overallPoShares + overallIoShares.
3.50
totalIssuedCapitalListing
String
20
The IPO company’s total issued number of securities upon listing.
3.51
totalIssuedHsharesListing
String
20
The IPO company’s total issued number of H-shares upon listing.
3.52
totalIssuedNonwvrsharesList
String
20
The IPO company’s total issued number of non-weighted voting rights
ing
securities upon listing.
3.53
denomTable
Array
200
An array of denominations at which a public offer subscriber may subscribe for
the IPO. Here, shares = number of securities for subscription and value = the
maximum value payable upon application.
Expressed in a nested format, e.g.:
"denomTable":[
{"id":"1","shares":"100","value":"101.01"},
{"id":"2","shares":"200","value":"202.02"},
{"id":"3","shares":"300","value":"303.03"},
{"id":"4","shares":"400","value":"404.03"},
{"id":"5","shares":"500","value":"505.04"},
{"id":"6","shares":"600","value":"606.05"},
{"id":"7","shares":"700","value":"707.06"},
{"id":"8","shares":"800","value":"808.06"},
{"id":"9","shares":"900","value":"909.07"},
{"id":"10","shares":"1000","value":"1010.08"},
{"id":"11","shares":"2000","value":"2020.15"}]
3.54
designatedSponsor
String
80
The designated sponsor of the IPO.
3.55
sponsors
Array
100
The other joint sponsors of the IPO. Here, member = the company name of a
joint sponsor.
Presented in a nested JSON format, e.g.
"sponsors":[
{"id":"1","member":"Goldman Sachs (Asia)"},
{"id":"2","member":"Morgan Stanley (Asia)"},
{"id":"3","member":"JP Morgan (Asia)"},
{"id":"4","member":"BOCI Securities"}]
3.56
legalSponsor
Array
100
The list of legal counsels retained by the sponsors of the IPO. Here, member =
the firm name of a sponsor counsel.
Presented in a nested JSON format, e.g.
"legalSponsor":[
{"id":"1","member":"Freshfields Bruckhaus Deringer"},
{"id":"2","member":"Clifford Chance"},
{"id":"3","member":"Deacons"}]
45
3.57
legalIssuer
String
80
The issuer’s legal counsel.
3.58
underwriters
Array
100
The list of underwriters within the IPO. Here, member = the company name of
an underwriter.
Presented in a nested JSON format, e.g.
"underwriters":[
{"id":"1","member":"Goldman Sachs (Asia)"},
{"id":"2","member":"Morgan Stanley (Asia)"},
{"id":"3","member":"JP Morgan (Asia)"},
{"id":"4","member":"BOCI Securities"}]
3.59
advisers
Array
100
The list of advisers within the IPO. Here, member = the company name of an
adviser.
Presented in a nested JSON format, e.g.
"advisers":[
{"id":"1","member":"Goldman Sachs (Asia)"},
{"id":"2","member":"Morgan Stanley (Asia)"},
{"id":"3","member":"JP Morgan (Asia)"},
{"id":"4","member":"BOCI Securities"}]
3.60
overallCoordinators
Array
100
The list of Overall Coordinators within the IPO. Here, the company of an overall
coordinator.
Presented in a nested JSON format, e.g.
"overallCoordinators":[
{"id":"1","member":"Goldman Sachs (Asia)"},
{"id":"2","member":"Morgan Stanley (Asia)"},
{"id":"3","member":"JP Morgan (Asia)"},
{"id":"4","member":"BOCI Securities"}]
3.61
distributors
Array
100
The list of distributors within the IPO. Here, member = the company name of a
distributor.
Presented in a nested JSON format, e.g.
"distributors":[
{"id":"1","member":"Goldman Sachs (Asia)"},
{"id":"2","member":"Morgan Stanley (Asia)"},
{"id":"3","member":"JP Morgan (Asia)"},
{"id":"4","member":"BOCI Securities"}]
3.62
hkSharereg
String
80
The HK share registrar of the IPO.
3.63
bookOpenDate
String
19
The time and date for opening the IPO’s public offer for subscriptions, in YYYY-
MM-DD HH:MM:SS format.
3.64
bookCloseDate
String
19
The time and date for closing the IPO’s public offer from subscriptions, in
YYYY-MM-DD HH:MM:SS format.
3.65
pricingDate
String
10
The latest time and date for determining the final price of the IPO, in YYYY-
MM-DD format.
3.66
allotmentDate
String
10
The expected date for broadcasting the public offer allotment results of the
IPO, in YYYY-MM-DD format.
3.67
listingDate
String
19
The expected time and date at which the IPO commences trading, in YYYY-
MM-DD HH:MM:SS format.
3.68
siInputDate
String
10
The expected date for HKSCC to permit the inputting of settlement instructions
into CCASS in relation to the IPO, in YYYY-MM-DD format.
3.69
placingSharesDeliveryDate
String
19
The latest time and date for delivering the institutional offer shares to CCASS.
3.70
prefOfferIndicator
String
1
If the IPO company has preferential offers, then "1". Else, the response will
return "0".
3.71
brokerage
Decimal
8,5
The percentage of the allotment value payable to the allottee’s broker,
example: "10" = 10%.
3.72
sfcLevy
Decimal
8,5
The percentage of the allotment value payable to the SFC, example: "10" =
10%.
3.73
sehkTradingFee
Decimal
8,5
The percentage of the allotment value payable to SEHK, example: "10" = 10%.
3.74
afrcTransactionLevy
Decimal
8,5
The percentage of the allotment value payable to Financial Reporting Council,
example: "10" = 10%.
4
totalSize
Integer
18
Total size of the API response.
5
timestamp
String
19
Timestamp of the API response, in YYYY-MM-DD HH:MM:SS format.
6
exception
Array
To indicate whether the entire request failed any validation checks:
46
 Empty array = no error(s) were identified across the entire request
 Non-empty array = the entire request was rejected due to a single or
multiple error(s), with each error expressed as an individual object
6.1
recordErrorCode
String
6
6.2
recordErrorMsg
String
100
{
"code": "0",
"message": "",
"data": [{
"stkCode": "9988",
"status": "40",
"companyEngFull": "Alibaba Group Holding Limited",
"companyEngShort": "BABA",
"companyChiFull": "阿里巴巴集團控股有限公司",
"companyChiShort": "阿里巴巴",
"placeOfCorp": "1",
"isin": "KYG017191142",
"nomValue": "0.000000000025",
"nomCur": "2",
"hkAddress": [{
"id": "1",
"line": "26/F Tower One, Times Square"
},
{
"id": "2",
"line": "1 Matheson Street"
},
{
"id": "3",
"line": "Causeway Bay"
},
{
"id": "4",
"line": "Hong Kong"
}
],
"warrants": [{
"warrantNameEngShort": "BABA-WRT 1",
"warrantNameEngFull": "Alibaba Warrant 1",
"warrantCode": "4988",
"isin": "",
"boardLot": 100000,
"subscriptionPrice": 2.000,
"faceValue": "Dollar Amount",
"totalWarrants": 10000000
},
{
"warrantNameEngShort": "BABA-WRT 2",
"warrantNameEngFull": "Alibaba Warrant 2",
"warrantCode": "4999",
"isin": "",
"boardLot": 100000,
"subscriptionPrice": 4.000,
"faceValue": "Dollar Amount",
"totalWarrants": 40000000
}
],
"offerType": 1,
"listSecurities": 1,
"listPlatform": 1,
47
"primaryExchange": ["10"],
"dualPrimaryExchange": null,
"biotechIndicator": "0",
"regsIndicator": "0",
"specialistTechIndicator": "0",
"wvrRatio": "1,10",
"tradeCurrency": "HKD",
"boardLot": 100,
"downwardPriceFlex": 10,
"priceMin": 0.000,
"priceMax": 188.000,
"priceFinal": null,
"clawback": [{
"id": "1",
"threshold": 1,
"allocation": 2.5
},
{
"id": "2",
"threshold": 15,
"allocation": 5
},
{
"id": "3",
"threshold": 50,
"allocation": 7.5
},
{
"id": "4",
"threshold": 100,
"allocation": 10
}
],
"preIpoShares": "80000000",
"ipoShares": "500000000",
"poSharesInitial": "12500000",
"poApplicationQuantity": "530465900",
"poOversubscriptionRatio": 42.44,
"poSharesFinal": "50000000",
"ioSharesInitial": "487500000",
"ioApplicationQuantity": "487500000",
"ioOversubscriptionRatio": 1.00,
"ioOfferSharesFinal": "450000000",
"poReallocationCap": 20,
"upsizeOption": 20,
"upsizePoShares": null,
"upsizeIoShares": null,
"overallotOption": 15,
"overallotPoShares": null,
"overallotIoShares": null,
"overallPoShares": null,
"overallIoShares": null,
"overallIpoShares ": null,
"totalIssuedCapitalListing": null,
"totalIssuedHsharesListing": null,
"totalIssuedNonwvrsharesListing": null,
"denomTable": [{
"id": "1",
"shares": 100,
"value": 188997.91
},
{
"id": "2",
48
"shares": 200,
"value": 37995.82
},
{
"id": "3",
"shares": 300,
"value": 56993.72
},
{
"id": "4",
"shares": 400,
"value": 75991.63
},
{
"id": "5",
"shares": 500,
"value": 94989.54
},
{
"id": "6",
"shares": 600,
"value": 113987.45
},
{
"id": "7",
"shares": 700,
"value": 132985.35
},
{
"id": "8",
"shares": 800,
"value": 151983.26
},
{
"id": "9",
"shares": 900,
"value": 170981.17
},
{
"id": "10",
"shares": 1000,
"value": 189979.08
},
{
"id": "11",
"shares": 2000,
"value": 379958.15
},
{
"id": "12",
"shares": 3000,
"value": 569937.23
},
{
"id": "13",
"shares": 4000,
"value": 759937.30
},
{
"id": "14",
"shares": 5000,
"value": 949895.38
},
49
{
"id": "15",
"shares": 6000,
"value": 1139874.46
},
{
"id": "16",
"shares": 7000,
"value": 1329853.53
},
{
"id": "17",
"shares": 8000,
"value": 1519832.61
},
{
"id": "18",
"shares": 9000,
"value": 1709811.68
},
{
"id": "19",
"shares": 10000,
"value": 1899790.76
}
],
"designatedSponsor": "Credit Suisse (Hong Kong) Limited",
"sponsors": [{
"id": "1",
"member": "China International Capital Corporation"
}],
"legalSponsor": [{
"id": "1",
"member": "Clifford Chance"
},
{
"id": "2",
"member": "Deacons"
}
],
"legalIssuer": "Freshfields Bruckhaus Deringer",
"underwriters": [],
"advisers": [],
"overallCoordinators": [{
"id": "1",
"member": "Credit Suisse (Hong Kong) Limited"
},
{
"id": "2",
"member": "China International Capital Corporation"
}
],
"distributors": [{
"id": "1",
"member": "Citigroup Global Markets Asia"
},
{
"id": "2",
"member": "JP Morgan"
},
{
"id": "3",
"member": "The Hongkong and Shanghai Banking"
50
}
],
"hkSharereg": "Computershare Investor Services HK",
"bookOpenDate": "2021-04-26 09:00:00",
"bookCloseDate": "2021-04-29 12:00:00",
"pricingDate": "2021-04-30",
"allotmentDate": "2021-04-30",
"listingDate": "2021-05-04 09:00:00",
"siInputDate": "2021-05-03",
"placingSharesDeliveryDate": "2021-05-04 09:00:00",
"prefOfferIndicator": "0",
"brokerage": 1.00000,
"sfcLevy": 0.00270,
"sehkTradingFee": 0.00500,
"afrcTransactionLevy": 0.00015
}],
"totalSize": 1,
"timestamp": "2021-04-29 15:00:00",
"exception":[]
}
51
7 EIPO Subscription
All EIPO Subscription-related requests and responses must be signed, with PII values encrypted / decrypted based on
the procedures set out in 3 End-to-End Encryption. All data field descriptions below are based upon the decrypted values
to illustrate the business-level validations required.
7.1
Add EIPO Subscription Entries
7.1.1
Request
POST
/api/eipo/subscriptions/add/v1
#
Field
Type
Length
Required
Description
1
data
Array
Yes
Min 1 object, max 1,000 objects. Each object should contain 1
subscriptions (i.e. each request may process up to 1,000 subscriptions).
1.1
requestID
Integer
7
Yes
A unique reference within the bulk request for pairing with a response
message. Must contain numeric characters only.
1.2
ipoID
String
20
Yes
Must be a valid ipoID from the Enquire IPO List API endpoint.
1.3
idList
Array
Yes
Min 1 object, max 4 objects. Each object contains the information of 1
applicant, e.g. 2 joint account holders should include 2 objects.
1.3.1
idType
String
2
Yes
The ID Type of the applicant, expressed in ID Codes:
ID Type
Description
1
HKID
2
National identification document
3
Passport
4
LEI registration document
5
Certificate of incorporation
6
Business registration certificate
7
Other official incorporation document
8
Broker-to-Client Assigned Number
If idList [Field 1.5] contains > 1 object, then must be 1, 2 or 3.
1.3.2
idCountryJurisdiction
String
3
Yes
The issuing authority of the applicant’s identification document. Based on
ISO-3166 Alpha-3 codes, or ‘OTH’ to represent "Other".
Restrictions:
If idType [Field #1.3.1] = 1, must be “HKG”.
If idType [Field #1.3.1] = 8, must be “OTH”.
1.3.3
idNum
String
40
Yes
The ID number of the applicant’s identification document.
Restrictions:
If idType [Field #1.3.1] = 1, then must be a concatenation (no spaces) of:
(i) Prefix: 1-2 upper case alphabetical characters
(ii) ID number: 6 integers
(iii) Check digit: 0 to 9, or “A”, enclosed by parentheses
Successful Examples
Unsuccessful Examples
Y123456(7), YZ123456(7),
Y123456, Y123456?
Y123456(A)
If idType [Field #1.3.1] = 2 and idCountryJurisdiction = 'CHN', idNum must
be either 15 or 18 characers.
If idType [Field #1.3.1] = 4, idNum must be exactly 20 uppercase
alphanumeric characters.
If idType [Field #1.3.1] = 8, idNum must be in “xxxxxx.##########”
format, where:
 “x” = a text string of exactly 6 uppercase alphanumeric characters
52
“.” = a delimiter to separate “x” and “#”
“#” = a positive integer up to 10 characters
Successful Examples
Unsuccessful Examples
“ABC123.1123456789”,
“ABC123.0000000001”,
“ABC123.112345678”,
“ABC123.0000000000”,
“ABC123.112345”
If idType [Field #1.3.1] = 3, 5, 6 or 7, any text input is permitted.
1.3.4
fullNameEng
String
150
No
The full English name of the applicant.
Only English alphanumeric characters are permitted. Mandatory if
fullNameChi [Field #1.5.5] = null or blank.
If IdType [Field #1.3.1] = 8, fullNameEng must be blank or null.
1.3.5
fullNameChi
String
150
No
The full Chinese or non-English name of the applicant.
Fully UTF-8 encoded. Mandatory if fullNameEng [Field #1.5.4] = null or
blank.
If IdType [Field #1.3.1] = 8, fullNameChi must be blank or null.
1.4
appQuantity
String
20
Yes
The number of securities being subscribed by the applicant.
Must be a ‘shares’ parameter from denomTable in the Enquire IPO
Reference Data API.
1.5
firmID
String
5
Yes
The SEHK Participant ID for identifying the recipient of any brokerage
fees.
Must be a valid SEHK Participant ID (with no leading zeroes), or ‘00000’
for HKSCC.
1.6
ownRef
String
40
No
Free text field for own reference.
{
"data": [{
"requestID": 1,
"ipoID": "1234",
"idList": [{
"idType": "1",
"idCountryJurisdiction": "HKG",
"idNum": "A123456(9)",
"fullNameEng": "Chan Tai Man",
"fullNameChi": "陳大文"
},
{
"idType": "1",
"idCountryJurisdiction": "HKG ",
"idNum": "B234567(1)",
"fullNameEng": "Chan Siu Man",
"fullNameChi": "陳小文"
}
],
"appQuantity": "1000",
"firmID": "00000",
"ownRef": null
},
{
"requestID": 2,
"ipoID": "1234",
53
"idList": [{
"idType": "4",
"idCountryJurisdiction": "OTH",
"idNum": "A1B200D4E5F6G7H8I9J0",
"fullNameEng": "Alpha Company Ltd",
"fullNameChi": "甲有限公司"
}],
"appQuantity": "5000",
"firmID": "00000"
},
{
"requestID": 3,
"ipoID": "1234",
"idList": [{
"idType": "1",
"idCountryJurisdiction": "HKG",
"idNum": "C345678(A)",
"fullNameEng": "",
"fullNameChi": "Rémy Victor"
}],
"appQuantity": "500000",
"firmID": "00000",
"ownRef": "Favourite client"
}
]
}
7.1.2
Response
#
Field
Type
Length
Description
1
code
String
6
0 to indicate ‘successful response’.
2
message
String
100
Empty string, i.e. "" to indicate successful response.
3
data
Array
3.1
requestID
Integer
7
The requestID from the original API request.
3.2
recordID
String
17
A Record ID generated for each subscription that has passed all validation
checks. It contains: (i) a sequentially-generated 16-digit integer; and (ii) a suffix
indicating the method through which the subscription was is created ("O" =
Online input, "B" = Bulk upload, and "A" = API.).
A response without a recordID indicates that the subscription failed ≥1
validation check(s).
3.3
exception
Array
To indicate whether an individual request has failed any validation checks:
 Empty array = the individual request has passed all validation checks
 Non-empty array = the individual request has a single or multiple errors,
with each error expressed as an individual object
3.3.1
recordErrorCode
String
6
3.3.2
recordErrorMsg
String
100
4
totalSize
Integer
18
Total size of the API response.
5
timestamp
String
19
Timestamp of the API response, in YYYY-MM-DD HH:MM:SS format.
6
exception
Array
To indicate whether the entire request failed any structural or permission-
related validation checks:
 Empty array = no structural or permission-related error(s) were identified
across the entire request
 Non-empty array = the entire request was rejected due to a single or
multiple structural or permission-related error(s), with each error expressed
as an individual object
54
6.1
recordErrorCode
String
6
6.2
recordErrorMsg
String
100
{
"code": "0",
"message": "",
"data": [
{
"requestID": 1,
"recordID": "1234567890123456A",
"exception": []
},
{
"requestID": 2,
"recordID": "1234567890123457A",
"exception": []
},
{
"requestID": 3,
"recordID": "123456789018858A",
"exception": []
}
],
"totalSize": 3,
"timestamp": "2021-08-26 09:13:22",
"exception": []
}
55
7.2
Change EIPO Subscription Entries
7.2.1
Request
POST
/api/eipo/subscriptions/change/v1
#
Field
Type
Length
Required
Description
1
data
Array
Yes
Min 1 object, max 1,000 objects. Each object should contain 1
subscriptions (i.e. each request may process up to 1,000 subscriptions).
1.1
recordID
String
17
Yes
To indicate the subscription that is being amended. Must be a valid
Record ID within own subscription list, under "Authorised" sub-flow status.
1.2
idList
Array
Yes
Min 1 object, max 4 objects. Each object should contain the subscription
information of 1 applicant, e.g. a joint account subscription with 2
applicants should include 2 objects.
1.2.1
idType
String
2
Yes
The ID Type of the applicant, expressed in ID Codes:
ID Type
Description
1
HKID
2
National identification document
3
Passport
4
LEI registration document
5
Certificate of incorporation
6
Business registration certificate
7
Other official incorporation document
8
Broker-to-Client Assigned Number
If idList [Field 1.2] contains > 1 object, then must be 1, 2 or 3.
1.2.2
idCountryJurisdiction
String
3
Yes
The issuing authority of the applicant’s identification document. Based on
ISO-3166 Alpha-3 codes, or ‘OTH’ to represent "Other".
Restrictions:
If idType [Field #1.2.1] = 1, must be “HKG”.
If idType [Field #1.2.1] = 8, must be “OTH”.
1.2.3
idNum
String
40
Yes
The ID number of the applicant’s identification document.
Restrictions:
If idType [Field #1.2.1] = 1, then must be a concatenation (no spaces) of:
(iv)Prefix: 1-2 upper case alphabetical characters
(v) ID number: 6 integers
(vi)Check digit: 0 to 9, or “A”, enclosed by parentheses
Successful Examples
Unsuccessful Examples
Y123456(7), YZ123456(7),
Y123456, Y123456?
Y123456(A)
If idType [Field #1.2.1] = 2 and idCountryJurisdiction = 'CHN', idNum must
be either 15 or 18 characers.
If idType [Field #1.2.1] = 4, then must be exactly 20 uppercase
alphanumeric characters.
If idType [Field #1.2.1] = 8, must be in “xxxxxx.##########” format,
where:
 “x” = a text string of exactly 6 uppercase alphanumeric characters
“.” = a delimiter to separate “x” and “#”
“#” = a positive integer up to 10 characters
Successful Examples
Unsuccessful Examples
“ABC123.1123456789”,
“ABC123.0000000001”,
“ABC123.112345678”,
“ABC123.0000000000”,
56
“ABC123.112345”
If idType [Field #1.2.1] = 2, 3, 5, 6 or 7, any text input is permitted.
1.2.4
fullNameEng
String
150
No
The full English name of the applicant.
Only English alphanumeric characters are permitted. Mandatory if
fullNameChi [Field #1.2.5] = null or blank.
If IdType [Field #1.2.1] = 8, fullNameEng must be blank or null.
1.2.5
fullNameChi
String
150
No
The full Chinese or non-English name of the applicant.
Fully UTF-8 encoded. Mandatory if fullNameEng [Field #1.2.4] = null or
blank.
If IdType [Field #1.2.1] = 8, fullNameChi must be blank or null.
1.3
appQuantity
String
20
Yes
The number of securities being subscribed by the applicant.
Must be a ‘shares’ parameter from denomTable in the Enquire IPO
Reference Data API.
1.4
firmID
String
5
Yes
The SEHK Participant ID for identifying the recipient of any brokerage
fees.
Must be a valid SEHK Participant ID (with no leading zeroes), or ‘00000’
for HKSCC.
1.5
ownRef
String
40
No
Free text field for own reference.
{
"data": [{
"recordID": "1234567890123456A",
"idList": [{
"idType": "1",
"idCountryJurisdiction": "HKG",
"idNum": "A123456(9)",
"fullNameEng": "Chan Tai Man",
"fullNameChi": "陳大文"
},
{
"idType": "1",
"idCountryJurisdiction": "HKG ",
"idNum": "B234567(1)",
"fullNameEng": "Chan Siu Man",
"fullNameChi": "陳小文"
},
{
"idType": "1",
"idCountryJurisdiction": "HKG ",
"idNum": "B234567(1)",
"fullNameEng": "Mary Lee Sum See",
"fullNameChi": "李心思"
}],
"appQuantity": "1000",
"firmID": "00000",
"ownRef": null
}
57
]
}
7.2.2
Response
#
Field
Type
Length
Description
1
code
String
6
0 to indicate ‘successful response’.
2
message
String
100
Empty string, i.e. "" to indicate successful response.
3
data
Array
3.1
recordID
String
17
The recordID from the original API request.
3.2
exception
Array
To indicate whether an individual request has failed any validation checks:
 Empty array = the individual request has passed all validation checks
 Non-empty array = the individual request has a single or multiple errors,
with each error expressed as an individual object
3.2.1
recordErrorCode
String
6
3.2.2
recordErrorMsg
String
100
4
totalSize
Integer
18
Total size of the API response.
5
timestamp
String
19
Timestamp of the API response, in YYYY-MM-DD HH:MM:SS format.
6
exception
Array
To indicate whether the entire request failed any structural or permission-
related validation checks:
 Empty array = no structural or permission-related error(s) were identified
across the entire request
 Non-empty array = the entire request was rejected due to a single or
multiple structural or permission-related error(s), with each error expressed
as an individual object
6.1
recordErrorCode
String
6
6.2
recordErrorMsg
String
100
{
"code": "0",
"message": "",
"data": [
{
"recordID": "1234567890123456A",
"exception": []
}
],
"totalSize": 1,
"timestamp": "2021-08-26 10:15:39",
"exception": []
}
58
7.3
Invalidate EIPO Subscription Entries
7.3.1
Request
POST
/api/eipo/subscriptions/invalidate/v1
#
Field
Type
Length
Required
Description
1
data
Array
Yes
Min 1 object, max 1,000 objects. Each object should contain 1
subscriptions (i.e. each request may process up to 1,000 subscriptions).
1.1
recordID
String
17
Yes
To indicate the subscription that is being amended. Must be a valid
Record ID within own subscription list, under "Authorised" sub-flow status.
{
"data": [
{
"recordID": "1234567890123456A"
}
]
}
7.3.2
Response
#
Field
Type
Length
Description
1
code
String
6
0 to indicate ‘successful response’.
2
message
String
100
Empty string, i.e. "" to indicate successful response.
3
data
Array
3.1
recordID
String
17
The recordID from the original API request.
3.2
exception
Array
To indicate whether an individual request has failed any validation checks:
 Empty array = the individual request has passed all validation checks
 Non-empty array = the individual request has a single or multiple errors,
with each error expressed as an individual object
3.2.1
recordErrorCode
String
6
3.2.2
recordErrorMsg
String
100
4
totalSize
Integer
18
Total size of the API response.
5
timestamp
String
19
Timestamp of the API response, in YYYY-MM-DD HH:MM:SS format.
6
exception
Array
To indicate whether the entire request failed any structural or permission-
related validation checks:
 Empty array = no structural or permission-related error(s) were identified
across the entire request
 Non-empty array = the entire request was rejected due to a single or
multiple structural or permission-related error(s), with each error expressed
as an individual object
6.1
recordErrorCode
String
6
6.2
recordErrorMsg
String
100
{
"code": "0",
"message": "",
"data": [
{
"recordID": "1234567890123456A",
"exception": []
}
],
"totalSize": 1,
59
"timestamp": "2021-08-26 11:28:09"
"exception": []
}
60
7.4
Enquire EIPO Subscription Entries
7.4.1
Request
POST
/api/eipo/subscriptions/query/v1
#
Field
Type
Length
Required
Description
1
data
Object
Yes
1.1
ipoID
String
20
No
Must be a valid ipoID from the Enquire IPO List API endpoint. Mandatory
if recordID [Field #1.2] = null or blank.
1.2
recordID
Array
1000*1
No
Must be a valid Record ID within own subscription list, under "Authorised"
of
7
sub-flow status. Mandatory if ipoID [Field #1.1] = null or blank.
String
1.3
subFlowStatus
String
2
No
To filter response by a subscription’s status, either by "3" (Authorised, i.e.
active subscription) or "4" (Invalidated, i.e. previously active, now
removed from subscription list).
2
size
Integer
18
No
Expected page size of the API response. Must be between 1 and 1,000. If
null or blank, default as 100.
3
nextCursor
String
20
Yes
Key reference (recordID) from which the response message should start.
"0" should be used to start from the first index.
{
"data": {
"ipoID":"1234",
"recordID": [],
"subFlowStatus": null
},
"size": 100,
"nextCursor": "0"
}
{
"data": {
"ipoID":"1234",
"recordID":["2462303930948573A","4317515259216099A","5365467074774676A"],
"subFlowStatus": null
},
"size": 100,
"nextCursor": "6962170439634540A"
}
{
"data": {
"ipoID":"1234",
"recordID":["2462303930948573A","4317515259216099A","5365467074774676A"],
"subFlowStatus":"3"
},
"size": 100,
"nextCursor": "6962170439634540A"
}
61
7.4.2
Response
#
Field
Type
Length
Description
1
code
String
6
0 to indicate ‘successful response’.
2
message
String
100
Empty string, i.e. "" to indicate successful response.
3
data
Array
3.1
stkCode
String
10
The IPO’s stock code.
3.2
isin
String
12
The IPO’s ISIN.
3.3
status
String
2
The status of the IPO, expressed in status codes:
Status
Description
25
Deal Initiated
30
Public Offer Closed
35
Application Validated
45
Allotment Confirmed
50
Money Settlement
55
Allocation Confirmed
60
Placing Approved
65
Allotment Results Approved
70
Trading Started
80
Suspended
90
Cancelled
3.4
subFlowStatus
String
2
The status of the subscription, expressed in status codes:
Status
Description
3
Authorised, i.e. active subscription
4
Invalidated, i.e. previously active, now removed from
subscription list
3.5
recordID
String
17
The subscription’s Record ID.
3.6
idList
Array
Min 1 object, max 4 objects. Each object contains the information of 1
applicant, e.g. 2 joint account holders should include 2 objects.
3.6.1
idType
String
2
The ID Type of the applicant, expressed in ID Codes:
ID Type
Description
1
HKID
2
National identification document
3
Passport
4
LEI registration document
5
Certificate of incorporation
6
Business registration certificate
7
Other official incorporation document
8
Broker-to-Client Assigned Number
3.6.2
idCountryJurisdiction
String
3
The issuing authority of the applicant’s identification document. Based on ISO-
3166 Alpha-3 codes, or ‘OTH’ to represent "Other".
3.6.3
idNum
String
40
The ID number of the applicant’s identification document.
3.6.4
fullNameEng
String
150
The full English name of the applicant.
3.6.5
fullNameChi
String
150
The full Chinese or non-English name of the applicant.
3.7
appQuantity
String
20
The number of securities being subscribed by the applicant
3.8
allotQuantity
String
20
The number of securities allotted to the applicant.
3.9
firmID
String
5
The SEHK Participant ID for identifying the recipient of any brokerage fees.
3.10
ownRef
String
40
Free text field for own reference.
3.11
unsuccessfulReason
String
2
To indicate the applicable reason for which the subscription was unsuccessful,
expressed in reason codes:
ID Type
Description
0
Allotted
1
Not allotted
2
Failed pre-funding
3
Duplicate application
4
Incomplete information
62
5
Invalid BCAN
6
EIPO default
99
Others
3.12
intDuplicateIndicator
String
1
If the subscription has been identified as a duplicate within the HKSCC
Participant’s subscription list, then "1". Else, the response will return "0".
3.13
exception
Array
To indicate whether an individual request has failed any validation checks:
 Empty array = the individual request has passed all validation checks
 Non-empty array = the individual request has a single or multiple errors,
with each error expressed as an individual object
3.13.1
recordErrorCode
String
6
3.13.2
recordErrorMsg
String
100
4
totalSize
Integer
18
Total size of the API response.
5
timestamp
String
19
Timestamp of the API response, in YYYY-MM-DD HH:MM:SS.
6
nextCursor
String
20
The key reference (recordID) immediately after the final result of response. If
there are no further records, "0" will be returned.
7
exception
Array
To indicate whether the entire request failed any structural or permission-
related validation checks:
 Empty array = no structural or permission-related error(s) were identified
across the entire request
 Non-empty array = the entire request was rejected due to a single or
multiple structural or permission-related error(s), with each error expressed
as an individual object
7.1
recordErrorCode
String
6
7.2
recordErrorMsg
String
100
{
"code": "0",
"message": "",
"data": [{
"stkCode": "9988",
"isin": "KYG017191142",
"status": "25",
"subFlowStatus": "3",
"recordID": "2462303930948573A ",
"idList": [{
"idType": "1",
"idCountryJurisdiction": "HKG",
"idNum": "A123456(9)",
"fullNameEng": "Chan Tai Man",
"fullNameChi": "陳大文"
},
{
"idType": "1",
"idCountryJurisdiction": "HKG ",
"idNum": "B234567(1)",
"fullNameEng": "Chan Siu Man",
"fullNameChi": "陳小文"
},
{
"idType": "1",
"idCountryJurisdiction": "HKG ",
"idNum": "B234567(1)",
"fullNameEng": "Mary Lee Sum See",
"fullNameChi": "李心思"
}],
"appQuantity": "1000",
"allotQuantity": "100",
63
"firmID": "00000",
"ownRef": null,
"unsuccessfulReason": "0",
"intDuplicateIndicator": "0",
"exception": []
},
{
"stkCode": "9988",
"isin": "KYG017191142",
"status": "25",
"subFlowStatus": "3",
"recordID": "4317515259216099A ",
"idList": [{
"idType": "4",
"idCountryJurisdiction": "OTH",
"idNum": "A1B200D4E5F6G7H8I9J0",
"fullNameEng": "Alpha Company Ltd",
"fullNameChi": "甲有限公司"
}],
"appQuantity": "5000",
"allotQuantity": "500",
"firmID": "00000",
"ownRef": null,
"unsuccessfulReason": "0",
"intDuplicateIndicator": "0",
"exception": []
},
{
"stkCode": "9988",
"isin": "KYG017191142",
"status": "25",
"subFlowStatus": "3",
"recordID": "5365467074774676A ",
"idList": [{
"idType": "1",
"idCountryJurisdiction": "HKG",
"idNum": "C345678(A)",
"fullNameEng": "",
"fullNameChi": "Rémy Victor"
}],
"appQuantity": "500000",
"allotQuantity": "50000",
"firmID": "00000",
"ownRef": null,
"unsuccessfulReason": "0",
"intDuplicateIndicator": "0",
"exception": []
}],
"totalSize": 3,
"timestamp": "2021-08-26 12:30:29",
"nextCursor": "0",
"exception":[]
}
64
8 EIPO Funding
8.1
Enquire EIPO Funding
8.1.1
Request
POST
/api/eipo/funding/query/v1
#
Field
Type
Length
Required
Description
1
data
Object
Yes
1.1
ipoID
String
20
No
Must be a valid ipoID from the Enquire IPO List API endpoint. Mandatory
if transactionRef [Field #1.2] = null or blank.
1.2
transactionRef
Array
1000*1
No
Must be a valid transactionRef assigned to the HKSCC Participant’s EIPO
of
3
subscriptions within an IPO. Mandatory if ipoID [Field #1.1] = null or
String
blank.
1.3
preFundingStatus
String
2
No
Sub-flow status of the Transaction Reference, expressed as status codes:
Code
Description
10
Pending
15
Not Applicable
20
Confirmed
30
Rejected
40
Invalidated
During the public offer book open (before the Pre-funding Requirement is
finalised), this field returns as null.
2
size
Integer
18
No
Expected page size of the API response. Must be between 1 and 1,000. If
null or blank, default as 100.
3
nextCursor
String
20
Yes
Timestamp of the API response, in YYYY-MM-DD HH:MM:SS format.
{
"data": {
"ipoID":"1234",
"transactionRef": [],
"preFundingStatus": null
},
"size": 100,
"nextCursor": "0"
}
{
"data": {
"ipoID":"1234",
"transactionRef": ["1241677736293","1614124660146","4557626203254"],
"preFundingStatus": null
},
"size": 100,
"nextCursor": "2244"
}
65
{
"data": {
"ipoID":"1234",
"transactionRef": ["1241677736293","1614124660146","4557626203254"],
"preFundingStatus": "10"
},
"size": 100,
"nextCursor": "5835245508721"
}
8.1.2
Response
#
Field
Type
Length
Description
1
code
String
6
0 to indicate ‘successful response’.
2
message
String
100
Empty string, i.e. "" to indicate successful response.
3
data
Array
3.1
ipoID
String
20
A unique, sequentially-generated value assigned to each IPO case stored on
FINI. Used as the identifier for IPOs within the FINI API Gateway.
3.2
stkCode
String
10
The IPO’s stock code.
3.3
isin
String
12
The IPO’s ISIN.
3.4
status
String
2
The status of the IPO, expressed in status codes:
Status
Description
25
Deal Initiated
30
Public Offer Closed
35
Application Validated
45
Allotment Confirmed
50
Money Settlement
55
Allocation Confirmed
60
Placing Approved
65
Allotment Results Approved
70
Trading Started
80
Suspended
90
Cancelled
3.5
transactionRef
String
13
The Transaction Reference assigned to the HKSCC Participant’s EIPO
subscriptions within the IPO.
3.6
preFundingStatus
String
2
Sub-flow status of the Transaction Reference, expressed as status codes:
Code
Description
10
Pending
15
Not Applicable
20
Confirmed
30
Rejected
40
Invalidated
During the public offer book open (before the Pre-funding Requirement is
finalised), this field returns as null.
3.7
settlementStatus
String
2
Settlement status of the Transaction Reference, expressed as status codes:
Code
Description
10
Pending
15
Not Applicable
20
Settled
30
Rejected
40
Defaulted
Before the public offer allotment is made available, this field returns as null.
3.8
ipoInfo
Object
3.8.1
tradeCurrency
String
3
The IPO’s trading currency, expressed as currency codes:
66
Currency
Description
HKD
Hong Kong Dollar
CNY
Chinese Yuan
USD
United States Dollar
3.8.2
priceMin
Decimal
12,3
The minimum offer price of the IPO.
3.8.3
downwardPriceFlex
Decimal
3,0
The percentage at which the IPO company may price its IPO below the
minimum offer price. Example: "10" = 10%.
3.8.4
priceFloor
Decimal
12,3
The lowest possible price for the IPO, calculated as priceMin * (1 -
downwardPriceFlex).
3.8.5
priceMax
Decimal
12,3
The maximum offer price of the IPO.
3.8.6
priceFinal
Decimal
12,3
The final offer price of the IPO.
3.8.7
poMaxValue
Decimal
20,2
The highest value the IPO company is able to allocate to the public offer.
3.8.8
prefundingDate
String
19
The date for confirming the HKSCC Participants’ pre-funding requirements.
3.9
fundingInfo
Object
3.9.1
partID
String
6
The HKSCC Participant’s ID within CCASS.
3.9.2
partName
String
15
The HKSCC Participant’s company short name.
3.9.3
poMaxOptIn
String
1
To indicate whether the HKSCC Participant has opted in to poMax for the pre-
funding requirement calculations. "Y" = Yes, "N" = No.
3.9.4
totalAppQuantity
String
20
The total number of securities subscribed by the HKSCC Participant within the
IPO.
3.9.5
appValue
Decimal
20,2
The total value of securities subscribed by the HKSCC Participant within the
IPO.
3.9.6
prefundingReq
Decimal
20,2
The HKSCC Participant’s pre-funding requirement. If the HKSCC Participant’s
poMaxOptIn = "Y", then it is calculated as the lower figure between poMax
Value and appValue. If the HKSCC Participant’s poMaxOptIn = "N", then it is
the appValue.
3.9.7
totalAllotQuantity
String
20
The total number of securities allotted to the HKSCC Participant within the IPO.
3.9.8
allotValue
Decimal
20,2
The total value of securities allotted the HKSCC Participant within the IPO.
3.10
bankAccInfo
Object
3.10.1
cpBankCode
String
3
The bank code of the HKSCC Participant’s designated bank account from
which the pre-funding requirement should be transferred.
3.10.2
cpBranchCode
String
3
The branch code of the HKSCC Participant’s designated bank account from
which the pre-funding requirement should be transferred.
3.10.3
cpBankAcctNum
String
9
The bank account number of the HKSCC Participant’s designated bank
account from which the pre-funding requirement should be transferred.
3.10.4
nomBankCode
String
3
The bank code of the EIPO Designated Bank’s nominee bank account to which
the pre-funding requirement should be transferred.
3.10.5
nomBranchCode
String
3
The branch code of the EIPO Designated Bank’s nominee bank account to
which the pre-funding requirement should be transferred.
3.10.6
nomBankAcctNum
String
28
The bank account number of the EIPO Designated Bank’s nominee bank
account to which the pre-funding requirement should be transferred.
3.11.7
debtorRef
String
40
The debtor reference of the EIPO Designated Bank’s nominee bank account to
which the pre-funding requirement should be transferred.
3.11
exception
Array
To indicate whether an individual request has failed any validation checks:
 Empty array = the individual request has passed all validation checks
 Non-empty array = the individual request has a single or multiple errors,
with each error expressed as an individual object
3.11.1
recordErrorCode
String
6
3.11.2
recordErrorMsg
String
100
4
totalSize
Integer
18
Total size of the API response.
5
timestamp
String
19
Timestamp of the API response, in YYYY-MM-DD HH:MM:SS format.
6
nextCursor
String
20
The key reference (transactionRef) immediately after the final result of
response. If there are no further records, "0" will be returned.
7
exception
Array
To indicate whether the entire request failed any structural or permission-
related validation checks:
 Empty array = no structural or permission-related error(s) were identified
across the entire request
67
 Non-empty array = the entire request was rejected due to a single or
multiple structural or permission-related error(s), with each error expressed
as an individual object
7.1
recordErrorCode
String
6
7.2
recordErrorMsg
String
100
{
"code": "0",
"message": "",
"data": [{
"ipoID": "1234",
"stkCode": "9988",
"isin":"KYG017191142",
"status": "25",
"transactionRef": "1241677736293",
"preFundingStatus": "10",
"settlementStatus": null,
"ipoInfo": {
"tradeCurrency": "HKD",
"priceMin": 0.000,
"downwardPriceFlex": 0,
"priceFloor": 0.000,
"priceMax": 188.000,
"priceFinal": 176,
"poMaxValue": 10449004280.00,
"prefundingDate": "2020-09-30"
},
"fundingInfo": {
"partID": "B01130",
"partName": "BOCI SECURITIES",
"poMaxOptIn": "Y",
"totalAppQuantity": "1000000",
"appValue": 208980085.60,
"prefundingReq": 208980085.60,
"totalAllotQuantity": null,
"allotValue": null
},
"bankAccInfo": {
"cpBankCode": "012",
"cpBranchCode": "001",
"cpBankAcctNum": "929874231",
"nomBankCode": "012",
"nomBranchCode": "004",
"nomBankAcctNum": "612352324",
"debtorRef": "ABCEDFGH"
},
"exception": []
},
{
"ipoID": "1234",
"stkCode": "9988",
"isin":"KYG017191142",
"status": "25",
"transactionRef": "1614124660146",
"preFundingStatus": "10",
"settlementStatus": "",
"ipoInfo": {
"tradeCurrency": "HKD",
"priceMin": 0.000,
"downwardPriceFlex": 0,
"priceFloor": 0.000,
"priceMax": 188.000,
68
"priceFinal": 176,
"poMaxValue": 10449004280.00,
"prefundingDate": "2020-09-30"
},
"fundingInfo": {
"partID": "B01345",
"partName": " PHILLIPSECHKLTD ",
"poMaxOptIn": "Y",
"totalAppQuantity": 3400200,
"appValue": 710574087.06,
"prefundingReq": 710574087.06,
"totalAllotQuantity": null,
"allotValue": null
},
"bankAccInfo": {
"cpBankCode": "012",
"cpBranchCode": "001",
"cpBankAcctNum": "827634232",
"nomBankCode": "012",
"nomBranchCode": "004",
"nomBankAcctNum": "612352324",
"debtorRef": "BCDEFGHI"
},
"exception": []
}
],
"totalSize": 2,
"timestamp": "2021-09-30 08:12:33",
"nextCursor": "0",
"exception": []
}
69
8.2
Confirm EIPO Funding
8.2.1
Request
POST
/api/eipo/funding/confirm/v1
#
Field
Type
Length
Required
Description
1
data
Array
Yes
Min 1 object, max 1,000 objects. Each object should contain 1
subscriptions (i.e. each request may process up to 1,000 subscriptions).
1.1
transactionRef
String
13
Yes
Must be a valid Transaction Reference with a preFundingStatus = "10"
1.2
preFundingStatus
String
2
Yes
The target pre-funding status to be amended by the API request.
Status
Description
20
Confirm pre-funding
30
Reject pre-funding
{
"data": [{
"transactionRef": "6398340114921",
"preFundingStatus": "20"
},
{
"transactionRef": "6398340114936",
"preFundingStatus": "20"
},
{
"transactionRef": "6398340114947",
"preFundingStatus": "20"
},
{
"transactionRef": "6398340114959",
"preFundingStatus": "20"
},
{
"transactionRef": "6398340114972",
"preFundingStatus": "30"
}
]
}
70
8.2.2
Response
#
Field
Type
Length
Description
1
code
String
6
0 to indicate ‘successful response’.
2
message
String
100
Empty string, i.e. "" to indicate successful response.
3
data
Array
3.1
transactionRef
String
13
The transactionRef from the original API request.
3.2
preFundingStatus
String
2
The latest preFundingStatus after processing the API request.
3.3
exception
Array
To indicate whether an individual request has failed any validation checks:
 Empty array = the individual request has passed all validation checks
 Non-empty array = the individual request has a single or multiple errors,
with each error expressed as an individual object
3.31
recordErrorCode
String
6
3.32
recordErrorMsg
String
100
4
totalSize
Integer
18
Total size of the API response.
5
timestamp
String
19
Timestamp of the API response, in YYYY-MM-DD HH:MM:SS format.
6
exception
Array
To indicate whether the entire request failed any structural or permission-
related validation checks:
 Empty array = no structural or permission-related error(s) were identified
across the entire request
 Non-empty array = the entire request was rejected due to a single or
multiple structural or permission-related error(s), with each error expressed
as an individual object
6.1
recordErrorCode
String
6
6.2
recordErrorMsg
String
100
{
"code": "0",
"message": "",
"data": [{
"transactionRef": "6398340114921",
"preFundingStatus": "20",
"exception": []
},
{
"transactionRef": "6398340114936",
"preFundingStatus": "20",
"exception": []
},
{
"transactionRef": "6398340114947",
"preFundingStatus": "20",
"exception": []
},
{
"transactionRef": "6398340114959",
"preFundingStatus": "20",
"exception": []
},
{
"transactionRef": "6398340114972",
"preFundingStatus": "30",
"exception": []
}
],
"totalSize": 5,
"timestamp": "2021-09-30 11:55:21",
71
"exception": []
}
72
9 FAQs for External User Testing (EUT) & Production
9.1
FINI API Connectivity
1.
How to ensure the connectivity to FINI API Gateway is successful after VPN is established?
Any typical browser request on the EIPO Listing API endpoint without JWT can get a JSON return.
{
"code" : "1G001",
"message" : "Bad Parameter Input",
"data" : [ ],
"totalSize" : 0,
"timestamp" : "2023-02-14 11:24:38",
"exception" : [ ]
}
2.
Where can the Participants input/maintain Agent profile and Machine profile information for JSON Web
Token (JWT)?
Under Support -> Manage Access Rights
3.
Why does Development Tool Postman / Browser return invalid SSL in EUT environment when
accessing the FINI API endpoints?
Self-signed CA Certificate approach is used for EUT, participants can suppress the SSL checking in the
setting of Postman and accept the SSL warning from Browser. API program should also accept the self-
signed CA certificate when connecting to FINI API Gateway.
4.
Can I use IP address instead of domain name for the API requests?
No. FINI will reject API request accessing by IP address.
5.
Can I perform load/performance testing on FINI EUT or Production environment?
No. There is throttle control, participants will find their IP is blocked and restricted to access FINI APIs.
9.2
FINI API Authentication
1. Does FINI API support SAML authentication?
No. FINI API uses OATH2.0 for authentication.
2. How to generate public and private key pair set for testing purpose?
73
Developer is recommended to use self-developed application for public and private key pair set generation.
For quick testing purpose, there are also free resources from the internet for public and private key pair
generation.
e.g.
Corresponding Key parameter requirement
Key Size: 2048
Key Use: Signature
Algorithm: RS256
Key ID: SHA-256
Show X.509: Yes
3. How do the Participants update their Key (Key Rotation every year) without application outage?
Both Agent Profile and Machine Profile allow at most two key pairs to be registered and used
simultaneously. Participants can consider updating one by one to minimize impact.
4. Can multiple program instances use the same JWT (from HKEX AM) for API requests?
Not recommended.
5. What is the JWT (from HKEX AM) expiry time?
The JWT expiry time is 30s.
9.3 EIPO Subscription Entries APIs encryption
1. Why does JAVA SecureRandom.getInstanceStrong() that recommended by the API Workshop unable to
work on Linux environment?
The SecureRandom.getInstanceStrong() works on Windows platform only, please consider using
SecureRandom.getInstance("NativePRNGNonBlocking") on Linux.
2. What is the reason of error message “Crypto process exception”?
Please check if encryption has been done for the following two API endpoints on Personal Data fields
according to the API Specification.
api/eipo/subscriptions/add/v1
api/eipo/subscriptions/change/v1
74
3.
As long as no personal data should be encrypted for Enquire/Invalidate EIPO Subscription Entries
APIs, what is the reason of having error message “Crypto process exception”?
Please check X-FINI-ENCRYPTION-CLIENT in HTTP header, which must be set to "N" for
Enquire/Invalidate EIPO.
4.
How often is the changing of public Key from Crypto Metadata Request API?
The public key may be changed/updated from time to time without notification. Please retrieve the key for
every single request that requires encryption.
9.4
FINI API endpoint validation
1.
What is the reason for always getting Signature Error for EIPO Subscription Entries API?
Please ensure the 3 major components must be included for the Signature calculation.
Payload + Request ID + Timestamp
2.
What is the reason always getting Signature Error when I use development tool Postman for all
encryption needed APIs?
Postman probably adds additional line break for the input payload, this makes discrepancy between the
Signature calculation value. Developer should ensure the Signature calculation on the payload is identical
to the Postman submitted one.
3.
What is the reason of error message “Bad Parameter Input”?
If the input JSON payload (POST Request) fails to pass the basic syntax validation leading FINI cannot
parse the JSON content OR missing mandatory parameters in the endpoint URL(GET Request). Then the
general validation message “Bad Parameter Input” will be found, thus the whole API request will be rejected.
4.
What if requestID value is duplicated in the same Add EIPO Subscription Entries API request?
All the particular duplicated records in the request will be rejected, other records with unique requestID will
be handled as usual.
5.
Can I use same requestID value in different Add EIPO Subscription Entries API requests?
Yes. The duplication checking on requestID only happens in the same Add EIPO Subscription Entries API
request.
6.
Will the whole Add EIPO Subscription Entries API request be rejected if there is certain number of
records are invalid?
No. FINI will reject only those invalid records, if the whole Add EIPO Subscription Entries API request can
pass the basic syntax validation.
7.
What will happen if the same EIPO applicant content was submitted by the same/different Add EIPO
Subscription Entries API requests from the same CP?
There is no immediate EIPO application duplication checking on the Add EIPO Subscription Entries API
request. All those requests, having duplications, will be submitted and recorded in FINI but the flag
75
intDuplicateIndicator will be updated as “1” from Enquire EIPO Subscription Entries endpoint return. In case
no further action is taken by CP, all duplicated records will be rejected only on the EIPO Public Offer Close
Day.
8.
What will happen if the same EIPO applicant content was submitted by different CPs?
The duplicated records will be rejected on the EIPO Public Offer Close Day.
9.
Is there any full list of FINI validation can be provided?
There is no FINI validation full list for the public, participants have to retrieve the validation error message
from the JSON response to understand the cause of rejection.
Generally, participants can check the HTTP response value (Section 2.4.2) to determine the follow up
action. HTTP 200 with JSON response is usually related business validation. IT team should follow up for
other HTTP response values like 400, 403, 404..etc.
9.5
Miscellaneous
1.
Why does FINI always return “Authorization in Input JSON is EMPTY”?
Please use protocol HTTP 1.1 instead of HTTP 2.0
2.
What encoding should be used for the Chinese Name in the EIPO Subscription Entries?
UTF-8
3.
I am using encoding UTF-8 as input source however the Chinese Characters still cannot be recorded by
FINI correctly. Unexpected Characters are found in the EIPO Subscription Entries result.
If participants use JAVA for their application development, please ensure the JVM handles the input source
UTF-8 flawlessly by checking if the JVM starts with parameter “-Dfile.encoding=UTF-8”.
4.
Is it a must to verify the remote Signature in HTTP Header X-FINI-SIGNATURE?
This is our recommendation for the Participants to detect if any tampered response.
5.
What is the purpose of Enquire EIPO Funding API?
If FINI BANK users would like to exercise the EIPO Funding Confirmation, corresponding record
transactionRef is the mandatory value that can only be obtained via Enquire EIPO Funding API.
6.
What should be done if there is “Time Out”/”No Response” situation for Add EIPO Subscription Entries
API request? Should I re-submit immediately?
Users have to verify if corresponding API requests are received and processed by FINI via FINI Portal (IPO
Card) or Enquire EIPO Subscription Entries API (by ipoID) before any re-try/re-submit action.
All those requests, having duplications, will be submitted and recorded in FINI but rejected only on the EIPO
Public Offer Close Day. Please refer to Section 9.4 Q7.
7.
Can I retrieve applicant’s allotment result via Enquire EIPO Subscription Entries API?
76
Yes. Enquire EIPO Subscription Entries API can show allotment quantity after the release of allotment
result.
77
Hong Kong Exchanges
and Clearing Limited
8/F, Two Exchange Square,
8 Connaught Place,
Central, Hong Kong
hkexgroup.com
|
hkex.com.hk
info@hkex.com.hk
T +852 2522 1122
F +852 2295 3106

 

 

 

 

 

 

 

 

 

 

//////////////////////////////////////////