Submit Application
curl --request POST \
--url https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit"
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit', 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://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Application submitted successfully",
"success": true,
"data": {
"application": {
"id": "f436daf8-146b-4949-bf28-9b36440085a4",
"invite_id": "b6075be0-f1d0-451f-a468-3e94563101d2",
"entity_type": "individual",
"status": "submitted",
"current_step": 3,
"is_complete": true,
"individual_info": {
"firstName": "Jane",
"lastName": "Doe",
"phone": "+2348012345678",
"dateOfBirth": "1990-05-14",
"citizenship": "NG"
},
"change_request_note": null,
"flagged_fields": [],
"created_at": "2026-06-12T23:30:43.040Z",
"updated_at": "2026-06-13T09:31:08.554Z"
},
"documents": [
{
"id": "0c95b2a1-7a93-4a3a-9a52-2a1f0b9b3c11",
"kyb_application_id": "f436daf8-146b-4949-bf28-9b36440085a4",
"document_type": "proof_of_address",
"file_name": "bank_statement.pdf",
"file_path": "f436daf8-146b-4949-bf28-9b36440085a4/proof_of_address/bank_statement_1781304842117.pdf",
"file_size": 284119,
"mime_type": "application/pdf",
"is_required": true,
"uploaded_at": "2026-06-13T09:14:02.117Z"
}
]
}
}{
"status": 400,
"message": "Application is incomplete",
"code": "APPLICATION_INCOMPLETE",
"missingFields": [
"related_persons.a3d4f21e-f499-488f-8508-43228dfea485.taxId"
],
"missingDocuments": [
"proof_of_address"
]
}{
"status": 400,
"message": "Validation failed",
"code": "ACCOUNT_RESTRICTED",
"errors": [
{
"path": [
"amount"
],
"message": "amount must be a whole number of smallest currency units (e.g. cents)"
}
]
}{
"status": 404,
"message": "Account not found"
}{
"status": 409,
"message": "All beneficial owners must complete KYC before submission",
"code": "KYC_INCOMPLETE",
"unverified": [
{
"personId": "a3d4f21e-f499-488f-8508-43228dfea485",
"name": "Jane Doe"
}
]
}Applications
Submit Application
Validates that the application is complete and submits it for review. Returns the outstanding items if anything is missing. For business accounts, every related person must have completed KYC before submission.
POST
/
accounts
/
{accountId}
/
submit
Submit Application
curl --request POST \
--url https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit"
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit', 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://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rolla.xyz/api/v1/external/accounts/{accountId}/submit")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Application submitted successfully",
"success": true,
"data": {
"application": {
"id": "f436daf8-146b-4949-bf28-9b36440085a4",
"invite_id": "b6075be0-f1d0-451f-a468-3e94563101d2",
"entity_type": "individual",
"status": "submitted",
"current_step": 3,
"is_complete": true,
"individual_info": {
"firstName": "Jane",
"lastName": "Doe",
"phone": "+2348012345678",
"dateOfBirth": "1990-05-14",
"citizenship": "NG"
},
"change_request_note": null,
"flagged_fields": [],
"created_at": "2026-06-12T23:30:43.040Z",
"updated_at": "2026-06-13T09:31:08.554Z"
},
"documents": [
{
"id": "0c95b2a1-7a93-4a3a-9a52-2a1f0b9b3c11",
"kyb_application_id": "f436daf8-146b-4949-bf28-9b36440085a4",
"document_type": "proof_of_address",
"file_name": "bank_statement.pdf",
"file_path": "f436daf8-146b-4949-bf28-9b36440085a4/proof_of_address/bank_statement_1781304842117.pdf",
"file_size": 284119,
"mime_type": "application/pdf",
"is_required": true,
"uploaded_at": "2026-06-13T09:14:02.117Z"
}
]
}
}{
"status": 400,
"message": "Application is incomplete",
"code": "APPLICATION_INCOMPLETE",
"missingFields": [
"related_persons.a3d4f21e-f499-488f-8508-43228dfea485.taxId"
],
"missingDocuments": [
"proof_of_address"
]
}{
"status": 400,
"message": "Validation failed",
"code": "ACCOUNT_RESTRICTED",
"errors": [
{
"path": [
"amount"
],
"message": "amount must be a whole number of smallest currency units (e.g. cents)"
}
]
}{
"status": 404,
"message": "Account not found"
}{
"status": 409,
"message": "All beneficial owners must complete KYC before submission",
"code": "KYC_INCOMPLETE",
"unverified": [
{
"personId": "a3d4f21e-f499-488f-8508-43228dfea485",
"name": "Jane Doe"
}
]
}Validates that the account’s application is complete and submits it for compliance review. If anything is missing, the response lists exactly what’s outstanding.
Application incomplete (
Per-person entries are prefixed No beneficial owners declared (
A business that has not declared anyone is reported through the same
Identity not verified — individual (
Related persons not verified — business (
Already submitted or approved (
An application that has already been approved returns the same shape with
Example Request
curl -X POST "https://api.rolla.xyz/api/v1/external/accounts/b6075be0-f1d0-451f-a468-3e94563101d2/submit" \
-H "X-API-Key: your_api_key_here"
Example Response
{
"status": 200,
"message": "Application submitted successfully",
"success": true,
"data": {
"application": {
"id": "f436daf8-146b-4949-bf28-9b36440085a4",
"invite_id": "b6075be0-f1d0-451f-a468-3e94563101d2",
"entity_type": "individual",
"status": "submitted",
"current_step": 3,
"is_complete": true,
"individual_info": {
"firstName": "Jane",
"lastName": "Doe",
"phone": "+2348012345678",
"dateOfBirth": "1990-05-14",
"citizenship": "NG"
},
"change_request_note": null,
"flagged_fields": [],
"created_at": "2026-06-12T23:30:43.040Z",
"updated_at": "2026-06-13T09:31:08.554Z"
},
"documents": [
{
"id": "0c95b2a1-7a93-4a3a-9a52-2a1f0b9b3c11",
"kyb_application_id": "f436daf8-146b-4949-bf28-9b36440085a4",
"document_type": "proof_of_address",
"file_name": "bank_statement.pdf",
"file_path": "f436daf8-146b-4949-bf28-9b36440085a4/proof_of_address/bank_statement_1781304842117.pdf",
"file_size": 284119,
"mime_type": "application/pdf",
"is_required": true,
"uploaded_at": "2026-06-13T09:14:02.117Z"
}
]
}
}
A business account’s application is returned in the same envelope, with
business_info,
business_address, contact_info, banking_info and related_persons in place of
individual_info, and current_step set to 6.Error Responses
When more than one thing is outstanding you get the most actionable one first: missing fields or documents are reported as
400 APPLICATION_INCOMPLETE and always list what is missing; 409 KYC_INCOMPLETE is returned only once the application data is complete and identity verification is the sole remaining hold.Application incomplete (400)
{
"status": 400,
"message": "Application is incomplete",
"code": "APPLICATION_INCOMPLETE",
"missingFields": [
"related_persons.a3d4f21e-f499-488f-8508-43228dfea485.taxId"
],
"missingDocuments": ["proof_of_address"]
}
related_persons.<personId>., so you can tell which
representative each one belongs to. Get Requirements
reports the same list without attempting a submit.
To find out what a submit would return without calling it, read submitBlocker on
Get Requirements — it carries the same
code and details as the errors below.
No beneficial owners declared (400)
A business that has not declared anyone is reported through the same
APPLICATION_INCOMPLETE body, with the bare related_persons entry in missingFields:
{
"status": 400,
"message": "Application is incomplete",
"code": "APPLICATION_INCOMPLETE",
"missingFields": ["related_persons"],
"missingDocuments": []
}
Identity not verified — individual (409)
{
"status": 409,
"message": "Identity verification must be completed before the application can be submitted",
"code": "KYC_INCOMPLETE",
"identityVerification": "pending"
}
Related persons not verified — business (409)
{
"status": 409,
"message": "All beneficial owners must complete KYC before submission",
"code": "KYC_INCOMPLETE",
"unverified": [
{
"personId": "a3d4f21e-f499-488f-8508-43228dfea485",
"name": "Jane Doe"
}
]
}
Already submitted or approved (409)
{
"status": 409,
"message": "Application already submitted"
}
"message": "Application already approved". Neither carries a code.
Key Behaviours
Individual accounts: the applicant must complete their KYC link before submission. Until they do,
readyToSubmit is false and this endpoint returns 409 KYC_INCOMPLETE.Business accounts: at least one beneficial owner or director must be declared, and every one of them must have completed identity verification. Generate KYC links for any
unverified person — or, if you verify identity yourself, submit reliance for them — and retry once they finish.Every related person needs a government identifier —
taxId, or nin for Nigerian residents. It is not required when you add the person, only here at submission, where a missing one appears as related_persons.<personId>.taxId in missingFields. It can be patched onto an existing person with Update Related Person, so representatives added without one do not need re-creating. See the per-country formats.Submitted applications are locked for editing. If the review team requests changes, the application reopens with a
changes_requested status and a note explaining what to fix.Authorizations
Your Rolla API key
Path Parameters
Identifier of an account owned by the same user as your API key's business