# IAM Smart

## Hong Kong's eID

For further details, please refer to the official iAM Smart [API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).

### General Usage Flow

1. Send a request to your service of choice (Authentication, AnonymousForm Filling, Signing, etc.)
2. Send follow up request(s) to Poll Data to obtain the results.\*

\*As the data requires user approval, your system may have to short poll to obtain the results in a timely manner.

### Anonymous vs Authenticated Flow:

* Anonymous: No prior authentication needed, single-step process Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing
* Authenticated: Requires prior authentication, two-step process Examples: Form Filling, Signing, PDF Signing

### Multi-device user journey

There are 2 types of user journeys:

1. single device (mobile with iAM Smart installed)
2. two device (mobile with iAM Smart installed AND any second device)

The primary difference is that two device workflows typically includes displaying a iAM Smart website with a iAM Smart QR code that needs to be scanned to link the request across devices.

Implementation details are in the endpoints documentation.

## Authentication

> Initialize user authentication with iAM Smart eID service.\
> \
> \
> \*\*Browser Flow:\*\*\
> \
> Returns a TempAuthToken (store for subsequent calls) and a URL to iAM Smart's QR page.\
> User scans the QR code with their iAM Smart mobile app, then the browser redirects\
> to your specified redirect URL.\
> \
> \
> \*\*Mobile App Flow:\*\*\
> \
> Returns a universal link to launch the iAM Smart authentication app.\
> After authentication, iAM Smart returns an auth\_code via GET request to your redirect URI.\
> Your mobile app must handle this redirect URI and pass the auth\_code to the token endpoint.\
> \
> \
> \*\*Redirect URI Requirements:\*\*\
> \
> \- Browser: Must be an HTTPS URL registered with iAM Smart\
> \- Mobile: Must be a universal link or custom scheme (e.g., \`your-app\://auth\`)\
> &#x20; that your mobile app can handle<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"IamSmartLanguage":{"type":"string","description":"iAM Smart App display language\n","enum":["en-US","zh-HK","zh-CN"],"default":"en-US"},"IamSmartSource":{"type":"string","description":"The device platform and browser combination","enum":["PC_Browser","android","iOS","Android_Chrome","Android_Firefox","Android_Edge","Android_Samsung","Android_Huawei","Android_Xiaomi","iOS_Safari","iOS_Chrome","iOS_Firefox","iOS_Edge","iOS_IMS_InAppBrowser","Android_IMS_InAppBrowser"]},"RedirectUri":{"type":"string","description":"Redirect URI after user authorization.\n\nBrowser: https URL to your website.\n\nMobile: Universal link (your-app://) or app scheme.\n"},"IamSmartScope":{"type":"string","description":"Setting the scope is required only in cases where operations are chained, e.g auth + formfilling, auth + signing.\nBy default, the scope is set to the value required for the operation.\nRequested scope of authorization based on available services.\nMultiple scopes should be space-separated. Valid scopes are:\neidapi_auth, eidapi_profiles, eidapi_formFilling, eidapi_sign, eidapi_fr, eidapi_bulksign\n","pattern":"^(eidapi_auth|eidapi_profiles|eidapi_formFilling|eidapi_sign|eidapi_fr|eidapi_bulksign)(\\s+(eidapi_auth|eidapi_profiles|eidapi_formFilling|eidapi_sign|eidapi_fr|eidapi_bulksign))*$"},"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}},"responses":{"BadRequest":{"description":"Bad Request - Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Unauthorized - Token is missing, invalid, or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/iamsmart/v2/request/auth":{"post":{"tags":["iAM Smart"],"summary":"Authentication","description":"Initialize user authentication with iAM Smart eID service.\n\n\n**Browser Flow:**\n\nReturns a TempAuthToken (store for subsequent calls) and a URL to iAM Smart's QR page.\nUser scans the QR code with their iAM Smart mobile app, then the browser redirects\nto your specified redirect URL.\n\n\n**Mobile App Flow:**\n\nReturns a universal link to launch the iAM Smart authentication app.\nAfter authentication, iAM Smart returns an auth_code via GET request to your redirect URI.\nYour mobile app must handle this redirect URI and pass the auth_code to the token endpoint.\n\n\n**Redirect URI Requirements:**\n\n- Browser: Must be an HTTPS URL registered with iAM Smart\n- Mobile: Must be a universal link or custom scheme (e.g., `your-app://auth`)\n  that your mobile app can handle\n","operationId":"iamSmartAuthentication","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source","redirect"],"properties":{"lang":{"$ref":"#/components/schemas/IamSmartLanguage"},"source":{"$ref":"#/components/schemas/IamSmartSource"},"redirect":{"$ref":"#/components/schemas/RedirectUri"},"scope":{"$ref":"#/components/schemas/IamSmartScope"}}}}}},"responses":{"200":{"description":"Authentication request successfully initialized.\nStore the token for subsequent API calls.\n","content":{"application/json":{"schema":{"type":"object","required":["token","url"],"properties":{"token":{"$ref":"#/components/schemas/Token","description":"Store this token for subsequent API calls"},"url":{"type":"string","format":"uri","description":"Browser: URL to iAM Smart QR page for scanning.\nMobile: Universal link to launch iAM Smart app.\n"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## Form Filling

> Request form filling data from authenticated user.\
> \
> \
> Pass the form details, source, and AuthToken (from Authentication endpoint)\
> to initialize the form filling request.\
> \
> \
> Returns a temporary token to be used with Poll Data endpoint to retrieve\
> the requested form filling details.\
> \
> \
> \*\*Note on Profile Fields:\*\*\
> \
> If you request overlapping fields in both \`profileFields\` and \`formData.formFields\`,\
> the \`profileFields\` takes precedence. You must display a consent page per iAM Smart\
> UI/UX requirements when using profile fields.\
> \
> \
> \*\*Note on Form Fields:\*\*\
> \
> The \`formFields\` array specifies which detail fields to request from the user.\
> All requested fields will be displayed to the user in their iAM Smart app for approval.<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"},"IamSmartSource":{"type":"string","description":"The device platform and browser combination","enum":["PC_Browser","android","iOS","Android_Chrome","Android_Firefox","Android_Edge","Android_Samsung","Android_Huawei","Android_Xiaomi","iOS_Safari","iOS_Chrome","iOS_Firefox","iOS_Edge","iOS_IMS_InAppBrowser","Android_IMS_InAppBrowser"]},"ProfileFields":{"type":"array","description":"Mandatorily obtain specific profile fields.\nNote: You must display a consent page per iAM Smart UI/UX requirements when using these fields.\nIf fields overlap between `profileFields` and `formData.formFields`, `profileFields` takes precedence.\n","items":{"type":"string","enum":["idNo","enName","chName","birthDate","gender"]}},"FormData":{"type":"object","properties":{"formName":{"type":"string","description":"Form title displayed to user in iAM Smart app","maxLength":100},"formNum":{"type":"string","description":"Form reference code","maxLength":50},"formDesc":{"type":"string","description":"Form description displayed to user","maxLength":500},"formFields":{"type":"array","description":"Detail fields to request from user","items":{"type":"string","enum":["idNo","enName","chName","gender","prefix","maritalStatus","homeTelNumber","officeTelNumber","mobileNumber","emailAddress","residentialAddress","postalAddress","educationLevel","addressDocInfo","addressDocFile"]}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}},"responses":{"BadRequest":{"description":"Bad Request - Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Unauthorized - Token is missing, invalid, or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/iamsmart/v2/request/formfilling":{"post":{"tags":["iAM Smart"],"summary":"Form Filling","description":"Request form filling data from authenticated user.\n\n\nPass the form details, source, and AuthToken (from Authentication endpoint)\nto initialize the form filling request.\n\n\nReturns a temporary token to be used with Poll Data endpoint to retrieve\nthe requested form filling details.\n\n\n**Note on Profile Fields:**\n\nIf you request overlapping fields in both `profileFields` and `formData.formFields`,\nthe `profileFields` takes precedence. You must display a consent page per iAM Smart\nUI/UX requirements when using profile fields.\n\n\n**Note on Form Fields:**\n\nThe `formFields` array specifies which detail fields to request from the user.\nAll requested fields will be displayed to the user in their iAM Smart app for approval.\n","operationId":"iamSmartFormFilling","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","source","formData"],"properties":{"token":{"$ref":"#/components/schemas/Token","description":"The authenticated user token from the Authentication workflow"},"source":{"$ref":"#/components/schemas/IamSmartSource"},"profileFields":{"$ref":"#/components/schemas/ProfileFields"},"formData":{"$ref":"#/components/schemas/FormData"}}}}}},"responses":{"200":{"description":"Form filling request successfully initialized.\nPoll with the returned token to retrieve form data when ready.\n","content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"$ref":"#/components/schemas/Token","description":"Use this token in Poll Data to retrieve form filling results"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## Signing

> Request digital signature for a document hash using iAM Smart.\
> \
> \
> Pass the document details (name and SHA-256 hash), source platform, and the\
> authenticated user token to initialize the signing request.\
> \
> \
> Returns a temporary token and HKIC check digits. Use the token with the Poll Data\
> endpoint to retrieve the signature results after the user approves the signing\
> request in their iAM Smart app.\
> \
> \
> \*\*Hash Requirements:\*\*\
> \
> \- Must be a SHA-256 hash of the document content\
> \- Must be exactly 64 hexadecimal characters\
> \- Use SHA256withRSA signature algorithm (default)<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"},"IamSmartSource":{"type":"string","description":"The device platform and browser combination","enum":["PC_Browser","android","iOS","Android_Chrome","Android_Firefox","Android_Edge","Android_Samsung","Android_Huawei","Android_Xiaomi","iOS_Safari","iOS_Chrome","iOS_Firefox","iOS_Edge","iOS_IMS_InAppBrowser","Android_IMS_InAppBrowser"]},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}},"responses":{"BadRequest":{"description":"Bad Request - Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Unauthorized - Token is missing, invalid, or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/iamsmart/v2/request/signing":{"post":{"tags":["iAM Smart"],"summary":"Signing","description":"Request digital signature for a document hash using iAM Smart.\n\n\nPass the document details (name and SHA-256 hash), source platform, and the\nauthenticated user token to initialize the signing request.\n\n\nReturns a temporary token and HKIC check digits. Use the token with the Poll Data\nendpoint to retrieve the signature results after the user approves the signing\nrequest in their iAM Smart app.\n\n\n**Hash Requirements:**\n\n- Must be a SHA-256 hash of the document content\n- Must be exactly 64 hexadecimal characters\n- Use SHA256withRSA signature algorithm (default)\n","operationId":"iamSmartHashSigning","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","source","name","hash"],"properties":{"token":{"$ref":"#/components/schemas/Token","description":"The authenticated user token from the Authentication workflow"},"source":{"$ref":"#/components/schemas/IamSmartSource"},"name":{"type":"string","description":"Document title displayed to user","maxLength":200},"hash":{"type":"string","description":"SHA-256 hash of the document file's content (64 hex characters)","pattern":"^[a-f0-9]{64}$"},"service":{"type":"string","description":"Service description to be displayed to user","maxLength":200},"organisation":{"type":"string","description":"Organisation name","maxLength":200}}}}}},"responses":{"200":{"description":"Signing request successfully initialized.\nPoll with the returned token to get signature results.\n","content":{"application/json":{"schema":{"type":"object","required":["token","hkic"],"properties":{"token":{"$ref":"#/components/schemas/Token","description":"Use this token in Poll Data to retrieve signing results"},"hkic":{"type":"integer","description":"HKIC check digits for verification","minimum":1000,"maximum":9999}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## PDF Signing

> Request PDF document signing with embedded digital signature using iAM Smart.\
> \
> \
> Pass the PDF document details (name and base64-encoded hash), service description,\
> and the authenticated user token to initialize the PDF signing request.\
> \
> \
> Returns a temporary token and HKIC check digits. Use the token with the Poll Data\
> endpoint to retrieve the signed PDF after the user approves the signing request\
> in their iAM Smart app.\
> \
> \
> \*\*File Hash Requirements:\*\*\
> \
> \- Must be a base64-encoded hash of the PDF file\
> \- The signed PDF will be returned with the signature embedded\
> \- PDF signature will be visible in PDF readers that support digital signatures<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"},"IamSmartSource":{"type":"string","description":"The device platform and browser combination","enum":["PC_Browser","android","iOS","Android_Chrome","Android_Firefox","Android_Edge","Android_Samsung","Android_Huawei","Android_Xiaomi","iOS_Safari","iOS_Chrome","iOS_Firefox","iOS_Edge","iOS_IMS_InAppBrowser","Android_IMS_InAppBrowser"]},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}},"responses":{"BadRequest":{"description":"Bad Request - Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Unauthorized - Token is missing, invalid, or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/iamsmart/v2/request/pdf-signing":{"post":{"tags":["iAM Smart"],"summary":"PDF Signing","description":"Request PDF document signing with embedded digital signature using iAM Smart.\n\n\nPass the PDF document details (name and base64-encoded hash), service description,\nand the authenticated user token to initialize the PDF signing request.\n\n\nReturns a temporary token and HKIC check digits. Use the token with the Poll Data\nendpoint to retrieve the signed PDF after the user approves the signing request\nin their iAM Smart app.\n\n\n**File Hash Requirements:**\n\n- Must be a base64-encoded hash of the PDF file\n- The signed PDF will be returned with the signature embedded\n- PDF signature will be visible in PDF readers that support digital signatures\n","operationId":"iamSmartPdfSigning","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","source","name","fileHash","service"],"properties":{"token":{"$ref":"#/components/schemas/Token","description":"The authenticated user token from the Authentication workflow"},"source":{"$ref":"#/components/schemas/IamSmartSource"},"name":{"type":"string","description":"Document title displayed to user","maxLength":200},"fileHash":{"type":"string","description":"Base64-encoded hash of the PDF file","format":"byte"},"service":{"type":"string","description":"Service description to be displayed to user","maxLength":200},"hkicHash":{"type":"string","description":"Hash of HKIC for verification (optional)","pattern":"^[a-f0-9]{64}$"},"department":{"type":"string","description":"Department name (optional)","maxLength":100}}}}}},"responses":{"200":{"description":"PDF signing request successfully initialized.\nPoll with the returned token to retrieve signed PDF when ready.\n","content":{"application/json":{"schema":{"type":"object","required":["token","hkic"],"properties":{"token":{"$ref":"#/components/schemas/Token","description":"Use this token in Poll Data to retrieve PDF signing results"},"hkic":{"type":"integer","description":"HKIC check digits for verification","minimum":1000,"maximum":9999}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## Re-authentication

> Re-authenticate a previously authenticated user to verify their identity again.\
> \
> \
> Pass the authenticated user token and source platform to initialize the\
> re-authentication request. This is useful for high-security operations that\
> require fresh user verification.\
> \
> \
> Returns a temporary token. Use this token with the Poll Data endpoint to\
> retrieve the re-authentication results after the user approves the request\
> in their iAM Smart app.\
> \
> \
> \*\*Use Cases:\*\*\
> \
> \- Verify user identity before sensitive operations\
> \- Refresh user authentication for extended sessions\
> \- Comply with security policies requiring periodic re-verification<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"},"IamSmartSource":{"type":"string","description":"The device platform and browser combination","enum":["PC_Browser","android","iOS","Android_Chrome","Android_Firefox","Android_Edge","Android_Samsung","Android_Huawei","Android_Xiaomi","iOS_Safari","iOS_Chrome","iOS_Firefox","iOS_Edge","iOS_IMS_InAppBrowser","Android_IMS_InAppBrowser"]},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}},"responses":{"BadRequest":{"description":"Bad Request - Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Unauthorized - Token is missing, invalid, or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/iamsmart/v2/request/reauth":{"post":{"tags":["iAM Smart"],"summary":"Re-authentication","description":"Re-authenticate a previously authenticated user to verify their identity again.\n\n\nPass the authenticated user token and source platform to initialize the\nre-authentication request. This is useful for high-security operations that\nrequire fresh user verification.\n\n\nReturns a temporary token. Use this token with the Poll Data endpoint to\nretrieve the re-authentication results after the user approves the request\nin their iAM Smart app.\n\n\n**Use Cases:**\n\n- Verify user identity before sensitive operations\n- Refresh user authentication for extended sessions\n- Comply with security policies requiring periodic re-verification\n","operationId":"iamSmartReauthentication","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","source"],"properties":{"token":{"$ref":"#/components/schemas/Token","description":"The authenticated user token to re-validate"},"source":{"$ref":"#/components/schemas/IamSmartSource"}}}}}},"responses":{"200":{"description":"Re-authentication request successfully initialized.\nPoll with the returned token to get re-authentication results.\n","content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"$ref":"#/components/schemas/Token","description":"Use this token in Poll Data to check re-authentication status"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## POST /iamsmart/v2/request/ccic

> CCIC

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"}}},"paths":{"/iamsmart/v2/request/ccic":{"post":{"tags":["iAM Smart"],"summary":"CCIC","operationId":"ccic","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"$ref":"#/components/schemas/Token"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"token":{"type":"string"}}}}}}}}}}}
```

## Anonymous Form Filling

> Request form filling data without requiring prior authentication.\
> \
> This endpoint combines authentication and form filling in a single flow.\
> Pass the scope, language, source, redirect URL, and form details to initialize\
> the anonymous form filling request.\
> \
> Returns a token and URL. The URL redirects users to iAM Smart where they can\
> authenticate and approve the form filling request in one step.\
> \
> \*\*Note on Profile Fields:\*\*\
> \
> If you request overlapping fields in both \`profileFields\` and \`formData.formFields\`,\
> the \`profileFields\` takes precedence. You must display a consent page per iAM Smart\
> UI/UX requirements when using profile fields.<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"IamSmartLanguage":{"type":"string","description":"iAM Smart App display language\n","enum":["en-US","zh-HK","zh-CN"],"default":"en-US"},"IamSmartSource":{"type":"string","description":"The device platform and browser combination","enum":["PC_Browser","android","iOS","Android_Chrome","Android_Firefox","Android_Edge","Android_Samsung","Android_Huawei","Android_Xiaomi","iOS_Safari","iOS_Chrome","iOS_Firefox","iOS_Edge","iOS_IMS_InAppBrowser","Android_IMS_InAppBrowser"]},"RedirectUri":{"type":"string","description":"Redirect URI after user authorization.\n\nBrowser: https URL to your website.\n\nMobile: Universal link (your-app://) or app scheme.\n"},"IamSmartScope":{"type":"string","description":"Setting the scope is required only in cases where operations are chained, e.g auth + formfilling, auth + signing.\nBy default, the scope is set to the value required for the operation.\nRequested scope of authorization based on available services.\nMultiple scopes should be space-separated. Valid scopes are:\neidapi_auth, eidapi_profiles, eidapi_formFilling, eidapi_sign, eidapi_fr, eidapi_bulksign\n","pattern":"^(eidapi_auth|eidapi_profiles|eidapi_formFilling|eidapi_sign|eidapi_fr|eidapi_bulksign)(\\s+(eidapi_auth|eidapi_profiles|eidapi_formFilling|eidapi_sign|eidapi_fr|eidapi_bulksign))*$"},"ProfileFields":{"type":"array","description":"Mandatorily obtain specific profile fields.\nNote: You must display a consent page per iAM Smart UI/UX requirements when using these fields.\nIf fields overlap between `profileFields` and `formData.formFields`, `profileFields` takes precedence.\n","items":{"type":"string","enum":["idNo","enName","chName","birthDate","gender"]}},"FormData":{"type":"object","properties":{"formName":{"type":"string","description":"Form title displayed to user in iAM Smart app","maxLength":100},"formNum":{"type":"string","description":"Form reference code","maxLength":50},"formDesc":{"type":"string","description":"Form description displayed to user","maxLength":500},"formFields":{"type":"array","description":"Detail fields to request from user","items":{"type":"string","enum":["idNo","enName","chName","gender","prefix","maritalStatus","homeTelNumber","officeTelNumber","mobileNumber","emailAddress","residentialAddress","postalAddress","educationLevel","addressDocInfo","addressDocFile"]}}}},"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}},"responses":{"BadRequest":{"description":"Bad Request - Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Unauthorized - Token is missing, invalid, or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/iamsmart/v2/request/formfilling-anonymous":{"post":{"tags":["iAM Smart"],"summary":"Anonymous Form Filling","description":"Request form filling data without requiring prior authentication.\n\nThis endpoint combines authentication and form filling in a single flow.\nPass the scope, language, source, redirect URL, and form details to initialize\nthe anonymous form filling request.\n\nReturns a token and URL. The URL redirects users to iAM Smart where they can\nauthenticate and approve the form filling request in one step.\n\n**Note on Profile Fields:**\n\nIf you request overlapping fields in both `profileFields` and `formData.formFields`,\nthe `profileFields` takes precedence. You must display a consent page per iAM Smart\nUI/UX requirements when using profile fields.\n","operationId":"iamSmartAnonFormFilling","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source","redirect"],"properties":{"lang":{"$ref":"#/components/schemas/IamSmartLanguage"},"source":{"$ref":"#/components/schemas/IamSmartSource"},"redirect":{"$ref":"#/components/schemas/RedirectUri"},"scope":{"$ref":"#/components/schemas/IamSmartScope"},"profileFields":{"$ref":"#/components/schemas/ProfileFields"},"formData":{"$ref":"#/components/schemas/FormData"},"activityClass":{"type":["string","null"],"description":"Android activity class (required if source is android)"},"activityParams":{"type":["string","null"],"description":"Additional activity parameters (optional if source is android)"}}}}}},"responses":{"200":{"description":"Anonymous form filling request successfully initialized.\nRedirect user to the URL, then poll with the token to retrieve form data.\n","content":{"application/json":{"schema":{"type":"object","required":["token","url"],"properties":{"token":{"$ref":"#/components/schemas/Token"},"url":{"type":"string","format":"uri","description":"URL to redirect user for anonymous form filling"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## Anonymous Hash Signing

> Request digital signature for a document hash without requiring prior authentication.\
> \
> This endpoint combines authentication and signing in a single flow.\
> Pass the scope, language, source, redirect URL, and document details to initialize\
> the anonymous signing request.\
> \
> Returns a token, URL, and HKIC check digits. The URL redirects users to iAM Smart\
> where they can authenticate and approve the signing request in one step.\
> \
> \*\*Hash Requirements:\*\*\
> \
> \- Must be a SHA-256 hash of the document content\
> \- Must be exactly 64 hexadecimal characters<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"IamSmartLanguage":{"type":"string","description":"iAM Smart App display language\n","enum":["en-US","zh-HK","zh-CN"],"default":"en-US"},"IamSmartSource":{"type":"string","description":"The device platform and browser combination","enum":["PC_Browser","android","iOS","Android_Chrome","Android_Firefox","Android_Edge","Android_Samsung","Android_Huawei","Android_Xiaomi","iOS_Safari","iOS_Chrome","iOS_Firefox","iOS_Edge","iOS_IMS_InAppBrowser","Android_IMS_InAppBrowser"]},"RedirectUri":{"type":"string","description":"Redirect URI after user authorization.\n\nBrowser: https URL to your website.\n\nMobile: Universal link (your-app://) or app scheme.\n"},"IamSmartScope":{"type":"string","description":"Setting the scope is required only in cases where operations are chained, e.g auth + formfilling, auth + signing.\nBy default, the scope is set to the value required for the operation.\nRequested scope of authorization based on available services.\nMultiple scopes should be space-separated. Valid scopes are:\neidapi_auth, eidapi_profiles, eidapi_formFilling, eidapi_sign, eidapi_fr, eidapi_bulksign\n","pattern":"^(eidapi_auth|eidapi_profiles|eidapi_formFilling|eidapi_sign|eidapi_fr|eidapi_bulksign)(\\s+(eidapi_auth|eidapi_profiles|eidapi_formFilling|eidapi_sign|eidapi_fr|eidapi_bulksign))*$"},"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}},"responses":{"BadRequest":{"description":"Bad Request - Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Unauthorized - Token is missing, invalid, or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/iamsmart/v2/request/signing-anonymous":{"post":{"tags":["iAM Smart"],"summary":"Anonymous Hash Signing","description":"Request digital signature for a document hash without requiring prior authentication.\n\nThis endpoint combines authentication and signing in a single flow.\nPass the scope, language, source, redirect URL, and document details to initialize\nthe anonymous signing request.\n\nReturns a token, URL, and HKIC check digits. The URL redirects users to iAM Smart\nwhere they can authenticate and approve the signing request in one step.\n\n**Hash Requirements:**\n\n- Must be a SHA-256 hash of the document content\n- Must be exactly 64 hexadecimal characters\n","operationId":"iamSmartAnonHashSigning","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source","redirect","name","fileHash","service"],"properties":{"lang":{"$ref":"#/components/schemas/IamSmartLanguage"},"source":{"$ref":"#/components/schemas/IamSmartSource"},"redirect":{"$ref":"#/components/schemas/RedirectUri"},"scope":{"$ref":"#/components/schemas/IamSmartScope"},"name":{"type":"string","description":"Document title","maxLength":200},"fileHash":{"type":"string","description":"SHA-256 hash of document (64 hex characters)","pattern":"^[a-f0-9]{64}$"},"hkicHash":{"type":"string","description":"Hash of HKIC for verification","pattern":"^[a-f0-9]{64}$"},"service":{"type":"string","description":"Service description","maxLength":200},"organisation":{"type":"string","description":"Organisation name","maxLength":200}}}}}},"responses":{"200":{"description":"Anonymous signing request successfully initialized.\nRedirect user to the URL, then poll with the token to retrieve signature.\n","content":{"application/json":{"schema":{"type":"object","required":["token","url","hkic"],"properties":{"token":{"$ref":"#/components/schemas/Token"},"url":{"type":"string","format":"uri","description":"URL to redirect user for anonymous signing"},"hkic":{"type":"integer","description":"HKIC check digits","minimum":1000,"maximum":9999}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## Anonymous PDF Signing

> Request digital signature for a PDF document without requiring prior authentication. This endpoint enables anonymous PDF signing where users can sign documents using their iAM Smart identity without a separate authentication step.\
> \
> The response includes a URL to the iAM Smart QR code page and a temporary token. Users scan the QR code with their iAM Smart mobile app (for desktop) or are redirected to the iAM Smart app (for mobile). After signing, users are redirected to the specified redirect URL.\
> \
> \
> \*\*Use the temporary token\*\* with the polling endpoint to retrieve the signed document once the user completes the signing process.<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"IamSmartLanguage":{"type":"string","description":"iAM Smart App display language\n","enum":["en-US","zh-HK","zh-CN"],"default":"en-US"},"IamSmartSource":{"type":"string","description":"The device platform and browser combination","enum":["PC_Browser","android","iOS","Android_Chrome","Android_Firefox","Android_Edge","Android_Samsung","Android_Huawei","Android_Xiaomi","iOS_Safari","iOS_Chrome","iOS_Firefox","iOS_Edge","iOS_IMS_InAppBrowser","Android_IMS_InAppBrowser"]},"RedirectUri":{"type":"string","description":"Redirect URI after user authorization.\n\nBrowser: https URL to your website.\n\nMobile: Universal link (your-app://) or app scheme.\n"},"IamSmartScope":{"type":"string","description":"Setting the scope is required only in cases where operations are chained, e.g auth + formfilling, auth + signing.\nBy default, the scope is set to the value required for the operation.\nRequested scope of authorization based on available services.\nMultiple scopes should be space-separated. Valid scopes are:\neidapi_auth, eidapi_profiles, eidapi_formFilling, eidapi_sign, eidapi_fr, eidapi_bulksign\n","pattern":"^(eidapi_auth|eidapi_profiles|eidapi_formFilling|eidapi_sign|eidapi_fr|eidapi_bulksign)(\\s+(eidapi_auth|eidapi_profiles|eidapi_formFilling|eidapi_sign|eidapi_fr|eidapi_bulksign))*$"},"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}},"responses":{"BadRequest":{"description":"Bad Request - Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Unauthorized - Token is missing, invalid, or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/iamsmart/v2/request/pdf-signing-anonymous":{"post":{"tags":["iAM Smart"],"summary":"Anonymous PDF Signing","description":"Request digital signature for a PDF document without requiring prior authentication. This endpoint enables anonymous PDF signing where users can sign documents using their iAM Smart identity without a separate authentication step.\n\nThe response includes a URL to the iAM Smart QR code page and a temporary token. Users scan the QR code with their iAM Smart mobile app (for desktop) or are redirected to the iAM Smart app (for mobile). After signing, users are redirected to the specified redirect URL.\n\n\n**Use the temporary token** with the polling endpoint to retrieve the signed document once the user completes the signing process.\n","operationId":"iamSmartAnonPdfSigning","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source","redirect","name","fileHash","service"],"properties":{"lang":{"$ref":"#/components/schemas/IamSmartLanguage"},"source":{"$ref":"#/components/schemas/IamSmartSource"},"redirect":{"$ref":"#/components/schemas/RedirectUri"},"scope":{"$ref":"#/components/schemas/IamSmartScope"},"name":{"type":"string","description":"PDF document title","maxLength":200},"fileHash":{"type":"string","description":"Base64-encoded hash of PDF","format":"byte"},"hkicHash":{"type":"string","description":"Hash of HKIC for verification","pattern":"^[a-f0-9]{64}$"},"service":{"type":"string","description":"Service description","maxLength":200}}}}}},"responses":{"200":{"description":"Successfully initiated anonymous PDF signing request","content":{"application/json":{"schema":{"type":"object","required":["token","url","hkic"],"properties":{"token":{"$ref":"#/components/schemas/Token"},"url":{"type":"string","format":"uri"},"hkic":{"type":"integer","minimum":1000,"maximum":9999}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## Redirect

> iAM Smart redirects the user to this endpoint after completing the authentication\
> or service request flow. It processes the authorization code or error from\
> iAM Smart and again redirects to the client's specified redirect URL.<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[],"paths":{"/iamsmart/v2/redirect/user/{service}":{"get":{"tags":["iAM Smart"],"summary":"Redirect","description":"iAM Smart redirects the user to this endpoint after completing the authentication\nor service request flow. It processes the authorization code or error from\niAM Smart and again redirects to the client's specified redirect URL.\n","operationId":"iamSmartRedirect","parameters":[{"name":"code","in":"query","required":false,"description":"Authorization code from iAM Smart (present on success)","schema":{"type":"string"}},{"name":"error_code","in":"query","required":false,"description":"Error code from iAM Smart (present on failure/rejection)","schema":{"type":"string"}},{"name":"state","in":"query","required":false,"description":"State parameter used to match the request.","schema":{"type":"string"}},{"name":"businessID","in":"query","required":false,"description":"Business ID to identify the transaction. Not received if service is auth","schema":{"type":"string"}},{"name":"source","in":"query","required":false,"description":"Source platform (optional)","schema":{"type":"string"}}],"responses":{"302":{"description":"Redirect to client application"},"400":{"description":"Bad Request - Missing required parameters or invalid service","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Poll Data

> Used for all iAM Smart services to poll for final results after user action.\
> \
> Short poll this endpoint, passing in the \`token\` (from any iAM Smart endpoint) to obtain the results.\
> \
> The response's \`token\` is a JWT or JWE depending if there's sensitive personal data. You should handle them like so:\
> \
> \- \`JWT\` verify\\\* token\
> &#x20;   \
> \- \`JWE\` decrypt using the private keys that Fill Easy has previously provided.\
> &#x20;   \
> Please note that the data result is returned only once and is deleted immediately.\
> \
> \\\*you can try using online decoder like \[<https://jwt.io/]\\(https://jwt.io/)>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}}},"paths":{"/iamsmart/v2/callback/client":{"post":{"tags":["iAM Smart"],"summary":"Poll Data","description":"Used for all iAM Smart services to poll for final results after user action.\n\nShort poll this endpoint, passing in the `token` (from any iAM Smart endpoint) to obtain the results.\n\nThe response's `token` is a JWT or JWE depending if there's sensitive personal data. You should handle them like so:\n\n- `JWT` verify\\* token\n    \n- `JWE` decrypt using the private keys that Fill Easy has previously provided.\n    \nPlease note that the data result is returned only once and is deleted immediately.\n\n\\*you can try using online decoder like [https://jwt.io/](https://jwt.io/)","operationId":"pollData","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"},"code":{"type":"string"},"error_code":{"type":"string"}}}}}},"responses":{"200":{"description":"Returns the final result with personal information, encoded in a JWE token.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"token":{"type":"string"}}}}}},"202":{"description":"Result Pending, user has not completed the action","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"299":{"description":"User rejected the request","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"description":"User rejected the request","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"410":{"description":"Personal data is deleted after 18 minutes / after first successful poll","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}}}}}}}
```

## Direct Login v2 Exchange

> Exchange an iAM Smart Direct Login v2 authCode for a Fill Easy authentication token.\
> Used by both the web variant (\`code\` is received\
> from iAM Smart in query parameters) and the app-to-app variant (\`code\` +\
> PKCE \`codeVerifier\` received from the deeplink).\
> \
> The client owns its iAM Smart-registered callback URL or deeplink target; Fill Easy\
> only handles the credential exchange.\
> \
> Only Direct Login V2 is supported.<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"iAM Smart","description":"# Hong Kong's eID\n\nFor further details, please refer to the official iAM Smart\n[API Specification](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_API_Specification_v2.5.2.pdf) and  [Developer Guide](https://iamsmart.cyberport.hk/wp-content/uploads/iAM_Smart_Developer_Guide_v2.3.1.pdf).\n\n## General Usage Flow\n\n1. Send a request to your service of choice (Authentication, AnonymousForm Filling,\nSigning, etc.)\n\n2. Send follow up request(s) to Poll Data to obtain the results.*\n\n\n*As the data requires user approval, your system may have to short poll\nto obtain the results in a timely manner.\n\n## Anonymous vs Authenticated Flow:\n\n- Anonymous: No prior authentication needed, single-step process\n  Examples: Anonymous Form Filling, Anonymous Signing, Anonymous PDF Signing\n\n- Authenticated: Requires prior authentication, two-step process\n  Examples: Form Filling, Signing, PDF Signing\n\n## Multi-device user journey\n\nThere are 2 types of user journeys:\n\n  1. single device (mobile with iAM Smart installed)\n\n  2. two device (mobile with iAM Smart installed AND any second device)\n\nThe primary difference is that two device\nworkflows typically includes displaying a iAM Smart website with a iAM\nSmart QR code that needs to be scanned to link the request across devices.\n\nImplementation details are in the endpoints documentation.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"responses":{"BadRequest":{"description":"Bad Request - Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Unauthorized - Token is missing, invalid, or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalServerError":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}},"paths":{"/iamsmart/v2/direct-login/exchange":{"post":{"tags":["iAM Smart"],"summary":"Direct Login v2 Exchange","description":"Exchange an iAM Smart Direct Login v2 authCode for a Fill Easy authentication token.\nUsed by both the web variant (`code` is received\nfrom iAM Smart in query parameters) and the app-to-app variant (`code` +\nPKCE `codeVerifier` received from the deeplink).\n\nThe client owns its iAM Smart-registered callback URL or deeplink target; Fill Easy\nonly handles the credential exchange.\n\nOnly Direct Login V2 is supported.\n","operationId":"iamSmartDirectLoginExchange","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string","description":"Authorization code from iAM Smart (single use, valid 30 seconds)"},"codeVerifier":{"type":"string","description":"PKCE code verifier received by the client app from iAM Smart. App-to-app\nvariant only — must be omitted for the web variant.\n"}}}}}},"responses":{"200":{"description":"Authentication success","content":{"application/json":{"schema":{"type":"object","required":["message","token"],"properties":{"message":{"type":"string"},"token":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fill-easy.com/iam-smart.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
