User guide
Expenses
Looking for what it does rather than how to use it? Read the Expenses overview .
What it is
Expenses records money a person spent — parking on a client site, a part bought at the counter, a hotel during a cutover. Each expense is reviewed by an administrator, and only an approved one can be reimbursed to the person who paid or charged on to a client.
Concepts
| Concept | What it is |
|---|---|
| Expense | A dated cost with a description, an amount, and the person who incurred it. Optionally linked to a ticket, a project and a client organization. |
| Category | A hierarchical classification aligned to your chart of accounts, optionally mapped to a QuickBooks account. Shared with vendor invoice lines. |
| Tag | A flat, coloured label for cross-cutting classification. Also shared with vendor invoice lines. |
| Receipt | An image or PDF attached as evidence. Stored privately and served only through the expense it belongs to. |
| Billable | Whether the cost is charged on to a client. A billable expense must name the client organization it is rebilled to. |
| Markup | The uplift applied when rebilling. Stored as a fraction — 0.15 is 15%. Resolved from your markup configuration unless you set one on the expense. |
| Reimbursable | Whether anybody is owed money back. True only when the expense was paid personally; a company card or a directly-billed supplier account owes nobody. |
| Approved | An administrator has cleared it. Approval fixes the rebill price and is what makes the expense reimbursable and invoiceable. |
| Invoiced | The expense has been billed onto a client invoice and is stamped with that invoice, so it cannot be billed a second time. |
The lifecycle
┌─────────┐
create ─────▶│ DRAFT │◀──────────────┐
└────┬────┘ │
│ submit │ submit (again)
▼ │
┌─────────────┐ reject ┌┴──────────┐
│ SUBMITTED │───────────▶│ REJECTED │
└──────┬──────┘ └───────────┘
│ approve editable, resubmittable
▼
┌─────────────┐ reimburse ┌──────────────┐
│ APPROVED │────────────▶│ REIMBURSED │
└──────┬──────┘ └──────────────┘
│ (personally-paid only)
│ invoice (billable only)
▼
stamped with the invoice
DRAFT and REJECTED are the only states in which the person who filed the expense can change or delete it. Once submitted it belongs to the approver.
Approval is the gate that matters, twice over: nothing is reimbursed until an administrator has cleared it, and nothing reaches a client invoice unless it is billable and approved and not already invoiced. That last condition is written once in the code and shared by the expense list, the rebilling preview and the invoice generator, so the three cannot disagree about what is eligible.
APPROVED is the final state for a company-card or directly-billed expense. Nothing is owed back, so marking it reimbursed would assert a payment that never happened; the API refuses it.
Roles and permissions
| Action | Customer | Power User | MSP Technician | Org Admin | MSP Admin | Platform Admin |
|---|---|---|---|---|---|---|
| File, edit, submit an expense | — | ● | ● | ● | ● | ● |
| Attach and remove own receipts | — | ● | ● | ● | ● | ● |
| See another person’s expense | — | — | — | ● | ● | ● |
| Approve / reject | — | — | — | ● | ● | ● |
| Mark reimbursed | — | — | — | ● | ● | ● |
| Rebill approved expenses | — | — | ● | ● | ● | ● |
| Manage categories and tags | — | — | ● | ● | ● | ● |
● = available in the interface · — = refused
Customer-portal callers are refused outright, on every expense route. An expense is an internal cost of the account, not something a client’s end user files, and letting them read the collection would expose your internal spend.
Approving is a role set, not a rank. Solidlio’s hierarchy ranks MSP technician above organization administrator, so a “minimum role” test cannot express “an administrator of this account”. A floor at MSP administrator would lock out the top role of a standalone account; a floor at organization administrator would readmit the very technicians whose expenses are under review. Approval therefore names the roles: platform administrator, SUPER_ADMIN, MSP administrator, organization administrator.
Filing an expense carries no role floor at all. Everything below approval is done by ordinary staff, so any floor at or above MSP technician would refuse organization administrator and power user — everyone in a standalone account — on the one feature whose point is that ordinary staff submit their own costs.
Administrators can approve their own expenses. A one-person MSP has nobody else to do it, and refusing would leave that cost permanently unreimbursable. The approver is always recorded, and a self-approval is labelled as such in the API response and in the detail panel rather than hidden.
Non-approvers see only their own expenses. A technician has no business reading a colleague’s hotel bill. Asking for someone else’s expense by id returns 404, not 403 — a 403 would confirm that it exists.
Walkthroughs
File an expense
- Go to Finance → Expenses (available in both the MSP and Organization portals) and press New expense.
- Enter the date, what it was for, and the merchant.
- Enter the amount before tax, and the tax paid separately. Keeping tax out of the amount is what stops it being charged to a client a second time when the invoice adds the client’s own tax.
- Pick a category and any tags.
- Choose how it was paid. Personally is the only option that produces a reimbursement.
- Save. The expense is created as a draft.
Attach a receipt
- Open the expense from the list and press Attach a receipt.
- Choose an image or PDF up to 16 MB.
- The receipt appears in the list. Press View to open it in a new tab.
- Receipts can be added and removed while the expense is draft, submitted or rejected — but not once it is approved, since that would change the evidence the approver signed off. View remains available at every stage.
Submit it and get it approved
- Open the expense and press Submit for approval. It becomes read-only to you.
- An administrator opens Finance → Expenses, filters to Awaiting approval, and presses Approve or Reject.
- Rejection requires a reason, which is shown to you on the expense.
- A rejected expense returns to your control: edit it, then press Submit for approval again. The previous rejection is cleared rather than left alongside the new submission.
Reimburse somebody
- Filter to Approved.
- Open an expense that was paid personally and press Mark reimbursed, optionally recording a payment reference such as an EFT number.
- The expense moves to Reimbursed, which is terminal.
Expenses paid on a company card or billed direct to the company never reach this step — pressing the button is not offered, and the API refuses it.
Charge an expense to a client
- When filing it, tick Rebill this to a client and give the client organization’s id. A billable expense without one is refused, because it would sit in your “ready to invoice” total forever with nowhere to send it.
- Optionally set a markup %. Leave it blank to inherit the markup configured for the account, the organization or the category.
- When an administrator approves the expense, the rebill price is calculated and fixed on the record. A later change to your markup policy will not restate an expense somebody has already signed off.
- On Finance → Expenses, in the Rebill approved expenses to a client panel, enter the client organization id. The panel previews how many expenses are eligible and what they total.
- Press Create draft invoice. One invoice line is created per expense, each priced at its approved rebill amount, and every billed expense is stamped with the invoice inside the same transaction so it can never be billed twice.
Manage categories and tags
- Go to Finance → Expenses → Settings.
- On Categories, press Add Category. A category can sit under a parent, carry an optional chart-of-accounts code, and map to a QuickBooks account id.
- Re-parenting a category rewrites the stored path of its whole subtree in one transaction, so the hierarchy cannot be left half-moved.
- On Tags, press Add Tag and pick a colour.
- Deleting is a deactivation, not an erasure. Tick Show inactive to see deactivated rows and press Activate to bring one back.
Categories and tags are shared with vendor invoice lines, so the same classification vocabulary spans accounts payable and expenses. The usage count shown on each row is the total across both.
Configuration
| Setting | Where | Effect if unset |
|---|---|---|
| Markup configuration | Purchasing → Customer markup | The rebill price equals the cost — no uplift. Resolved by contract, then account, then organization, then category. |
| Expense markup % | Per expense | Falls back to the markup configuration above. Fixed at approval either way. |
| Category | Per expense | The expense is uncategorised. It still submits, approves and invoices. |
| Tax paid | Per expense | Treated as zero. The amount is billed as if it were entirely pre-tax. |
| Currency | Per expense | Defaults to CAD. |
| Payment method | Per expense | Defaults to Personal, which makes the expense reimbursable. |
| Client organization | Per expense | Required when billable; otherwise the expense is treated as an internal cost. |
| Organization address | Organization settings | A Canadian client with no province set cannot be invoiced — the rebilling panel says so rather than billing at a guessed rate. |
Plan tiers
Expenses carries no plan gate. Every capability in this guide is available on every plan. Filing, receipts, approval, reimbursement, markup and rebilling are not restricted by subscription tier.
Troubleshooting
| Message | Cause |
|---|---|
Customer-portal users cannot file or view expenses | Expenses are an internal cost of the account. Use a staff or org-portal login. |
A billable expense needs an organizationId — the client it is rebilled to | Tick off “Rebill this to a client”, or name the client. |
Organization not found or access denied | The client organization is outside your billing reach. |
Expense category not found in your account | The category belongs to another tenant, or was deactivated. |
One or more tags do not exist in your account | Same, for tags. |
You can only edit expenses you filed | Administrators can see and decide on an expense, but not rewrite it. |
Cannot edit a submitted expense. Ask an approver to reject it back to you first. | Submission hands the record to the approver. |
Only a submitted expense can be approved (this one is draft) | Submit it first. |
Approving expenses requires an organization or MSP administrator | Technicians, power users and customers cannot approve. |
This expense is not reimbursable — it was not paid personally. Approved is its final state. | Company-card and direct-bill expenses owe nobody anything. |
Cannot attach receipts to an approved expense | The evidence behind a cleared claim is part of the audit trail. |
Receipt data is empty or not valid base64 | The upload was truncated or the file was empty. |
Receipt exceeds the 16MB limit | Photograph the receipt at a lower resolution. |
No billable, approved, un-invoiced expenses to bill | Nothing is simultaneously billable, approved and unbilled for that client. |
Cannot determine tax: this Canadian organization has no province set. | Set the organization’s province, or pass an explicit taxRate. |
Cannot delete category in use by expenses | Reassign the expenses first; the classification on approved records is kept. |
Cannot delete category with child categories | Delete or re-parent the children first. |
Tag with this name already exists | Tag names are unique within an organization. |
Limits and known behaviour
- Approval is a single step. There is no multi-stage approval chain and no value threshold that routes an expense to a different approver. The multi-step approval workflows in Purchasing apply to purchase orders and vendor invoices, not to expenses.
- A receipt is not required. An expense can be submitted and approved with no receipt attached. Approvers can reject one for that reason, but nothing enforces it.
- Administrators can approve their own expenses. Recorded and labelled as a self-approval, but not prevented.
- There is no expense report. Expenses are submitted and approved one at a time; they cannot be batched into a period claim.
- No bulk approve. Each expense is approved individually.
- Rebilling takes an organization id, not a picker. The client is identified by its
org_…id. - Rebilling is all-or-nothing per client by default. The API accepts a list of specific expense ids, but the panel bills everything eligible for that client.
- The markup is fixed at approval and never recalculated. Correcting it after approval is not possible without crediting the invoice.
- Mileage is not modelled. There is no distance-times-rate calculation; log the computed amount.
- No per-diem or policy limits. Nothing caps an expense amount by category.
- Currency is recorded but not converted. An expense in a currency other than the client’s is billed at its face value.
- Expenses do not appear on the ticket or project they reference. The
ticketIdandprojectIdlinks are recorded and filterable through the API but are not surfaced on those records’ own screens. - Reimbursement is a record, not a payment. Marking an expense reimbursed stamps who and when and an optional reference; it does not move money or create a payment record.
- No plan gating. Expenses is not restricted by subscription tier.