Driver onboarding in BetterSuite has two surfaces and a real state machine. There's the admin-side flow in the dashboard (Taxi → Drivers) where you create or review drivers, and there's the driver-app side where the person uploads their own documents. They meet in the middle at the Driver approvals queue.
The actual driver state machine
DriverStatus is defined in backend/crates/core/kernel/src/driver_status.rs:
| Status | When a driver lands here |
|---|---|
Pending | Newly registered driver, hasn't submitted vehicle details yet. |
PendingReview | Driver has submitted vehicle details and is waiting on admin review. |
Approved | Verified driver who can go online and take trips. |
Suspended | Temporarily blocked. |
Blocked | Permanently banned. |
Archived | Deleted / inactive. |
A driver needs Approved status to go online. Approving a driver also approves their KYC application (see Step 3).
Step 1: Get drivers into the system
There are two ways a driver record gets created.
A. Admin-created from the dashboard
In Taxi → Drivers → New driver, you fill in one form with four sections:
| Section | Fields |
|---|---|
| Driver | Profile photo, first name and last name (both required), email, phone (preselects your workspace's country), gender. Provide at least an email or a phone number. |
| Driving licence | Licence number and expiry date. |
| Vehicle | Make, model and colour from your Vehicle Catalog (the model list follows the make), year, plate number, and the driver's search radius in metres. |
| Service classes | The ride types this driver is offered. |
Admin-created drivers don't upload documents from this form — they finish their documents in the driver app and then wait for your approval.
The service classes you tick come from the workspace's catalog (the list comes from serviceClassesAdmin). The selection is saved as INCLUDE rows in taxi.driver_service_class via the setDriverServiceClasses mutation. The driver's vehicle and record must still qualify for a class in Dynamic mode.
Behind the scenes, the createDriver mutation (in backend/crates/taxi/application/src/driver_admin/driver_admin_mutation.rs):
- Looks for an existing account with that email or phone and reuses it, otherwise creates a new account on your workspace.
- Grants the Driver role.
- Creates a driver record bound to that account.
The newly created driver lands at Pending status. Service-class assignments are written but the driver still needs the rest of their KYC flow before they can go online.
B. Driver-app self-registration
A driver can also install the BetterTaxi driver app, sign in with phone + OTP, and complete the onboarding themselves. The app's KYC step (frontend/apps/taxi_driver/lib/features/kyc/presentation/widgets/kyc_documents_widget.dart) fetches the workspace's KYC requirements, creates a draft KycApplication, and walks the driver through uploading one document per requirement plus a FACE_MATCH selfie used as the profile picture.
Two important details:
- If the workspace has no KYC policy for the (App=Taxi, Role=Driver) combination, the driver app shows a "No KYC documents required for your account" screen and the application step is skipped.
- If the workspace is flagged as a demo / test workspace (
isDemofrom theTenantCubit), the UI shows a banner explaining that uploads will be auto-approved for testing purposes.
Step 2: Configure KYC requirements (once per workspace)
The documents a driver has to upload are not hard-coded — they come from your workspace's KYC policy. The relevant entities live in backend/crates/kyc/domain/:
KycPolicyEntityis keyed by(tenant_id?, vertical, role, country?). Workspace-specific policies override the platform default. Policies are versioned (policy_key+version).- A policy holds a list of requirements, each pointing at a
KycCheckKind.
The available check kinds (kyc_check_kind_enum.rs) are:
| Kind | Purpose |
|---|---|
GovId | National ID or passport. |
DriverLicense | Driver's license — relevant for taxi / courier roles. |
AddressProof | Utility bill, bank statement, etc. |
FaceMatch | Selfie matched against a photo on a document. |
Liveness | Video liveness check. |
VehicleRegistration | Vehicle registration documents. |
VehicleInsurance | Vehicle insurance proof. |
BusinessRegistration | Used for KYB / business registration. |
UboDeclaration | Ultimate beneficial owner declaration. |
BankAccountVerification | Bank account proof. |
FoodLicense | Food handling license (F&B merchants). |
ProfessionalLicense | Trade-specific licenses (electrician, plumber, etc.). |
You manage policies in Configuration → KYC Policies. Each policy carries vertical (Service), role (RoleKind), optional country, a min_level, and an active flag. Platform default policies are listed there too, read-only.
You can also manage Certifications (workspace-defined KycRequirement rows) from Manage certifications on the same page and reference them in a Service Class's Compliance section ("Required certifications" multi-select). A driver who hasn't uploaded an approved document for a required certification can't go online for that service class.
Step 3: Review and approve
When a driver finishes uploading documents in the driver app, the KYC application moves from Draft to Pending (backend/crates/kyc/domain/src/application_status_enum.rs), and the driver shows up in Taxi → Driver approvals — the queue of drivers waiting on a decision: new sign-ups whose documents are in, and suspended drivers.
Clicking a driver in the queue opens the Review driver page, in two parts:
- Documents — each uploaded
KycDocumentappears with two reviewer inputs: Valid until (expiresAt) and Keep for, a retention period picked from the workspace'sRetentionPolicycatalog. Blank dates follow your KYC policy. - Details — name, contact, vehicle details and service classes. These are editable here; fix anything that's wrong before you decide.
There are two actions:
| Action | Effect |
|---|---|
| Approve | Runs approveDriver — sets DriverStatus = Approved and approves the underlying KYC application via the KYC service. |
| Reject | Opens a rejection dialog with two kinds. Ask for new documents is a fixable (soft) rejection — the driver gets your message and can re-submit. Reject for good is a permanent (hard) rejection — the driver is blocked and can't apply again. |
The rejection dialog collects two messages:
- Message to the driver — shown to the driver in the app.
- Note for your team — internal note, saved on the driver's Notes tab and never shown to them.
For a closer look at one driver's paperwork, open the driver from Taxi → Drivers and use the Documents tab. It lists every KYC submission with each document's status, lets you change a document's expiry, run OCR on it, and grant or revoke a KYC waiver. The Eligibility tab next to it shows, per service class, whether the driver is offered that ride type right now and what stops them if not.
What we don't have
The previous version of this article promised a few things that aren't in the product. Don't go looking for them:
- No bulk-import CSV for drivers.
createDriveris single-driver. If you need to migrate a fleet, use theMigrationsrunner in the Owner Dashboard (/dashboard/migrations) — that has the bulk import pipelines. - No "kiosk mode" for in-person onboarding. There's no tablet-friendly batch UI for walking drivers through registration in person. You can run an event by sitting drivers down with their own phones and creating the records one at a time via either the admin Create flow or driver self-signup.
- No "generate registration link with your workspace slug" feature. Drivers find your workspace in the driver app by entering your join code, not through a magic link.
- No automatic KYC scoring shown in the queue. What you see in the review screen is the documents and their
DocumentStatus, not a provider-side fraud score. - No cross-service KYC applications queue. Each service has its own approvals page — Driver approvals for taxi, Shop verification, Lot approvals and Provider verification for parking, Provider approvals for services.
Driver app — once approved
Once a driver is Approved, the BetterTaxi driver app surfaces:
- Status — go online / offline.
- Earnings — per-period earnings with charts.
- Ride history — past trips.
- Wallet — driver wallet balance and transactions.
- Payout methods — bank or mobile-wallet accounts they get paid into.
- Vehicle — their registered vehicle.
- Profile, settings, requirements — the rest of the self-service surface.
Folder reference: frontend/apps/taxi_driver/lib/features/.
What's next
- Set Up Your Fleet — if your service classes or pricing aren't ready yet, drivers can't be assigned to anything useful.
- Dashboard Tour — Driver approvals sits in the Taxi group of the sidebar; KYC Policies is under Configuration.
- Plans & Billing — your plan caps how many cities (and therefore how many distinct local rosters) you can operate.