curl --request GET \
--url https://api.platform.dakota.xyz/customers/{customer_id} \
--header 'x-api-key: <api-key>'const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.platform.dakota.xyz/customers/{customer_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.platform.dakota.xyz/customers/{customer_id}"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.platform.dakota.xyz/customers/{customer_id}"
req, _ := http.NewRequest("GET", 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))
}{
"id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"name": "Acme Corp",
"email": "contact@acmecorp.com",
"external_id": "external_customer_123",
"customer_type": "business",
"kyb_status": "pending",
"kyc_status": "pending",
"kyb_links": [
{
"provider_id": "trm_labs",
"link_type": "persona",
"url": "https://verify.provider.com/kyb/a1b2c3d4e5f6",
"status": "pending",
"created_at": 1234567890,
"updated_at": 1234567890,
"expires_at": 1234567890,
"deleted_at": 1234567890
}
],
"provider_statuses": [
{
"provider_id": "trm_labs",
"status": "approved",
"endorsements": [
"string"
]
}
],
"application_id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"decision": "approved",
"application_url": "https://onboarding.example.com/applications/abc123?token=xyz789",
"created_at": 1234567890,
"updated_at": 1234567890,
"deleted_at": 1234567890
}{
"type": "https://docs.dakota.xyz/api-reference/errors#invalid-request",
"title": "Invalid request",
"status": 400,
"detail": "Invalid request",
"instance": "https://api.platform.dakota.xyz/customers/example-id",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#authentication-error",
"title": "Unauthorized",
"status": 401,
"detail": "Unauthorized",
"instance": "https://api.platform.dakota.xyz/customers/example-id",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Forbidden",
"instance": "https://api.platform.dakota.xyz/customers/example-id",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer not found",
"status": 404,
"detail": "Customer not found",
"instance": "https://api.platform.dakota.xyz/customers/example-id",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}Retrieve a customer record by ID
Retrieves a single customer by customer_id for the authenticated client.
curl --request GET \
--url https://api.platform.dakota.xyz/customers/{customer_id} \
--header 'x-api-key: <api-key>'const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.platform.dakota.xyz/customers/{customer_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.platform.dakota.xyz/customers/{customer_id}"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.platform.dakota.xyz/customers/{customer_id}"
req, _ := http.NewRequest("GET", 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))
}{
"id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"name": "Acme Corp",
"email": "contact@acmecorp.com",
"external_id": "external_customer_123",
"customer_type": "business",
"kyb_status": "pending",
"kyc_status": "pending",
"kyb_links": [
{
"provider_id": "trm_labs",
"link_type": "persona",
"url": "https://verify.provider.com/kyb/a1b2c3d4e5f6",
"status": "pending",
"created_at": 1234567890,
"updated_at": 1234567890,
"expires_at": 1234567890,
"deleted_at": 1234567890
}
],
"provider_statuses": [
{
"provider_id": "trm_labs",
"status": "approved",
"endorsements": [
"string"
]
}
],
"application_id": "1NFHrqBHb3cTfLVkFSGmHZqdDPi",
"decision": "approved",
"application_url": "https://onboarding.example.com/applications/abc123?token=xyz789",
"created_at": 1234567890,
"updated_at": 1234567890,
"deleted_at": 1234567890
}{
"type": "https://docs.dakota.xyz/api-reference/errors#invalid-request",
"title": "Invalid request",
"status": 400,
"detail": "Invalid request",
"instance": "https://api.platform.dakota.xyz/customers/example-id",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#authentication-error",
"title": "Unauthorized",
"status": 401,
"detail": "Unauthorized",
"instance": "https://api.platform.dakota.xyz/customers/example-id",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Forbidden",
"instance": "https://api.platform.dakota.xyz/customers/example-id",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer not found",
"status": 404,
"detail": "Customer not found",
"instance": "https://api.platform.dakota.xyz/customers/example-id",
"request_id": "req_01hzy6y7v8w9x0y1z2a3b4c5d6"
}Authorizations
Path Parameters
Unique identifier (ksuid) of the customer record KSUID is a 27-character globally unique ID that combines a timestamp with a random component. Used for all entity identifiers in the Dakota platform.
27^[0-9A-Za-z]{27}$"1NFHrqBHb3cTfLVkFSGmHZqdDPi"
Response
Customer record retrieved successfully
A customer of the client: an individual or a business, with its onboarding application, verification verdicts and account onboarding status.
KSUID is a 27-character globally unique ID that combines a timestamp with a random component. Used for all entity identifiers in the Dakota platform.
27^[0-9A-Za-z]{27}$"1NFHrqBHb3cTfLVkFSGmHZqdDPi"
Name of the customer
"Acme Corp"
Type of entity - either an individual person or a company/organization
individual, business "business"
The customer's account onboarding status: whether its accounts are cleared to transact. Despite the name, it applies to every customer type, individual and business alike, not only to businesses.
pending: Dakota has no status for the customer yet, which is the case until it is provisioned.partner_review: Dakota has a status for the customer, but the customer is not yet active, rejected or frozen.active: Dakota and at least one banking partner have approved the customer; it can transact.rejected: Dakota rejected or automatically declined the customer, or every banking partner rejected it.frozen: the customer is frozen and cannot move money.
auto_declined is in the enum but is never returned; an automatic decline reads
rejected.
For the identity verification verdict see kyc_status; for one combined badge see
status.
active, pending, partner_review, rejected, frozen, auto_declined "pending"
Provider-agnostic effective KYC/B status for this customer, derived server-side for display convenience. Returns the same answer for both Sumsub-verified and Persona-verified customers without the client having to know which provider did the work.
Derivation order (most authoritative first):
- The customer's onboarding application
decision, if set (approved→approved;declined/auto_declined→rejected;withdrawn→expired). - The most-recently-updated non-deleted persona
kyb_link's status (legacy customers from before the orchestration layer — Persona'screatedmaps tonot_started,completedtoapproved,needs_reviewtoin_review). pendingif the customer has an open onboarding application but no decision yet (Sumsub in-flight).not_startedotherwise.
Advisory, not authoritative. This field is provided for
badge rendering and operator UIs. The derivation rules may
evolve as new verification providers are added. For
compliance-critical decisions, consult decision,
kyb_links, and provider_statuses directly.
not_started, pending, expired, approved, rejected, in_review "pending"
Unix timestamp (seconds) when the customer was created.
1234567890
Unix timestamp (seconds) when the customer record itself was last modified: for
example a change to its name, email or account status, including the legal name a
business customer takes when it is provisioned. Onboarding and verification status
changes (kyb_status, kyc_status, application_status, decision, status) do
not themselves move it. To follow those, subscribe to the customer.kyb_status.*
webhooks or read the fields directly.
1234567890
Email address of the customer
"contact@acmecorp.com"
Your own label for the customer, as supplied when the customer was created. Not unique: several customers can share one value. Omitted when no external ID was set.
"external_customer_123"
KYB Links for different providers used in the KYB process.
Show child attributes
Show child attributes
Detailed status information from different verification providers used in the KYB process.
Show child attributes
Show child attributes
Whether this customer is currently permitted to hold RD, derived
server-side from the same US-state geofence that guards RD account
creation. true when RD is allowed; false only when one of the
customer's governing US states is on the restricted list while the
geofence is active. Customers with no resolvable US governing state
— non-US customers, or those whose jurisdiction is unconfirmed — are
allowed. When the geofence is disabled (empty blocklist) this is
true for everyone.
This is the canonical read path for the RD-eligibility verdict: consumers read a boolean and never see or copy the underlying blocklist.
true
ID of the customer's onboarding application, for an individual or a business customer alike
27^[0-9A-Za-z]{27}$"1NFHrqBHb3cTfLVkFSGmHZqdDPi"
Current lifecycle state of the customer's onboarding application
(e.g. pending, submitted, under_review, approved,
declined). Omitted when the customer has no application.
Use this field to drive workflow UI — it tracks where the
customer is in the onboarding flow. For the orthogonal questions
"is this customer cleared to transact?" and "what's the
provider-agnostic KYC verdict?", see kyb_status and
kyc_status respectively.
pending, submitted, under_review, request_for_information, admin_revision, approved, declined, completed, compliance_review, closed "submitted"
Application decision status
approved, declined, auto_declined, withdrawn "approved"
Why the application was decided, in words you can show. For a
withdrawn application it is the fixed reason recorded when the
applicant withdrew from an RFI email. For a declined application it
is the same text as decline_message. Omitted when there is no
decision, or when a declined application has no decline_reason.
"User withdrew the application from the request-for-information (RFI) email"
The category of the decline, when the customer's most recent application was declined and a category was recorded. Omitted otherwise.
unsupported_region, prohibited_country, prohibited_business_type, other "prohibited_country"
The fixed client-facing sentence for decline_reason. Present
exactly when decline_reason is. Show it as is; it is the only
explanation Dakota provides.
"The applicant is located in a country Dakota does not support."
The single client-facing status for this customer, derived
server-side. It collapses three signals into one badge so a client
never has to reconcile kyb_status, kyc_status, and
application_status by hand.
Precedence (first match wins):
frozen— the customer has an open freeze; surfaced over a stale approval so an actionable freeze is never masked.- the most-recent application's decision —
approved,declined(declined or auto_declined), orwithdrawn. - the most-recent application's lifecycle —
info_requestedwhen a request for information is open (the customer owes a response); the internal in-review states collapse tosubmitted;pendingotherwise. pendingwhen the customer has no application yet.
Once a customer is approved / declined / withdrawn, that is the
final answer and kyb_status / kyc_status do not change it. Use
those fields only for the underlying breakdown.
frozen, declined, withdrawn, approved, info_requested, submitted, pending "info_requested"
URL for accessing the onboarding application. Always present when the
customer has an onboarding application, including during an open RFI
loop. In an RFI loop the additive resubmit_url is returned as well,
and the dashboard links to that resubmission page rather than this
plain application view.
"https://onboarding.example.com/applications/abc123?token=xyz789"
The resubmission link for a customer in an open RFI loop — the exact
/applications/{id}/resubmit?token=… URL the applicant receives in
the RFI email, built from the customer's existing onboarding token
(no new token is minted on read). Present only when an RFI is open
AND a request with a resubmission scope was sent (the page shows what
that request asked for; an application moved into
request_for_information without one has nothing to resubmit through
it, so no link is returned). An RFI is open when status is
info_requested, or when an approved individual was asked for a proof
of address because they are close to the proof-of-address volume limit
(customer.rfi.requested with reason: poa_volume_limit_approaching;
status stays approved). Returned alongside application_url rather
than in place of it.
"https://onboarding.example.com/applications/abc123/resubmit?token=xyz789"
Unix timestamp (seconds) when the customer was deleted. Omitted for a customer that has not been deleted.
1234567890
ID of the sub-client this customer is associated with, if any.
27^[0-9A-Za-z]{27}$"1NFHrqBHb3cTfLVkFSGmHZqdDPi"
Name of the sub-client this customer is associated with, if any.
"Partner Corp"
Whether this customer is a sub-client. This is set when the customer is created and cannot be changed afterwards.
Was this page helpful?

