Customer Onboarding
Bringing a new customer live, end to end. A tenant is created empty: no master data, platform defaults everywhere. It reaches production by completing a fixed sequence of milestones, some of which block the rest. This page is the runbook that ties them together; each milestone has its own guide.
What has to be true to go live
| # | Milestone | Owner | Blocks |
|---|---|---|---|
| 1 | Single sign-on configured and tested | Customer IT + SpendOne | everything below |
| 2 | Legal entities created | Customer admin | 3, 4, 6 |
| 3 | Organization structure loaded (org units + cost centers) | Customer admin | 5, 6, 7 |
| 4 | Accounting connection live (chart of accounts, tax codes, export method) | Finance + SpendOne | go-live |
| 5 | Permission sets defined, users loaded | Customer admin | 7, 8 |
| 6 | Card program live, where cards are used | Finance + SpendOne | card spend only |
| 7 | Approval rules first-cut configured | Finance + Procurement | go-live |
| 8 | Notification defaults reviewed | Customer admin | |
| 9 | Pilot group runs real purchases end to end | Customer | go-live |
| 10 | Cutover | Both |
Steps 1 to 3 are strictly sequential. Steps 4 through 8 can run in parallel once 3 is committed.
1. Single sign-on
Set this up before importing any user. First login links an IdP identity to a pre-provisioned record by email, so the records have to exist under the addresses the IdP will present, and the federation has to exist for anyone to log in and check.
Your identity provider federates into Zitadel, the identity provider SpendOne trusts, and SpendOne configures that side. Everything about the flow, the two tenant modes and what a login does to a record is in SSO and user provisioning.
2. Legal entities
The entity is what invoices are addressed to, what books the spend, and what decides which chart of accounts and which card account apply. Nothing below can be created without one.
POST /api/v1/legal-entities
GET /api/v1/legal-entities
Mark one primary. Set the ISO 4217 default currency. Where an entity keeps its own chart of accounts rather than the tenant-wide one, enable it now: PUT /legal-entities/{code}/custom-chart-of-accounts.
3. Organization structure
Org units top-down, parents before children, each naming its legal entity; cost centers alongside them, each carrying the accounting code the export will map on.
Two routes, and the choice is about volume, not correctness:
- Bulk: the
organisational_unitsimport kind. One CSV creates the units and their cost centers together. See Data import. - Record by record:
POST /organizational-units,POST /cost-centers.
Verify the shape before moving on: GET /organizational-units/root and GET /organizational-units/{code}/hierarchy.
4. Accounting connection
Pick the export method and configure what it needs. This is the milestone that most often stalls, so start it in parallel with 5 to 7 and do not go live until one round-trip export has been validated in the customer's own system.
- Export method:
PUT /csv-export/method, one ofCSV,EMAIL,SAP,DATEVorDATEV_REWE. - Chart of accounts:
POST /accounts/import, or thegeneral_ledger_accountsimport kind. The upload takes the FI-neutralcode;name;kind;descriptionCSV underformat=generic, or a Sachkontenstamm export under the defaultformat=datev.kind=creditorloads creditor accounts rather than G/L ones, and it requiresformat=datev: the generic format acceptskind=general_ledgeronly, because creditor master data is supplier-owned. - Tax-code mappings:
GET /tax-mappings. An invoice with an unmapped VAT rate cannot be transferred;GET /tax-mappings/gapsfinds what is still missing. - The export shape: a CSV profile with its field order, delivery target and lookup tables, or, on a DATEV method, the OAuth connection and its per-entity export configs.
Full mechanics: Accounting System Integration.
5. Permission sets and users
Permission sets first, users second, because a user references a set by code.
Define one set per way of working rather than one per person: a requester set, an approver set, an accounting set, an admin set. Roles are derived from the permissions in the set, never assigned. See Roles and Permissions.
Then load the people. Use the users import kind for the initial load and SCIM or the REST API for the steady state; the whole flow, including the ordering rules and the leadership-versus-manager distinction, is in Push users and permissions.
Two things to finish before calling this milestone done:
- At least two users hold a set deriving ADMIN. One is a single point of failure.
- Every org unit has a leader. An org unit with no leader has no approval route.
6. Card program
Where the customer issues virtual cards, configure the AirPlus account on each legal entity and check that the reference data resolves. Every value sent with a card is derived from the purchase order, so cost centers and org units must be populated first, which is why step 3 blocks this one rather than the other way round.
See AirPlus DBI Field Configuration.
7. Approval rules
Start coarse and refine after a month of real data. One rule per amount band is a reasonable first cut. Rules are configured under /rules, and POST /rules/simulate dry-runs one against real data before you save it.
See Approval Rules Configuration.
8. Notification defaults
Review the platform defaults for invoice approvals, purchase requests and reminders; disable the channels the customer does not want and set the digest cadence per role.
GET /api/v1/notification-configs
PUT /api/v1/notification-configs/{type}
GET /api/v1/notification-scope-settings
PUT /api/v1/notification-scope-settings
GET /api/v1/notification-digests
9. Pilot
A small group runs real purchases from request through to a validated export. This is the only milestone that tests the configuration as a whole, and it is where a missing tax mapping or a leaderless org unit actually surfaces.
10. Cutover
Load the remaining master data, switch the steady-state provisioning path on (SCIM or your scheduled import), and open the platform to everyone.
Optional: AI assistants
Once single sign-on works and users are loaded, your people can also reach SpendOne from an AI assistant such as Claude, each as themselves. It is switched on per customer and is not part of the go-live sequence. Setup, what a security review asks, and how to remove access: MCP server.
For integrators: the same sequence as calls
All paths are tenant-scoped; the tenant comes from the token. Full schemas in the API reference.
| Milestone | Endpoints |
|---|---|
| 2. Legal entities | POST /legal-entities, GET /legal-entities |
| 3. Organization | POST /organizational-units (root first), POST /cost-centers, GET /organizational-units/root, or POST /admin/dataimport/kinds/organisational_units/upload |
| 4. Accounting | PUT /csv-export/method, POST /accounts/import, GET /tax-mappings, GET /csv-export/profiles, GET /datev/auth-url |
| 4b. Tenant config and custom fields | GET /configs/section/{section_name}, POST /configs, PUT /configs/{code}, POST /custom-fields |
| 5. Permission sets and users | POST /permission-sets, POST /admin/dataimport/kinds/users/upload, POST /users, POST /organizational-units/{code}/members/{user_code} |
| 6. Cards | PUT /legal-entities/{code}, POST /credit-cards/sync-dbi-config |
| 7. Rules | GET /rules, POST /rules, POST /rules/simulate |
| 8. Notifications | GET /notification-configs, PUT /notification-configs/{type}, GET /notification-scope-settings |
Every import upload answers 202 and tells you nothing about the rows; read the outcome from GET /admin/dataimport/jobs/{code}.
Your service account needs a permission set deriving ADMIN for all of the above.