Onboarding Foreign API Spc » History » Revision 5
Revision 4 (Ryan Supawarapong, 03/05/2026 02:13 AM) → Revision 5/12 (Ryan Supawarapong, 03/05/2026 02:14 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 |
|---|---|---|---|
| registerId | string | `"registerId"` | 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
(501 — Not Implemented)
| JSON Path | Type | Example | Required |
|---|---|---|---|
| message | string | `"get result appman not implemented"` | yes |
| xid | string | `"xRequestId"` | yes |
---
## 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 |