Project

General

Profile

Onboarding Foreign API Spc » History » Revision 7

Revision 6 (Ryan Supawarapong, 03/05/2026 02:20 AM) → Revision 7/12 (Ryan Supawarapong, 03/05/2026 02:52 AM)

# Onboarding Foreign API Spc 

 ## 1. Pre-Create (Fullname) 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/individual/ico/precreate` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | title | string | `"Mr."` | yes | 
 | name | string | `"John"` | yes | 
 | surname | string | `"Doe"` | yes | 
 | email | string | `"john@doe.com"` | yes | 
 | mobile | string | `"0987654321"` | yes | 
 | birthDate | string (ISO 8601) | `"1990-01-01T00:00:00Z"` | yes | 
 | marriageStatus | string | `"Single"` | yes | 
 | nationality | string | `"USA"` | yes | 
 | passportNumber | string | `"AC123435"` | yes | 
 | expirationDate | string (ISO 8601) | `"2030-01-01T00:00:00Z"` | yes | 
 | agreement | boolean | `true` | yes | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"success"` | yes | 
 | data | object | `{"registerId":"..."}` | yes | 
 | data.registerId | string | `"registerId"` | no (`omitempty`) | 
 | data.alreadyExist | boolean | `true` | no (`omitempty`) | 
 | xid | string | `"xRequestId"` | yes | 

 ### Error Response 

 #### Bad Request (400) — bind/validate/usecase error 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"failed"` or `"error"` | yes | 
 | message | string | `"error message"` | no | 
 | data | object | `{"errors":[...]}` | no (validation) | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 2. Back to Register 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/individual/ico/backregister` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | passportNumber registerId | string | `"AC1234"` `"registerId"` | yes no | 
 | citizenId | string | `"1234567890123"` | no | 
 | name | string | `"John"` | no | 
 | taxId | string | `"TAX123"` | no | 
 | dateFrom | string (ISO 8601) | `"2024-01-01T00:00:00Z"` | no | 
 | dateTo | string (ISO 8601) | `"2025-01-01T00:00:00Z"` | no | 
 | page | number | `1` | no | 
 | pageSize | number | `10` | no | 
 | sessionId | string | `"session-id"` | no | 
 | icoCode | string | `"ICO001"` | no | 
 | staus | number | `1` | no | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | response | object | existing customer info object | yes | 
 | xid | string | `"xRequestId"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"error message"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 3. Init Appman 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/appman/init/:registerId` | 
 | Request Type | `GET` | 
 | Content-Type | `application/json` | 

 ### Query Parameters 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | registerId | string | `"registerId-12345"` | yes | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | - | - | - | no body | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | redirect_url | string | `"https://appman.test"` | yes | 
 | xid | string | `"xRequestID"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"registerId is required"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 

 ## 4. Get Result Appman 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/appman/result` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 _Not yet implemented._ 

 ### Response 

 *** 

 

 ## 5. Submit CRS 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/individual/ico/crs` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | registerId | string | `"registerId"` | yes | 
 | crs | array\<object\> | `[{"member_id":"...","is_tax_not_usa":true,...}]` | yes | 
 | crs[].member_id | string | `"member-001"` | no | 
 | crs[].is_tax_not_usa | boolean | `true` | no | 
 | crs[].country_tax_residence | string | `"US"` | no | 
 | crs[].is_tin | boolean | `true` | no | 
 | crs[].tin | string | `"123456789"` | no | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | xid | string | `"xRequestId"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"error message"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 6. Post-Create (Basic Info — Create) 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/individual/ico/postcreate` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | registerId | string | `"registerId"` | yes | 
 | addresses | array\<object\> | see below | no | 
 | addresses[].homeNumber | string | `"homeNumber"` | yes | 
 | addresses[].villageNumber | string | `"homeAddress"` | no | 
 | addresses[].villageName | string | `"villageName"` | no | 
 | addresses[].subStreetName | string | `"subStreetName"` | no | 
 | addresses[].streetName | string | `"homeAddress"` | no | 
 | addresses[].subDistrictName | string | `"ตลาดยอด"` | yes | 
 | addresses[].districtName | string | `"เขตมีนบุรี"` | yes | 
 | addresses[].provinceName | string | `"ตราด"` | yes | 
 | addresses[].zipCode | string | `"10400"` | yes | 
 | addresses[].countryName | string | `"หมู่เกาะอะแลนด์"` | yes | 
 | addresses[].types | number | `1` | yes | 
 | occupation | object | see below | no | 
 | occupation.education | string | `"2"` | no | 
 | occupation.sourceOfIncome | string | `"3"` | no | 
 | occupation.currentOccupation | string | `"4"` | no | 
 | occupation.officeName | string | `"tisco"` | no | 
 | occupation.typeOfBusiness | string | `"6"` | no | 
 | occupation.positionName | string | `"tisco"` | no | 
 | occupation.salaryRange | string | `"3"` | no | 
 | banks | array\<object\> | see below | no | 
 | banks[].bankName | string | `"ธนาคารไทยพาณิชย์"` | no | 
 | banks[].bankBranchName | string | `"ธนาคารไทยพาณิชย์"` | no | 
 | banks[].bankAccountNumber | string | `"12345"` | no | 
 | banks[].types | number | `1` | no | 
 | banks[].isDefault | boolean | `true` | no | 
 | investment | object | see below | no | 
 | investment.shortTermInvestment | boolean | `true` | no | 
 | investment.longTermInvestment | boolean | `false` | no | 
 | investment.taxesInvestment | boolean | `true` | no | 
 | investment.retireInvestment | boolean | `true` | no | 
 | pageID | number | `100` | yes | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | registerId | string | `"registerId"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"error message"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 7. Update Post (Basic Info — Edit) 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/individual/ico/update/post` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 _Same as [6. Post-Create](#6-post-create-basic-info--create)._ 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | registerId | string | `"registerId"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"error message"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 8. Suite Test — Save 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/suitetest/ico/result/individual/save` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | registerId | string | `"registerId"` | yes | 
 | suiteTestResult | object | see below | no | 
 | suiteTestResult.registerId | string | `"registerId"` | yes | 
 | suiteTestResult.investorTypeRisk | string | `"เสี่ยงปานกลางค่อนสูง"` | no | 
 | suiteTestResult.level | number | `3` | no | 
 | suiteTestResult.totalScore | number | `24` | no | 
 | suiteTestResult.suiteTestResult | object | `{"answer":{"0":{"ans":[0,1,0,0]},...}}` | no | 
 | isFatca | boolean | `true` | no | 
 | fatcaInfo | array\<number\> | `[1,0,1,0,1,0,1,0]` | no | 
 | isKnowLedgeDone | boolean | `true` | no | 
 | knowLedgeTestResult | number | `15` | no | 
 | pageId | number | `600` | no | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | xid | string | `"xRequestId"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"error message"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 9. Suite Test — Edit 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/suitetest/ico/result/individual/edit` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 _Same as [8. Suite Test — Save](#8-suite-test--save)._ 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | xid | string | `"xRequestId"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"error message"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 10. Upload Onboarding Document 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/upload/onboarding` | 
 | Request Type | `POST` | 
 | Content-Type | `multipart/form-data` | 

 ### Request Body (form fields) 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | register_id | string | `"register-id-123"` | yes | 
 | type | integer (enum) | `3` | yes | 
 | doc_types | string (comma-separated) | `"country_origin_govt,proof_resident_thai"` | yes | 
 | files | file(s) | binary | yes | 

 **`type` enum values:** 

 | Value | Meaning | Allowed `doc_types` | 
 |---|---|---| 
 | `1` | Work Permit | `work_permit` | 
 | `2` | Visa | `visa_or_smart_visa` | 
 | `3` | Document by Origin Govt | `country_origin_govt`, `proof_resident_thai` | 
 | `4` | Document by Thai Govt | `proof_resident_thai` | 

 **Constraints:** 
 - Max 4 files per `doc_type` (types 1, 2, 4) 
 - Type 3 allows max 8 files total (up to 4 `country_origin_govt` + up to 4 `proof_resident_thai`) 
 - Max 10 MB per file, 80 MB total 
 - Number of `doc_types` values must match number of uploaded files 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"success"` | yes | 
 | message | string | `"success"` | yes | 
 | xid | string | `"xRequestID"` | yes | 

 ### Error Response 

 #### Bad Request (400) — validation error 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"failed"` or `"error"` | yes | 
 | message | string | `"files field is required"` | no | 
 | data | object | `{"error":"..."}` | no | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 11. Verify Email (Send) 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/user/verify/email` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | registerId | string | `"register-id-123"` | no | 
 | tokenId | string | `"token-id-123"` | yes | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | xid | string | `"xRequestID"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"verify email failed"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 12. Confirm Email (Check) 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/user/verify/email/check` | 
 | Request Type | `GET` | 
 | Content-Type | `application/json` | 

 ### Query Parameters 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | token | string | `"token-id-123"` | yes | 
 | code | string | `"register-id-123"` | yes | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | - | - | - | no body | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | data | string | `"confirmed"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"error message"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 13. Mobile Verify (Send OTP) 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/user/verify/mobile` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | registerId | string | `"registerId"` | yes | 
 | referenceCode | string | `"REF123"` | no | 
 | otp | string | `"123456"` | no | 
 | mobile | string | `"0987654321"` | no | 
 | isUpdate | boolean | `false` | no | 
 | pageId | number | `1600` | no | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | reference | string | `"AB1234"` | yes | 
 | xid | string | `"xRequestID"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"error message"` | yes | 
 | xid | string | `"xRequestId"` | yes | 

 --- 

 ## 14. Confirm Mobile (Verify OTP) 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/foreign/user/verify/mobile/check` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | registerId | string | `"registerId"` | yes | 
 | referenceCode | string | `"AB1234"` | no | 
 | otp | string | `"123456"` | no | 
 | mobile | string | `"0987654321"` | no | 
 | isUpdate | boolean | `false` | no | 
 | pageId | number | `1600` | no | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | xid | string | `"xRequestId"` | yes | 

 ### Error Response 

 #### Bad Request (400) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | message | string | `"error message"` | yes | 
 | xid | string | `"xRequestId"` | yes |