Skip to main content
Before processing payments, customers must complete KYB (Know Your Business) onboarding. This guide explains how to integrate Dakota Platform’s onboarding flow.

Overview

The onboarding process involves:
  1. Creating a customer record (KYB automatically initiated)
  2. Redirecting customer to complete verification
  3. Monitoring KYB status via API or webhooks

Step 1: Create a Customer

First, create a customer record with basic business information.

Customer Creation Fields

FieldTypeRequiredDescriptionExample
namestringLegal name of the business or individual"Acme Corp"
customer_typestringType of customer account. Must be "business" or "individual""business"
external_idstringYour internal identifier for this customer"acme_001"

Request Example

cURL
curl -X POST https://api.platform.dakota.xyz/customers \
  -H "X-API-Key: your-api-key" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corp",
    "customer_type": "business"
  }'
JavaScript
const response = await fetch('https://api.platform.dakota.xyz/customers', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your-api-key',
    'X-Idempotency-Key': crypto.randomUUID(),
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Acme Corp',
    customer_type: 'business'
  })
});

const customer = await response.json();
console.log('Created customer:', customer.data.id);
Python
import requests
import uuid

response = requests.post(
    'https://api.platform.dakota.xyz/customers',
    headers={
        'X-API-Key': 'your-api-key',
        'X-Idempotency-Key': str(uuid.uuid4()),
        'Content-Type': 'application/json'
    },
    json={
        'name': 'Acme Corp',
        'customer_type': 'business'
    }
)

customer = response.json()
print(f'Created customer: {customer["data"]["id"]}')
Go
package main

import (
    "bytes"
    "net/http"
    "github.com/google/uuid"
)

func main() {
    client := &http.Client{}
    body := bytes.NewBufferString(`{
        "name": "Acme Corp",
        "customer_type": "business"
    }`)
    
    req, _ := http.NewRequest("POST", "https://api.platform.dakota.xyz/customers", body)
    
    req.Header.Add("X-API-Key", "your-api-key")
    req.Header.Add("X-Idempotency-Key", uuid.New().String())
    req.Header.Add("Content-Type", "application/json")
    
    resp, _ := client.Do(req)
    defer resp.Body.Close()
}
Rust
use reqwest::header::{HeaderMap, HeaderValue};
use uuid::Uuid;
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = reqwest::Client::new();
    
    let mut headers = HeaderMap::new();
    headers.insert("X-API-Key", HeaderValue::from_static("your-api-key"));
    headers.insert("X-Idempotency-Key", HeaderValue::from_str(&Uuid::new_v4().to_string())?);
    headers.insert("Content-Type", HeaderValue::from_static("application/json"));
    
    let body = json!({
        "name": "Acme Corp",
        "customer_type": "business"
    });
    
    let response = client
        .post("https://api.platform.dakota.xyz/customers")
        .headers(headers)
        .json(&body)
        .send()
        .await?;
    
    Ok(())
}
Java
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.UUID;

public class DakotaCustomerExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        
        String body = """
            {
              "name": "Acme Corp",
              "customer_type": "business"
            }
            """;
        
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.platform.dakota.xyz/customers"))
            .header("X-API-Key", "your-api-key")
            .header("X-Idempotency-Key", UUID.randomUUID().toString())
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
            
        HttpResponse<String> response = client.send(request, 
            HttpResponse.BodyHandlers.ofString());
    }
}
Response:
{
  "id": "2Nq8G7xK9mR4Ls6DyJ1Uf3Tp",
  "kyb_links": [],
  "application_id": "2WGC9cKv9P4K8eGzqY6qJ3Xz7Qm",
  "application_url": "https://apply.dakota.com/applications/2WGC9cKv9P4K8eGzqY6qJ3Xz7Qm?token=kJ8xN3zQ9mL2pR5vY7wC1aF4dG6hK0sT8uW3nB5eM9",
  "application_expires_at": 1734567890000000000
}

Step 2: Application Process (Automatic)

An onboarding application is automatically created when you create a customer. The response includes an application_url that you can use to redirect your customer to Dakota’s hosted onboarding form.

Automatic Application Creation

When you create a customer, the system automatically:
  • Creates an onboarding application
  • Generates a secure application_url with an embedded token
  • Sets the initial application status to "pending"

Response Fields

The customer creation response includes:
FieldDescriptionExample
idUnique identifier for the customer"2Nq8G7xK9mR4Ls6DyJ1Uf3Tp"
kyb_linksArray of KYB provider links (if any)[]
application_idUnique identifier for the onboarding application"2WGC9cKv9P4K8eGzqY6qJ3Xz7Qm"
application_urlDakota-hosted onboarding URL with embedded auth token"https://apply.dakota.com/applications/...?token=..."
application_expires_atUnix timestamp (nanoseconds) when the application token expires1734567890000000000

Using the Application URL

From the customer creation response, extract the onboarding URL:
const customer = await response.json();
const onboardingUrl = customer.application_url;

// Redirect customer to complete onboarding
window.location.href = onboardingUrl;

Step 3: Handle the Onboarding Flow

Direct your customer to the application_url to complete verification using Dakota’s hosted onboarding form. The customer will:
  1. Provide business information and documentation
  2. Add beneficial owners and control persons
  3. Upload required documents (ID, proof of address, etc.)
  4. Submit the application for review
  5. Receive approval or requests for additional information

Step 4: Monitor Application Status

Check onboarding status programmatically:
cURL
curl -X GET https://api.platform.dakota.xyz/customers/{customer_id} \
  -H "X-API-Key: your-api-key"
JavaScript
const response = await fetch(`https://api.platform.dakota.xyz/customers/${customerId}`, {
  headers: {
    'X-API-Key': 'your-api-key'
  }
});

const customer = await response.json();
console.log('KYB Status:', customer.kyb_status);
Python
import requests

response = requests.get(
    f'https://api.platform.dakota.xyz/customers/{customer_id}',
    headers={'X-API-Key': 'your-api-key'}
)

customer = response.json()
print(f'KYB Status: {customer["kyb_status"]}')
Go
package main

import (
    "net/http"
)

func main() {
    client := &http.Client{}
    req, _ := http.NewRequest("GET", "https://api.platform.dakota.xyz/customers/" + customerId, nil)
    
    req.Header.Add("X-API-Key", "your-api-key")
    
    resp, _ := client.Do(req)
    defer resp.Body.Close()
}
Rust
use reqwest::header::{HeaderMap, HeaderValue};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = reqwest::Client::new();
    
    let mut headers = HeaderMap::new();
    headers.insert("X-API-Key", HeaderValue::from_static("your-api-key"));
    
    let response = client
        .get(&format!("https://api.platform.dakota.xyz/customers/{}", customer_id))
        .headers(headers)
        .send()
        .await?;
    
    Ok(())
}
Java
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;

public class DakotaKYBStatusExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.platform.dakota.xyz/customers/" + customerId))
            .header("X-API-Key", "your-api-key")
            .GET()
            .build();
            
        HttpResponse<String> response = client.send(request, 
            HttpResponse.BodyHandlers.ofString());
    }
}
Response:
{
  "id": "2Nq8G7xK9mR4Ls6DyJ1Uf3Tp",
  "name": "Acme Corp",
  "customer_type": "business",
  "kyb_status": "active",
  "kyb_links": [],
  "application_id": "2WGC9cKv9P4K8eGzqY6qJ3Xz7Qm",
  "created_at": 1705320600,
  "updated_at": 1705324200
}

KYB Status Values

The kyb_status field indicates the customer’s verification status:
StatusDescription
pendingKYB verification in progress
activeCustomer approved and can transact
partner_reviewUnder manual review
rejectedVerification failed
frozenAccount suspended
You can also check the application status directly via the Get Application endpoint for more detailed status information.

Best Practices

User Experience

  • Clearly communicate the onboarding requirements
  • Provide progress indicators
  • Set expectations for processing time
  • Offer support contact information

Error Handling

  • Handle rejection gracefully
  • Provide clear next steps
  • Allow customers to restart if needed
  • Log all onboarding events

Compliance

  • Store audit trails
  • Monitor for suspicious activity
  • Keep records for compliance reporting
  • Regular review of rejected applications

Required Documents

Typical documents required for business verification:
  • Certificate of Incorporation
  • Bank Statements
  • Director/Officer Identification
  • Beneficial Ownership Information

Troubleshooting

Common Issues

Onboarding Stuck in “Pending”
  • Check if customer has accessed the onboarding URL
Repeated Rejections
  • Ensure document quality meets requirements
  • Consider manual review process
Webhook Not Received
  • Verify webhook endpoint is responding with 200
  • Check webhook signature validation
  • Review webhook logs in dashboard
Any issues not covered here can be addressed by contacting Dakota Platform support.

Next Steps

After successful customer onboarding:
  1. Set up Recipients & Destinations - Configure payment targets
  2. Create Transactions - Process payments for approved customers
  3. Webhook Integration - Get real-time KYB status updates
  4. Testing - Test your onboarding flow

API Reference

For detailed endpoint documentation, see: