A trip in Bezala is a mileage expense — the employee drove their own vehicle for work purposes and is being reimbursed at a per-kilometre rate. The cost is computed from distance, vehicle type, and (optionally) the number of additional passengers.
This is the third expense type, alongside receipts and daily allowances. Same lifecycle, same approval rules.
Anatomy of a trip
A trip has:
A vehicle — chosen from the user's saved vehicles. Each vehicle carries the per-km rate that applies to it (a personal car has a different rate from a personal car used for hauling, an electric car may have a different rate from a petrol car).
A list of entries — one per leg of the trip. Each entry has a date, a starting point, an ending point, a distance in kilometres, and an optional number of additional passengers.
A description — the business purpose.
Optional cost centers.
Bezala calculates the cost: base mileage cost + additional passenger cost.
Vehicles and waypoints
Vehicles are managed in the user's settings; they're returned by GET /api/home so a client can show a dropdown without an extra round-trip.
Waypoints are the user's saved locations — home, office, customer sites — that show up as autocomplete options when filling in a trip. GET /api/my_waypoints returns the calling user's saved waypoints. They're a UI affordance, not a data integrity requirement: you can always pass arbitrary text for a starting or ending point.
Calculating the cost up-front
Like daily allowances, trips have a calculate_cost endpoint:
The response in cents:
If number_of_people is greater than 1, the additional-passenger rate kicks in (passengers beyond the driver get a per-km bump in many tax regimes).
Submitting a trip
POST /api/trips creates the trip; the response includes the calculated cost. To save as draft, add draft: 1 at the top level of the body.
Lifecycle
Same as receipts and daily allowances. The transitions are:
Action | Endpoint |
Show | GET /api/trips/:id |
List | GET /api/trips |
Approve | PUT /api/trips/:id/approve |
Approve with edits | same, with body |
Disapprove | POST /api/trips/:id/disapprove |
The list endpoint takes the standard filters.
Conditional values
GET /api/trips/:id/conditional_values returns the vehicles, the per-km rates, and any country-specific configuration that's currently valid for this trip given the user's company and the year of the trip. Use it to drive UI dropdowns. For pure data integration, you can usually skip it.
How trips become accounting entries
The journal entry credits the same "Reimbursable to employee" asset account used by personal-card receipts and daily allowances. The expense account is configured per-company under mileage settings — typically a "Mileage" or "Travel" account. Per-passenger uplifts post to a separate line if your company config separates them.
The SEPA file pays the employee.
A few subtleties
Per-km rates can change mid-year. Tax rates are set annually, but companies sometimes top up. Bezala uses the rate effective at the trip's date, not the date you submitted it.
Round trips are usually two entries. Bezala doesn't auto-double a one-way distance. If the employee went there and came back, that's two entries with two distance_km values.
Vehicles belong to a user. A trip can only reference vehicles registered to the submitting user. If you're submitting on someone else's behalf, make sure their vehicle is set up first.
Common integration patterns
Calendar / CRM → trip. When an outdoor meeting closes, your integration creates a draft trip with the date, route, and a sensible default distance pulled from a maps API. The employee opens Bezala, confirms, and submits.
Vehicle GPS → trip. Some fleets log every drive automatically. Push them to Bezala as drafts with draft: 1 and let employees mark which ones were business.
Annual reporting. Pull all accounted trips for a year via date_range and state=accounted, group by user, and you have the year-end mileage report most tax authorities will ask for.



