Client Documents
The six endpoints that read a client's submitted documents, approve or reject them, and manage the canned rejection reasons.
Overview
A client fills in the fields the document scheme asks for and submits them; these endpoints read those submissions and settle them. The scheme itself is a separate job and lives in Document Scheme.
Each record maps to one field and carries its own status. A client can have some documents approved while others are still waiting.
Reference
Fetching Documents
Returns the document records the client submitted. Records hang off the field id and every filter is merged into one list.
[{ id, name }].input, textarea, selectbox, radio, checkbox, file.awaiting, verified or unverified.curl 'https://panel.example.com/api/v1/admin/clients/42/documents' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/documents', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
const waiting = body.data.records.filter((r) => r.status === 'awaiting');$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/documents');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->GetClientDocuments(['id' => 42]);
$waiting = [];
foreach ($response['data']['records'] as $record) {
if ($record['status'] === 'awaiting') {
$waiting[] = $record['id'];
}
}Reviewing Documents
Updates the verification status of several records at once. Every record whose status changes sends the client a notification.
{"<recordId>": {"status": …, "message": …}}.verified, unverified or awaiting. A record carrying anything else is skipped in silence.curl -X PATCH 'https://panel.example.com/api/v1/admin/clients/42/documents' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"statuses":{"51":{"status":"verified"},"52":{"status":"unverified","message":"The document is unreadable, please send a clearer copy"}}}'const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/documents', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
statuses: {
51: { status: 'verified' },
52: { status: 'unverified', message: 'The document is unreadable, please send a clearer copy' },
},
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/documents');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'statuses' => [
51 => ['status' => 'verified'],
52 => ['status' => 'unverified', 'message' => 'The document is unreadable, please send a clearer copy'],
],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->ReviewClientDocuments([
'id' => 42,
'statuses' => [
51 => ['status' => 'verified'],
52 => ['status' => 'unverified', 'message' => 'The document is unreadable, please send a clearer copy'],
],
]);
$rejected = $response['data']['rejected'] ?? 0;{
"data": {
"reviewed": true,
"verified": 1,
"rejected": 1
}
}Deleting a Document Record
Deletes a single document record.
curl -X DELETE 'https://panel.example.com/api/v1/admin/clients/42/documents/51' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/documents/51', {
method: 'DELETE',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/documents/51');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->DeleteClientDocument([
'id' => 42,
'record_id' => 51,
]);Listing Rejection Reasons
Returns the saved rejection reasons. These are the canned texts used while reviewing.
curl 'https://panel.example.com/api/v1/admin/clients/document-rejection-reasons' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/clients/document-rejection-reasons', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/document-rejection-reasons');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->GetDocumentRejectionReasons();Adding a Rejection Reason
Adds a new canned reason to the list.
value was empty.curl -X POST 'https://panel.example.com/api/v1/admin/clients/document-rejection-reasons' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"value":"The document is unreadable, please send a clearer copy"}'const res = await fetch('https://panel.example.com/api/v1/admin/clients/document-rejection-reasons', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ value: 'The document is unreadable, please send a clearer copy' }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/document-rejection-reasons');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['value' => 'The document is unreadable, please send a clearer copy']),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->AddDocumentRejectionReason(['value' => 'The document is unreadable, please send a clearer copy']);Deleting a Rejection Reason
Removes a reason from the list. You send the text itself, not an id.
value was empty.curl -X DELETE 'https://panel.example.com/api/v1/admin/clients/document-rejection-reasons' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"value":"The document is unreadable, please send a clearer copy"}'const res = await fetch('https://panel.example.com/api/v1/admin/clients/document-rejection-reasons', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ value: 'The document is unreadable, please send a clearer copy' }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/clients/document-rejection-reasons');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['value' => 'The document is unreadable, please send a clearer copy']),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);$response = Api::Clients()->DeleteDocumentRejectionReason(['value' => 'The document is unreadable, please send a clearer copy']);Pitfalls
The fetch endpoint is not read-only: calling it marks the records as read. An integration polling this while watching the pending-document badge will clear that badge on every poll.
Every record whose status changes sends an approval or rejection notice. Sending the same status twice counts as no change, but rejecting a record by mistake and fixing it produces two notices.
The delete request takes value, not an id, and the text has to match exactly. Even one space of difference will not find the record.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.