Corebanq Public Docs
Customers

Description

Overview

The customers package provides comprehensive functionality for managing customers, their team members, shareholders, and signatories. It includes features for invitation management, document generation, and verification processes.

Security Architecture

Authentication & Authorization

All customer endpoints require JWT-based authentication. Access control is enforced through RBAC (Role-Based Access Control) at the service layer, ensuring users can only access and modify records they have permission to view.

Rate Limiting Strategy

Critical endpoints implement Redis-backed rate limiting to prevent abuse:

  • Name availability checks: Limited to 3 requests per minute per authenticated user
  • Purpose: Prevents database enumeration, brute-force attacks, and resource exhaustion
  • Tracking: Rate limits are tracked by user ID (not IP) for authenticated endpoints
  • Reset: Counters automatically reset at the end of each time window

Audit & Compliance

All operations are logged with full request traceability:

  • request_id - Unique identifier for each API request
  • user_id - Authenticated user performing the action
  • ip_address - Client IP address
  • action - Operation performed
  • timestamp - When the operation occurred

This ensures complete audit trails for regulatory compliance and security investigations.

Data Structure

Core Fields

FieldTypeDescription
namestringThe full name of the customer
descriptionstringA detailed description of the customer
abbreviationstringShort form or acronym for the customer
logostringBase64 encoded image data of the customer's logo
activebooleanIndicates if the record is active for operational use
metadataJSONAdditional flexible metadata stored as JSON
FieldTypeDescription
uidstringUnique identifier for the customer
dateOfRegistrationdateDate when the customer was officially registered
legalFormstringLegal structure of the organization
seatstringOfficial registered seat of the company
statusstringCurrent status of the customer
principalIdUUIDReference to the user who initially registered the account
counterpartyIdUUIDMirror-linked counterparty created for same customer entity; use it when flows need counterparty context for that customer
documentsJSONAssociated documents stored in JSON format

Status Values

StatusDescription
KYBInitial status when a company has started the registration process
SIGNStatus when signatories have been invited to sign documents
REVIEWStatus when signed documents are under review by a Compliance officer
ACTIVEStatus when approval is given and the company can operate
SUSPENDEDStatus when a company's activity has been suspended

API Methods

Name Validation

Check Company Name Availability

POST /v1/customers/check-name

Validates whether a company name is available for registration before creating a new customer record.

Authentication: Required (JWT Bearer token)
Authorization: Accessible to all authenticated users with User role
Rate Limiting: 3 requests per minute per user

Purpose:

  • Prevents duplicate company registrations
  • Provides immediate feedback during onboarding
  • Improves user experience by validating names upfront

Request Parameters:

FieldTypeRequiredConstraints
namestringYes2-255 characters

Response:

FieldTypeDescription
availablebooleantrue if name is available, false if already taken
namestringNormalized company name that was checked

Validation Rules:

  • Case-insensitive matching (prevents duplicates with different casing)
  • Automatic whitespace trimming
  • Minimum length: 2 characters
  • Maximum length: 255 characters

Error Scenarios:

  • 400 - Invalid company name (too short, too long, or empty)
  • 401 - Unauthorized (missing or invalid JWT token)
  • 429 - Rate limit exceeded (max 3 requests per minute)
  • 500 - Database or system error

Typical Workflow:

  1. User authenticates and receives JWT token
  2. User enters company name in registration form
  3. Frontend calls /v1/customers/check-name to validate availability
  4. If available, user proceeds to complete registration
  5. User submits full customer creation via /v1/customers

Customers

Create Customer

POST /v1/customers

Creates a new customer record.

Request

{
  "abbr": "EXE",
  "logo": "base64_encoded_string",
  "documents": {
    "corp_struct": "base64_encoded_string",
    "share_reg": "base64_encoded_string"
  },
  "uid": "CHE450748806",
  "date_of_registration": "2023-09-15",
  "legal_form": "Corporation",
  "seat": "Zurich",
  "status": "Active",
  "principal_id": "uuid",
  "name": "Example Company AG",
  "description": "",
  "active": true,
  "metadata": {}
}

Response

{
  "abbr": "EXE",
  "logo": "base64_encoded_string",
  "documents": {
    "share_reg": "base64_encoded_string",
    "corp_struct": "base64_encoded_string"
  },
  "uid": "CHE450748806",
  "date_of_registration": "2023-09-15",
  "legal_form": "Corporation",
  "seat": "Zurich",
  "status": "Active",
  "principal_id": "uuid",
  "counterparty_id": "uuid",
  "signing_room_id": "uuid",
  "chatroom_id": "uuid",
  "tariff_id": "uuid",
  "fx_tariff_id": "uuid",
  "name": "Example Company AG",
  "description": null,
  "id": "uuid",
  "created_at": "2024-03-20T10:00:00Z",
  "created_by": "uuid",
  "modified_at": "2024-03-20T10:00:00Z",
  "modified_by": "uuid",
  "active": true,
  "metadata": {
    "route": "/company"
  },
  "addresses": [
    {
      "rec_id": "uuid",
      "rec_type": "customers",
      "type": "registration",
      "street": "Example Street",
      "number": "123",
      "postal_code": "12345",
      "city": "Example City",
      "country": "CH",
      "is_primary": false,
      "id": "uuid",
      "created_at": "2024-03-20T10:00:00Z",
      "created_by": "uuid",
      "modified_at": "2024-03-20T10:00:00Z",
      "modified_by": "uuid",
      "active": true,
      "metadata": null
    }
  ]
}

Patch Customer (Partial Update)

PATCH /v1/customers/{id}

Updates one or more of the following fields for a customer. Only provided fields are updated:

  • tariff_id (UUID)
  • fx_tariff_id (UUID)
  • type (string)
  • status (string)
  • signing_room_id (UUID)
  • principal_id (UUID)

Request Example

{
  "tariff_id": "uuid",
  "status": "ACTIVE"
}

Response Example

{
  "id": "uuid",
  "status": "ACTIVE",
  "tariff_id": "uuid"
  // ... other fields ...
}

Team Management

Create Team Member

POST /v1/customers/{id}/teams

Adds a new team member to a customer's team.

Request

{
  "email": "team.member@example.com",
  "role": "admin",
  "permissions": ["read", "write"],
  "metadata": {
    "department": "finance"
  }
}

Response

{
  "id": "uuid",
  "customer_id": "uuid",
  "email": "team.member@example.com",
  "role": "admin",
  "status": "invited",
  "permissions": ["read", "write"],
  "metadata": {
    "department": "finance"
  },
  "created_at": "2024-03-20T10:00:00Z"
}

Update Team Member

PATCH /v1/customers/{id}/teams/{user_id}

Updates team member details.

Request

{
  "role": "member",
  "permissions": ["read"],
  "metadata": {
    "department": "operations"
  }
}

Shareholders

Create Shareholder

POST /v1/customers/{id}/shareholders

Creates a new shareholder record.

Request

{
  "type": "individual",
  "name": "Jane Smith",
  "email": "jane.smith@example.com",
  "share_percentage": 25.5,
  "nationality": "CH",
  "tax_residence": "CH",
  "documents": [
    {
      "type": "passport",
      "number": "X123456",
      "country": "CH",
      "expiry_date": "2030-12-31"
    }
  ]
}

Response

{
  "id": "uuid",
  "customer_id": "uuid",
  "type": "individual",
  "name": "Jane Smith",
  "email": "jane.smith@example.com",
  "share_percentage": 25.5,
  "nationality": "CH",
  "tax_residence": "CH",
  "status": "pending_verification",
  "documents": [
    {
      "id": "uuid",
      "type": "passport",
      "number": "X123456",
      "country": "CH",
      "expiry_date": "2030-12-31",
      "status": "pending_verification"
    }
  ],
  "created_at": "2024-03-20T10:00:00Z",
  "updated_at": "2024-03-20T10:00:00Z"
}

Signatories

Create Signatory

POST /v1/customers/{id}/signatories

Creates a new signatory record.

Request

{
  "name": "Robert Johnson",
  "email": "robert.johnson@example.com",
  "phone": "+41791234567",
  "signing_authority": "individual",
  "signing_limit": {
    "amount": 100000,
    "currency": "CHF"
  },
  "documents_required": ["passport", "proof_of_address"]
}

Response

{
  "id": "uuid",
  "customer_id": "uuid",
  "name": "Robert Johnson",
  "email": "robert.johnson@example.com",
  "phone": "+41791234567",
  "signing_authority": "individual",
  "signing_limit": {
    "amount": 100000,
    "currency": "CHF"
  },
  "status": "pending_documents",
  "documents_required": ["passport", "proof_of_address"],
  "documents_submitted": [],
  "created_at": "2024-03-20T10:00:00Z",
  "updated_at": "2024-03-20T10:00:00Z"
}

Invite Signatories

POST /v1/customers/{id}/signatories/invite

Sends invitations to signatories.

Request

{
  "signatory_ids": ["uuid1", "uuid2"],
  "message": "Please complete your verification",
  "expires_in": 7200
}

Response

{
  "invitations": [
    {
      "signatory_id": "uuid1",
      "email": "signatory1@example.com",
      "status": "sent",
      "expires_at": "2024-03-22T10:00:00Z"
    },
    {
      "signatory_id": "uuid2",
      "email": "signatory2@example.com",
      "status": "sent",
      "expires_at": "2024-03-22T10:00:00Z"
    }
  ]
}

Error Codes

CodeDescription
customers_m.invalid_company_nameInvalid company name (validation failed)
customers_m.failed_to_check_name_availabilityFailed to check company name availability
customers_m.rate_limit_exceededRate limit exceeded for name availability checks
customers_m.not_foundCustomer not found
customers_m.failed_to_createFailed to create customer
customers_m.failed_to_getFailed to retrieve customer
customers_m.not_linkedCustomer not linked
customers_m.customer_type_not_foundCustomer type not found
customers_m.persona_already_existsPersona already linked to a customer
customers_m.address_not_foundAddress not found
customers_m.failed_to_create_rolesFailed to create customer roles
customers_m.customer_roles_config_not_foundCustomer roles configuration not found
customers_m.invalid_roles_configInvalid customer roles configuration
customers_m.failed_to_create_personaFailed to create persona
customers_m.failed_to_create_organizationFailed to create organization
customers_m.failed_to_fetch_entityFailed to fetch related entity
customers_m.failed_to_create_shareholderFailed to create shareholder
customers_m.failed_to_create_addressFailed to create address
customers_m.failed_to_create_linkFailed to create link between records
customers_m.failed_to_check_permissionFailed to check permissions
customers_m.failed_to_get_signatory_idsFailed to get signatory IDs
customers_m.failed_to_get_signatoriesFailed to get signatories
customers_m.company_type_invalidInvalid company type
common.failed_to_serializeFailed to serialize or deserialize request/response payload
common.duplicate_entityDuplicate entity detected
common.permission_deniedAccess denied – insufficient permissions
common.database_errorInternal database error
common.record_not_foundRequested record not found

Dependencies

  • common/errs - Error handling
  • common/auth - Authentication
  • common/logger - Logging functionality
  • common/rbac - Role-based access control
  • common/links - Entity relationship management
  • modules/countries - Country validation
  • modules/uploads - Document upload handling
  • modules/kyc - KYC verification processes
  • modules/personas - Person/Organization management
  • modules/roles - Role management
  • modules/users - User management

On this page