User operations





Introduction


Once you are registered as a client in ioCash, you can start creating accounts for your users so that they can start using the service.




Operations

Create a user


The first interaction you have to do with the API is to create a user. There are two types of users you can create: individual persons (natural users) and companies (juridical users). Depending on the type of clients your business has you will need to create ones or the others. Also, you can create a user in an specific network associated to your client. The POST requests you need to call are:

HTTP Request


POST /api/v2/public/users/natural


POST /api/v2/public/users/juridical


With the following information provided as JSON for natural users:


{
  “userName”: “johndoe”,
  “firstName”: “John”,
  “lastName”: “Doe”,
  “email”: “johndoe@example.com”,
  “mobilePhone”: “+34612345678”,
  “dltAddress”: “0xSUF9AS84DS4ADVFFSDDDSSA92SFA0AxAFDS9DD4FAF”,
  “dltNetwork”: “AlastriaTelsius”
  }
  

and the following for juridical users:


{
  “userName”: “CompanyA”,
  “companyName”: “CompanyA”,
  “email”: “companya@example.com”,
  “mobilePhone”: “+34612345678”,
  “dltAddress”: “0xSUF9AS84DS4ADVFFSDDDSSA92SFA0AxAFDS9DD4FAF”,
  “dltNetwork”: “AlastriaTelsius”
  }
  

Request body parameters


Parameter Mandatory Datatype Description
userName yes string A freely chosen identification for the user
firstName yes string The first name of the user. Only for Natural person
lastName yes string The last name of the user. Only for Natural person
companyName yes string The last name of the user. Only for Juridical person
email no string The email address of the user
mobilePhone yes string A Spanish mobile phone number
dltAddress yes string The Ethereum address of the user.
The client can either use an already existing address, if the user provides it, or create a new one.
dltNetwork no string The Ethereum network of the user.
Has to be one of the associated networks of the client. When not provided the client default network will be used.

As response, you will get the following JSON object:


{
  “id”: “91af1cb8-1caa-47d0-8ef8-2c11948baaba”,
  “companyName”: “null”
  “email”: “johndoe@example.com”,
  “firstName”: “John”,
  “lastName”: “Doe”,
  “mobilePhone”: “+34612345678”,
  “status”: “PENDING”,
  “userName”: “johndoe”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
id string The UUID of the created user. You will need it for future requests
companyName string The company name of the user created. If it is a natural user it appears as null
email string The value which was provided in the request
firstName string The value which was provided in the request. If it is a juridical user it appears as null
lastName string The value which was provided in the request. If it is a juridical user it appears as null
mobilePhone string The value which was provided in the request
status string The status can be either PENDING_VERIFICATION, VERIFIED or ACTIVATED.
userName string The value which was provided in the request

From this JSON it is important that you save the id of the user, in the above example: 91af1cb8-1caa-47d0-8ef8-2c11948baaba. You will need the user ID for future requests.

When you create the new user, an IoCash wallet will be generated with the provided DLT address and a new IBAN associated to it. To get this generated wallet ID, please refer to Get wallet




Update a user


In order to update basic info of the users like first name, last name and/or username you have to call the following requests depending if the user to be updated is natural or juridical.


HTTP Request


PATCH /api/v2/public/users/natural/{userId}

PATCH /api/v2/public/users/juridical/{userId}

In our example, the whole request will be PATCH /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/natural

With the following information provided as JSON:


{
  “firstName”: “newFirstName”,
  “lastName”: “newLastName”,
  “userName”: “newUserName”
  }
  

If you only want to update one of the fields you only have to send this one in the request.


Additionally, the telephone number of a user can be updated, only if the user is still in status PENDING_VERIFICATION. This endpoint has been enabled for the case in which the user introduces a wrong phone number and he/she cannot pass the verification process -usually an OTP sms-. With this request he/she can change it without the need of creating a whole new user.

HTTP Request


PATCH /api/v2/public/users/natural/{userId}/mobile-phone

PATCH /api/v2/public/users/juridical/{userId}/mobile-phone

In our example, the whole request will be PATCH /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/mobile-phone

With the following information provided as JSON:


{
  “mobilePhone”: “newMobilePhone”
  }
  



Get user info


To get the information of a natural or juridical user you can make the following requests using the id of the user.


HTTP Request


GET /api/v2/public/users/natural/{userId}

GET /api/v2/public/users/juridical/{userId}

In our example, the whole request would be GET /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba

And as response, we would get the following JSON object:


{
  “id”: “91af1cb8-1caa-47d0-8ef8-2c11948baaba”,
  “email”: “johndoe@example.com”,
  “firstName”: “John”,
  “lastName”: “Doe”,
  “mobilePhone”: “+34612345678”,
  “status”: “ACTIVATED”,
  “userName”: “johndoe”
  }
  




Get user list


If you want to get the list of all the users in your system, you can make the following requests:


HTTP Request


GET /api/v2/public/users/ will give you as response a JSON array with the information of the common fields for all the juridical and natural users existing in your system. The response will include for each user a Hateoas link to get the specific information for its type of user.

Additionnally, you can also retrieve all the natural users you by using:

GET /api/v2/public/users/natural

and for getting the juridicals:

GET api/v2/public/users/juridical.


If you want to try any of these functionalities yourself and learn more about them, please go to the API catalogue





KYC transitions


In order to operate in ioCash, users have to be KYCed - pass identity verification processes. Following what is stipulated in the Electronic Money License, there are different levels of KYC that define the operation limits users have. The operation limits for each level of KYC are shown in the tablebelow.


kyc-levels

Both natural and juridical users can use the HTTP requests to reach KYC 0. However all the other HTTP requests described below for the rest of KYC levels (1, 2 and 3) are specific for natural users. For transitioning juridical users to higher KYC levels we follow a manual process. Please contact our support team to to be guided through this process.

KYC level 0


To reach KYC level 0, users have to verify their telephone number. In order to do so they have to do two calls to our API: one requesting a One Time Password (OTP) and another one verifying it.

To request the OTP:


HTTP Request


POST /api/v1/public/users/{userId}/request-otp

In our example, the whole request would be POST /api/v1/public/users/91af1cb8-1caa-47d0-8ef8-2c11948baaba/request-otp

And as response, we would get the following JSON object:


{
  “expirationTime”: “2019-07-31T10:36:02.499Z”,
  “status”: “PEN”,
  “type”: “T”,
  “verificationId”: “4bFaa68nSGi9pRTogcZE”
  }
  

Where:

HTTP Response parameters



Parameter Datatype Description
expirationTime date Date when the code will be expired
status string Status of the code. It can be PEN for pending, VER for verified, CAD for expired or ERR for error.
type string Type of the verification code. It can be T for telephone or E for email. In this case it will always take the T value.
verificationId string Internal system id for the code

Once the request succeeds, an sms will be directly sent to the user with the OTP. The user will have to send us back this OTP using the following request to verify that he/she is in possession of his/her mobile phone.


HTTP Request


POST /api/v1/public/users/{userId}/validate-otp

In our example, the whole request would be POST /api/v1/public/users/91af1cb8-1caa-47d0-8ef8-2c11948baaba/validate-otp

With the following information provided as JSON:


{
  “otp”: “1111”
  }
  

Where:

Request body parameters


Parameter Mandatory Datatype Description
otp Yes string Code sent to the user via sms.


And as response, we would get the following JSON object:


{
  “expirationTime”: “2019-07-31T10:36:02.499Z”,
  “status”: “VER”,
  “type”: “T”,
  “verificationId”: “4bFaa68nSGi9pRTogcZE”
  “verificationTime”: “2019-07-31T10:36:02.575Z”
  }
  


Where:

HTTP Response parameters


Parameter Datatype Description
expirationTime date Date when the code will be expired
status string Status of the code. It can be PEN for pending, VER for verified, CAD for expired or ERR for error.
type string Type of the verification code. It can be T for telephone or E for email. In this case it will always take the T value.
verificationId string Internal system id for the code
verificationTime Date Date when the verification was done.

KYC level 1


To reach KYC level 1, users have to verify their identity. They have to first provide some data about their identity card and then verify it with a video. To pass the identity data, you have to use the following request:


HTTP Request


POST /api/v2/public/users/natural/{userId}/identity

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/identity

With the following information provided as JSON:



  {
  “nationality”: “ES”,
  “identityType”: “DNI”,
  “identityNumber”: “92659479T”,
  “birthDate”: “13-08-1985”
  “issueDate”: “12-08-2010”,
  “expiryDate”: “13-08-2020”
  }
  

Where:

Request body parameters


Parameter Mandatory Datatype Description
nationality Yes string Two-letter country code based on ISO 3166.
identityType Yes string Can be DNI or PAS for passport.
identityNumber Yes string Identity card or passport number.
birthDate No date ISO 8601 date without time.
issueDate No date Identity card or passport issue date. ISO 8601 date without time.
expiryDate No date Identity card or passport expiry date. ISO 8601 date without time.

And as response, we would get the following JSON object:



  {
  “id”: “91af1cb8-1caa-47d0-8ef8-2c11948baaba”,
  “nationality”: “ES”,
  “identityType”: “DNI”,
  “identityNumber”: “92659479T”,
  “birthDate”: “13-08-2021”
  “issueDate”: “12-08-2010”,
  “expiryDate”: “13-08-2021”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
id UUID User id.
nationality string User identity nationalty.
identityType string User identity type.
identityNumber string User identity number.
birthDate date User birth date.
issueDate date User identity card or passport issue date.
expiryDate date User identity card or passport expiry date.

Next step is to verify the identity with a video verification process. To do so you have to do the following request to to obtain the url that will direct them to the video process.


HTTP Request


POST /api/v2/public/users/natural/{userId}/verify-identity

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/verify-identity

With the following information provided as JSON:



  {
  “successUrl”: “https://io.cash",
  “failureUrl”: “https://io.cash"
  }
  

Where:

Request body parameters


Parameter Mandatory Datatype Description
successUrl No string Callback url if the verification goes success
failureUrl No string Callback url if the verification goes wrong

And as response, we would get the following JSON object:



  {
  “url”: “https://identificacion.zonadeprueba.es?token=sfVMSgLPASauZQvoQ7NAxvDjXwbd3X1nwMVm32QLV7znMZWziCrp2KYHwfooUHQV9Y1wAbN9so3KGb5fLM2fz2nNmCpKRgRwek7b3WV6FcJb&lang=es"
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
url string Url to perform the identity verification process via video.

Once the video process is completed, if the introduced user identity data matches the identity card or passport data captured with the video, the user will be directly transited to KYC level 1. The transition of KYC level can take up to 1 minute. If you do not want to wait for that long you can use the following request:


HTTP Request


GET /api/v2/public/users/natural/{userId}/identity

In our example, the whole request would be GET /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/identity

If as response you get that the status of the ID is in VERIFIED, it means that the verification process has been successful. Otherwise, you can do two things: either continue calling our API doing polling, or you can subscribe to the KycLevelSetToUser event of our smart contract that it is emitted when the user changes KYC level. If after 5 minutes, the status of the ID has not changed or the event has not been released, it means that there was a problem on the verification process and the user has to repeat it again.

In addition, when the identity of the user is verified by one of our expert verificators, the user will pass to level KYC 2, if all the rest of the information is completed (see next subsection).

KYC level 2


In order to reach KYC level 2, apart of having the idenitity video verified by one of our experts verificators, users have to provide us the following information: home address, occupation, income level and external account IBAN bumber and proof file. To do so, we have enabled several API endpoints:


Home address

The home address is formed by several fields that have to be passed using the following request:


HTTP Request


POST /api/v2/public/users/natural/{userId}/home-address

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/home-address

With the following information provided as JSON:



  {
  “countryCode”: “ES”,
  “province”: “Madrid”,
  “city”: “Pozuelo de Alarcón”,
  “address”: “Parque Científico y Tecnológico UPM Campus de Montegancedo s/n”,
  “postalCode”: “28223”
  }
  

Where:

Request body parameters


Parameter Mandatory Datatype Description
countryCode Yes string Two-letter country code based on ISO 3166.
province Yes string Home address country province.
city Yes string Home address city.
address Yes string Home address. Can include street, number and so on.
postalCode Yes string Home address postal code.

And as response, we would get the following JSON object:



  {
  “id”: “91af1cb8-1caa-47d0-8ef8-2c11948baaba”,
  “countryCode”: “ES”,
  “province”: “Madrid”,
  “city”: “Pozuelo de Alarcón”,
  “address”: “Parque Científico y Tecnológico UPM Campus de Montegancedo s/n”,
  “postalCode”: “28223”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
id UUID User id
countryCode String Home address country
province String Home address province
city String Home address city
address String Home address
postalCode String Home address postal code

PUT method can be used to update the information once it is filled for the first time.


Occupation

Users have to add their occupation code, based on the the following list of the goverment of Spain: Occupation codes.


HTTP Request


POST /api/v2/public/users/natural/{userId}/occupation

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/occupation

With the following information provided as JSON:



  {
  “occupationCode”: “1211”,
  }
  

Where:

Request body parameters


Parameter Mandatory Datatype Description
occupationCode Yes string Valid occupation code.

And as response, we would get the following JSON object:



  {
  “id”: “91af1cb8-1caa-47d0-8ef8-2c11948baaba”,
  “occupationCode”: “1211”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
id UUID User id
occupationCode String User occupation code

PUT method can be used to update the information once it is filled for the first time.


Income level

Possible levels are A, B, C or D.

HTTP Request


POST /api/v2/public/users/natural/{userId}/financial-information

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/financial-information

With the following information provided as JSON:



  {
  “incomeLevel”: “A”,
  }
  

Where:

Request body parameters


Parameter Mandatory Datatype Description
incomeLevel Yes string Code of the different income levels ranges:
A: less than 100,000 €
B: between 100,001 and 600,000 €
C: between 600,001 and 1,200,000 €
D: above 1,200,000 €

And as response, we would get the following JSON object:



  {
  “id”: “91af1cb8-1caa-47d0-8ef8-2c11948baaba”,
  “incomeLevel”: “A”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
id UUID User id
incomeLevel String User income level

PUT method can be used to update the information once it is filled for the first time.


External Account

Users need to prove they own an external IBAN account. For this, 2 API calls are needed, one to provide the IBAN number and the other to upload a document that proves they are the owner of the account (e.g. bank recepit).

HTTP Request


POST /api/v2/public/users/natural/{userId}/iban

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/iban

With the following information provided as JSON:



  {
  “iban”: “ES9621001464407281768591”,
  }
  

Where:

Request body parameters


Parameter Mandatory Datatype Description
iban Yes string Valid IBAN number.

And as response, we would get the following JSON object:



  {
  “id”: “91af1cb8-1caa-47d0-8ef8-2c11948baaba”,
  “iban”: “ES9621001464407281768591”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
id UUID User id
iban String User external account IBAN.

PUT method can be used to update the information once it is filled for the first time.


For uploading the file that proves that the user owns the submitted IBAN number you have to do the following request:


HTTP Request


POST /api/v2/public/users/natural/{userId}/iban-file

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/iban-file

The request should be a multipart request with a part called “file”.


Where:

Request body parameters


Parameter Mandatory Datatype Description
file Yes Multipart request file part The file should not exceed 50mb size. Supported file formats are png, jpg, jpeg and pdf.

And as response, we would get the following JSON object:



  {
  “id”: “91af1cb8-1caa-47d0-8ef8-2c11948baaba”,
  “fileVersion”: “Jbz2jvozyXXvHrTAm06x2wb0kxVg04Yl”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
id UUID User id
fileVersion String File version.

PUT method can be used to update file once it has been uploaded for the first time.


After all information has been validated, the user KYC level is changed to 2.


KYC level 3


In order to reach KYC level 3, users have to provide us with their last year income tax document, and sign a KYC terms document that is automatically created by our Electronic Money Entity when the user reaches KYC level 2. The KYC document contains a summary of the personal information introduced to reach level 2. With the signature of the document, the user confirms that all this data is correct. For these functionalities we have enabled several API endpoints:


KYC document

To download and see the KYC document the client has to do the following request:


HTTP Request


GET /api/v2/public/users/natural/{userId}/kyc-file

In our example, the whole request would be GET /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/kyc-file. The document will only be available if the user is in KYC level 2 or higher.


And as response, we would get the file



  {
  “file”: “{file}”,
  “name”: “kyc.pdf”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
file File Kyc file
name String Kyc document name

To sign the KYC document, the user has to request a signature code that will be sent to her mobile phone via SMS. Then, she will have to send back the code via API to confirm her signature.


To request the signature code use the following request:


HTTP Request


POST /api/v2/public/users/natural/{userId}/request-kyc-terms-signature

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/request-kyc-terms-signature


As response, you would get the following JSON object:



  {
  “signatureId”: “ewiWXPgrnq8aZ9sVd4xd”,
  “status”: “PENDING”,
  “type”: “SMS”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
signatureId String Identification for the signature that will be needed for the confirmation request
status String Signature status
type String Signature type

To confirm the KYC document signature:

HTTP Request


POST /api/v2/public/users/natural/{userId}/sign-kyc-terms

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/sign-kyc-terms

With the following information provided as JSON:



  {
  “signCode”: “3tM3WD”,
  “signatureId”: “ewiWXPgrnq8aZ9sVd4xd”
  }
  

Where:

Request body parameters


Parameter Mandatory Datatype Description
signCode Yes string Signature code that the user received via SMS
signatureId Yes string Must be the same as the signatureId received in the request signature response

And as response, we would get the following JSON object:



  {
    “signatureDate”: “2019-09-05T09:46:31.750Z”,
    “signatureId”: “ewiWXPgrnq8aZ9sVd4xd”,
    “status”: “SIGNED”,
    “type”: “SMS”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
signatureDate Date Document sign date
signatureId string Must be the same as the signatureId received in the request signature response
status String Signature status
type String Signature type

Income tax

For uploading the income tax file you have to do the following request:


HTTP Request


POST /api/v2/public/users/natural/{userId}/income-tax-file

In our example, the whole request would be POST /api/v2/public/users/natural/91af1cb8-1caa-47d0-8ef8-2c11948baaba/income-tax-file

The request should be a multipart request with a part called “file”.


Where:

Request body parameters


Parameter Mandatory Datatype Description
file Yes Multipart request file part The file should not exceed 50mb size. Supported file formats are png, jpg, jpeg and pdf.

And as response, we would get the following JSON object:



  {
  “id”: “91af1cb8-1caa-47d0-8ef8-2c11948baaba”,
  “fileVersion”: “Jbz2jvozyXXvHrTAm06x2wb0kxVg04Yl”
  }
  

Where:

HTTP Response parameters


Parameter Datatype Description
id UUID User id
fileVersion String File version.

The PUT method can be used to update the file after it has been uploaded for the first time.