Create Onboarding Consent
curl --request POST \
--url https://api.example.com/v2/consent/onboardingimport requests
url = "https://api.example.com/v2/consent/onboarding"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v2/consent/onboarding', 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.example.com/v2/consent/onboarding",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$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.example.com/v2/consent/onboarding"
req, _ := http.NewRequest("POST", url, nil)
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.example.com/v2/consent/onboarding")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v2/consent/onboarding")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyConsent
Create Onboarding Consent
Create a new consent set during user onboarding before a userId exists
POST
/
v2
/
consent
/
onboarding
Create Onboarding Consent
curl --request POST \
--url https://api.example.com/v2/consent/onboardingimport requests
url = "https://api.example.com/v2/consent/onboarding"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v2/consent/onboarding', 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.example.com/v2/consent/onboarding",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$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.example.com/v2/consent/onboarding"
req, _ := http.NewRequest("POST", url, nil)
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.example.com/v2/consent/onboarding")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v2/consent/onboarding")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyOverview
Creates a new consent set during user onboarding using theonboardingId from the registration flow. This endpoint is typically called after personal details submission and before address submission during the registration flow.
Use the
onboardingId returned from email verification (POST /v1/auth/register/email/verify) - do NOT generate a new ID. This links the consent to the user’s registration session.Use Cases
Mobile App Registration
Collect consent during mobile app onboarding flows
Web Registration
Capture consent on web registration forms
KYC Processes
Record consent during identity verification
Pre-Registration Consent
Collect consent before user account creation
Endpoint
POST https://api.baanx.com/v2/consent/onboarding
Headers
| Header | Required | Description |
|---|---|---|
x-client-key | ✅ | Your public API key |
x-secret-key | ✅ | Your secret API key (keep secure) |
Content-Type | ✅ | Must be application/json |
x-us-env | ❌ | Set to true for US region routing |
Security: The
x-secret-key should only be used in server-side code. Never expose it in client-side applications.Request Body
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
onboardingId | string | ✅ | Unique temporary identifier for this onboarding session |
tenantId | string | ✅ | Your tenant identifier (provided by Baanx) |
policyType | string | ✅ | Policy type: global or US |
consents | array | ✅ | Array of consent items to record (min 1 item) |
metadata | object | ❌ | Additional metadata about the consent capture session |
Consent Item Structure
| Field | Type | Required | Description |
|---|---|---|---|
consentType | string | ✅ | Type of consent (see Consent Types) |
consentStatus | string | ✅ | Status: granted or denied |
metadata | object | ❌ | Additional context for this specific consent |
Consent Types
| Type | Description | Required In |
|---|---|---|
eSignAct | Electronic signature agreement (E-Sign Act compliance) | US policy only |
termsAndPrivacy | Terms of service and privacy policy | All policies |
marketingNotifications | Marketing communications opt-in | All policies |
smsNotifications | SMS/text message notifications | All policies |
emailNotifications | Email notifications | All policies |
Metadata Fields (Optional)
| Field | Type | Description |
|---|---|---|
ipAddress | string | User’s IP address at time of consent |
userAgent | string | Browser/device user agent string |
timestamp | string | ISO 8601 timestamp when consent was captured |
clientId | string | Client application identifier |
version | string | API or app version |
Additional custom fields can be included in
metadata. All fields must be JSON-serializable.Examples
US Policy (All 5 Consents)
{
"onboardingId": "100a99cf-f4d3-4fa1-9be9-2e9828b20ebb",
"tenantId": "tenant_baanx_prod",
"policyType": "US",
"consents": [
{
"consentType": "eSignAct",
"consentStatus": "granted"
},
{
"consentType": "termsAndPrivacy",
"consentStatus": "granted"
},
{
"consentType": "marketingNotifications",
"consentStatus": "granted"
},
{
"consentType": "smsNotifications",
"consentStatus": "denied"
},
{
"consentType": "emailNotifications",
"consentStatus": "granted"
}
],
"metadata": {
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)",
"timestamp": "2024-01-15T10:30:00Z",
"clientId": "mobile-app-ios-v2.1.0"
}
}
Global Policy (4 Consents, No eSignAct)
{
"onboardingId": "200b88de-e39c-52e5-8cd9-3f9944b31fcc",
"tenantId": "tenant_baanx_global",
"policyType": "global",
"consents": [
{
"consentType": "termsAndPrivacy",
"consentStatus": "granted"
},
{
"consentType": "marketingNotifications",
"consentStatus": "granted"
},
{
"consentType": "smsNotifications",
"consentStatus": "granted"
},
{
"consentType": "emailNotifications",
"consentStatus": "granted"
}
]
}
Response
201 Created
Success Response:{
"consentSetId": "550e8400-e29b-41d4-a716-446655440001",
"onboardingId": "onboarding_abc123xyz",
"tenantId": "tenant_baanx_prod",
"createdAt": "2024-01-15T10:30:00Z",
"_links": {
"self": {
"href": "https://api.baanx.com/v2/consent/consentSet/550e8400-e29b-41d4-a716-446655440001",
"method": "GET"
}
}
}
| Field | Type | Description |
|---|---|---|
consentSetId | string (UUID) | Generated unique identifier for this consent set |
onboardingId | string | Your provided onboarding identifier |
tenantId | string | Your tenant identifier |
createdAt | string (ISO 8601) | Timestamp when consent set was created |
_links | object | HATEOAS links for related resources |
Store the
consentSetId: You’ll need this to link the user after account creation completes.400 Bad Request - Missing Required Consents
{
"error": "Validation error",
"details": [
"Missing required consent: termsAndPrivacy for policy type: global"
]
}
- US Policy: All 5 types (including
eSignActfor E-Sign Act compliance) - Global Policy: 4 types (excludes
eSignAct)
400 Bad Request - Invalid Consent Type
{
"error": "Validation error",
"details": [
"Invalid consentType: 'pushNotifications'. Must be one of: eSignAct, termsAndPrivacy, marketingNotifications, smsNotifications, emailNotifications"
]
}
409 Conflict - Duplicate Onboarding ID
{
"error": "Conflict",
"details": [
"Consent set with onboardingId 'onboarding_abc123' already exists"
]
}
onboardingId has already been used.
Solution: Generate a new unique onboardingId and retry.
498 Invalid Client Key
{
"error": "Invalid client key",
"details": [
"The provided x-client-key is invalid or expired"
]
}
499 Missing Client Key
{
"error": "Missing client key",
"details": [
"x-client-key header is required for all requests"
]
}
x-client-key header.
Validation Rules
Onboarding ID Requirements
Onboarding ID Requirements
- Must be the
onboardingIdfrom registration email verification - Do NOT generate a new ID - use the ID from
POST /v1/auth/register/email/verify - Format: UUID string (e.g.,
100a99cf-f4d3-4fa1-9be9-2e9828b20ebb)
// ✅ Correct: Use onboardingId from registration
const { onboardingId } = await verifyEmail(email, code);
await createConsent(onboardingId, consents);
// ❌ Wrong: Do not generate new ID
// const onboardingId = `onboarding_${uuid()}`;
Policy Type Requirements
Policy Type Requirements
US Policy requires all 5 consent types (E-Sign Act compliance):
eSignAct(required for E-Sign Act compliance)termsAndPrivacymarketingNotificationssmsNotificationsemailNotifications
eSignAct):termsAndPrivacymarketingNotificationssmsNotificationsemailNotifications
Consent Status Values
Consent Status Values
Only two status values are valid for creation:
granted: User has provided consentdenied: User has explicitly refused consent
Both
granted and denied are acceptable. However, if required consents are denied, the user’s overall consent status will be incomplete.Metadata Best Practices
Metadata Best Practices
Include these fields for comprehensive audit trails:All values must be JSON-serializable (no functions, circular references, or undefined).
metadata: {
ipAddress: req.ip,
userAgent: req.headers['user-agent'],
timestamp: new Date().toISOString(),
clientId: 'web-app-v1.2.0',
sessionId: req.session.id,
privacyPolicyVersion: 'v2.1',
termsVersion: 'v3.0'
}
Code Examples
TypeScript
async function createOnboardingConsent(
onboardingId: string, // From registration email verification
consents: Array<{ type: string; status: 'granted' | 'denied' }>,
userIp: string,
userAgent: string
) {
const response = await fetch('https://api.baanx.com/v2/consent/onboarding', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-client-key': process.env.BAANX_CLIENT_KEY!,
'x-secret-key': process.env.BAANX_SECRET_KEY!
},
body: JSON.stringify({
onboardingId, // Use ID from registration, don't generate new one
tenantId: 'tenant_baanx_prod',
policyType: 'US',
consents: consents.map(c => ({
consentType: c.type,
consentStatus: c.status
})),
metadata: {
ipAddress: userIp,
userAgent: userAgent,
timestamp: new Date().toISOString(),
clientId: 'web-app-v1.2.0'
}
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Consent creation failed: ${error.details.join(', ')}`);
}
const { consentSetId } = await response.json();
return consentSetId;
}
// Get onboardingId from registration flow (Step 2)
const { onboardingId } = await verifyEmailCode(email, verificationCode);
// Create consent during registration (Step 4 - before address submission)
const consentSetId = await createOnboardingConsent(
onboardingId, // From registration
[
{ type: 'eSignAct', status: 'granted' },
{ type: 'termsAndPrivacy', status: 'granted' },
{ type: 'marketingNotifications', status: 'granted' },
{ type: 'smsNotifications', status: 'denied' },
{ type: 'emailNotifications', status: 'granted' }
],
'192.168.1.1',
'Mozilla/5.0...'
);
console.log(`Consent set created: ${consentSetId}`);
Python
import requests
from datetime import datetime
def create_onboarding_consent(onboarding_id, consents, user_ip, user_agent):
"""Create consent using onboardingId from registration flow"""
response = requests.post(
'https://api.baanx.com/v2/consent/onboarding',
headers={
'Content-Type': 'application/json',
'x-client-key': os.getenv('BAANX_CLIENT_KEY'),
'x-secret-key': os.getenv('BAANX_SECRET_KEY')
},
json={
'onboardingId': onboarding_id, # From registration, don't generate new
'tenantId': 'tenant_baanx_prod',
'policyType': 'US',
'consents': [
{'consentType': c['type'], 'consentStatus': c['status']}
for c in consents
],
'metadata': {
'ipAddress': user_ip,
'userAgent': user_agent,
'timestamp': datetime.utcnow().isoformat() + 'Z',
'clientId': 'web-app-v1.2.0'
}
}
)
response.raise_for_status()
data = response.json()
return data['consentSetId']
# Get onboardingId from registration flow (Step 2)
onboarding_id = verify_email_code(email, verification_code)['onboardingId']
# Create consent during registration (Step 4 - before address submission)
consent_set_id = create_onboarding_consent(
onboarding_id, # From registration
[
{'type': 'eSignAct', 'status': 'granted'},
{'type': 'termsAndPrivacy', 'status': 'granted'},
{'type': 'marketingNotifications', 'status': 'granted'},
{'type': 'smsNotifications', 'status': 'denied'},
{'type': 'emailNotifications', 'status': 'granted'}
],
'192.168.1.1',
'Mozilla/5.0...'
)
print(f"Consent set created: {consent_set_id}")
cURL
curl -X POST https://api.baanx.com/v2/consent/onboarding \
-H "Content-Type: application/json" \
-H "x-client-key: your_client_key" \
-H "x-secret-key: your_secret_key" \
-d '{
"onboardingId": "100a99cf-f4d3-4fa1-9be9-2e9828b20ebb",
"tenantId": "tenant_baanx_prod",
"policyType": "US",
"consents": [
{
"consentType": "eSignAct",
"consentStatus": "granted"
},
{
"consentType": "termsAndPrivacy",
"consentStatus": "granted"
},
{
"consentType": "marketingNotifications",
"consentStatus": "granted"
},
{
"consentType": "smsNotifications",
"consentStatus": "denied"
},
{
"consentType": "emailNotifications",
"consentStatus": "granted"
}
],
"metadata": {
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"timestamp": "2024-01-15T10:30:00Z",
"clientId": "web-app-v1.2.0"
}
}'
Next Steps
After creating the consent set:- Store the
consentSetId: You’ll need it to link the user later - Complete user registration: Finalize account creation in your system
- Link user to consent: Call Link User to Consent Set
Related Endpoints
Link User to Consent
Associate userId with consent set after registration
Get User Consent Status
Check user’s consent status
Get Consent Audit Trail
Retrieve complete consent change history
Implementation Guide
Full integration guide with examples
Was this page helpful?