Data model

Understand company API records, employment context and the separate ownership of personal wallets.

Everything in the Kua API hangs off a single company — the one that owns your API key. You never see or touch another business’s data.

The core objects

Company

Your business. The API key is scoped to exactly one company; every object in this public company API is filtered to that company. Personal identity and wallet ownership are separate.

Employment type

An employment classification or template (for example Full-time or Contractor). Statutory treatment follows the employee’s authoritative salary/profile settings, company policy and country requirements; the label alone does not switch deductions on or off.

Employee

A person on your payroll, tied to an employment type.

Payroll run

A month’s payroll for the company, built from the current roster. Draft preparation is separate from approval, disbursement and individual line outcomes; a partially disbursed run is not fully paid.

Wallet

Company funding and personal wallets have different owners. Personal wallets belong to a person and currency, not to one employer. The public SDK has no general wallet-management routes.

Event

An immutable record of something that happened (a run disbursed, an employee was added). Delivered via webhooks and queryable at /v1/events.

How they relate

Company
├── Employment types
├── Employees ───────────── (each references an employment type)
├── Payroll runs ────────── (built from the roster of active employees)
│     └── authorised settlement can credit a person-and-currency wallet
├── Company funding context (separate from personal wallet ownership)
└── Events ──────────────── (emitted as things happen → webhooks)

Identifiers

Company API records use stable id values (UUID strings). IDs are safe to store and reference. Timestamps are ISO-8601 in UTC (e.g. 2026-07-25T10:30:00+00:00), and money fields must be interpreted using the specific resource schema and currency. Fields named amountMinor or toSalaryMinor use that currency’s minor units; do not infer a currency from a sample.

The payroll lifecycle

Creating a run gives you a draft — nothing moves money yet. Approval and disbursement are deliberate, separate steps (handled in the dashboard or via owner-gated flows), so an API integration can prepare payroll without being able to release funds on its own. You observe each transition through events: payroll.run.hr_approved, payroll.run.disbursed, and so on.

Test mode

A kua_test_… key supports isolated employee creation and payroll draft/list operations; it is not a sandbox mirror of every API. Payroll listing needs payroll:read and returns only Test runs. Test records auto-purge after 14 days. POST /v1/test-data/clear requires test-data:clear (or *) for API keys; either Live or Test keys may clear only their own company’s Test records.

Events, leave, advances and performance have no isolated Test partition. Their ten read routes return 409 TEST_MODE_UNSUPPORTED to sufficiently scoped Test keys. Existing unsupported add-on writes and the independent webhook mode gate retain 400 TEST_MODE_UNSUPPORTED; * does not bypass either restriction. For events/add-on reads, missing scopes return 403 INSUFFICIENT_SCOPE first. Do not substitute a Live key just to run a Test-data example. See the scope and upgrade contract.

Use the public boundary

The public SDK creates employee records and payroll drafts and can observe events. Employment-type setup, salary changes, payroll approval/payment, personal wallet actions and employer-context selection use their authorised product flows. A promotion record does not update salary automatically. Do not infer a public execution route from an event name.

Done when: your integration stores IDs with company and key mode, treats personal identity/wallet ownership separately from employment, and distinguishes Draft, queued, partial and settled outcomes. Continue with API coverage.

Search documentation

↑ ↓ to move · Enter to open · Esc to close