curl --request POST \
--url https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"redirectUrl": "https://www.example.com/",
"kycProviderShareToken": "<string>"
}
'import requests
url = "https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/"
payload = {
"redirectUrl": "https://www.example.com/",
"kycProviderShareToken": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({redirectUrl: 'https://www.example.com/', kycProviderShareToken: '<string>'})
};
fetch('https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'redirectUrl' => 'https://www.example.com/',
'kycProviderShareToken' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/"
payload := strings.NewReader("{\n \"redirectUrl\": \"https://www.example.com/\",\n \"kycProviderShareToken\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"redirectUrl\": \"https://www.example.com/\",\n \"kycProviderShareToken\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"redirectUrl\": \"https://www.example.com/\",\n \"kycProviderShareToken\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"submissionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"createdAt": "2023-11-07T05:31:56Z",
"providerUrl": "<string>",
"otpRequired": true
}Start KYC
Starts a KYC verification for the customer. Takes no identity data — only a required redirectUrl and an optional kycProviderShareToken.
If the customer already has an approved KYC on your account, this returns 400 with the error code 20015 (KycAlreadyApprovedException) — nothing left to do.
Otherwise, an email OTP is sent to the customer as part of starting the verification. The response’s otpRequired tells you what to do next:
otpRequired: true— validate the code with Validate KYC OTP before continuing.otpRequired: false— no OTP step needed. Check the response’sstatusto see what’s next.
If the customer already has an approved KYC with Ripio, validating the OTP approves them immediately — no further steps required. Otherwise, once the OTP is confirmed, submit the customer’s data with Submit KYC Information to complete the verification.
curl --request POST \
--url https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"redirectUrl": "https://www.example.com/",
"kycProviderShareToken": "<string>"
}
'import requests
url = "https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/"
payload = {
"redirectUrl": "https://www.example.com/",
"kycProviderShareToken": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({redirectUrl: 'https://www.example.com/', kycProviderShareToken: '<string>'})
};
fetch('https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'redirectUrl' => 'https://www.example.com/',
'kycProviderShareToken' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/"
payload := strings.NewReader("{\n \"redirectUrl\": \"https://www.example.com/\",\n \"kycProviderShareToken\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"redirectUrl\": \"https://www.example.com/\",\n \"kycProviderShareToken\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://skala-sandbox.ripio.com/api/v1/customers/{customerId}/kyc/start/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"redirectUrl\": \"https://www.example.com/\",\n \"kycProviderShareToken\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"submissionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"createdAt": "2023-11-07T05:31:56Z",
"providerUrl": "<string>",
"otpRequired": true
}kycSubmission — identity data is sent afterwards through Submit KYC Information, once the OTP is confirmed (or skipped entirely, if the response already resolved the identity).400KycAlreadyApprovedException(20015) — this customer already has an approved KYC on your account. No OTP is sent and nothing is opened; skip KYC entirely and continue with the quote.otpRequired: true— validate the code with Validate KYC OTP before doing anything else. If the customer already has an approved KYC with Ripio, that validation approves them immediately — no data required.otpRequired: false— no OTP left to validate. Check the response’sstatus: continue with Submit KYC Information if data is still missing, or move on to polling otherwise.
Authorizations
Access token obtained via /oauth2/token/. Use as Authorization: Bearer <access_token>.
Path Parameters
Unique identifier for the customer.
Body
Request body to start a KYC verification. Takes no identity data.
URL to redirect the user to after completing the KYC flow.
"https://www.example.com/"
Optional. Sumsub share token for a customer already verified in your own Sumsub account (Reusable KYC) — see kycProviderShareToken on Submit KYC Information for the full behavior and prerequisites; it works the same way here.
2000Response
KYC verification started.
Unique identifier for the submitted KYC data.
Date and time the KYC submission was created (UTC format).
Points to a third-party KYC provider's widget to handle file uploads and liveness checks. Only available in production.
Whether the OTP sent to the customer's email still needs to be validated with Validate KYC OTP before continuing. Only present for accounts configured for Ripio KYC reuse via OTP.
Was this page helpful?