Basware (platform)

Basware is a purchase-to-pay and accounts-payable automation platform: purchase requisitions and orders, goods receipts, invoices and matching against orders, with REST APIs (Purchase, Invoice, Matching, Master Data) published on the Basware Developer Portal. Services and outsourced spend are executed as purchase documents rather than VMS work orders, so Basware is the system of execution for statement-of-work and managed-service decisions, not a VMS. composerID publishes the approved services decision as a Purchase API document and carries the Intent ID in the header's client-supplied externalCode, the same key Basware uses to identify externally sourced documents, then reads the order and its matched invoices back by that code.

Publish path
Direct API
composerID adapter → Basware API
Events back
Poll-first
scheduled reconciliation
API access
Open docs
public developer portal
Contract tier
Tier B
publish + poll reconciliation
composerID carrier
Stamped
purchase_order externalCode: written into the record and read back; indicative until confirmed at onboarding
Tenant configuration (mandatory fields, approval chains, picklists) is a separate gate from vendor capability: it is discovered at preflight before first publish and may need destination admin changes. How composerID connects →
Reference
API at a glance

The public API facts composerID's adapter relies on. Tenant-specific details (custom fields, picklists, approval chains) are confirmed during connection and folded into the MappingProfile.

AuthenticationOAuth 2.0 client credentials: Basware provisions the client ID and secret per customer tenant (or certified partner) rather than through self-service signup, and every call carries the bearer token. The token endpoint and any scope names are indicative until confirmed at onboarding.
API styleREST over HTTPS with JSON bodies. Imports on the Purchase and Master Data APIs are accepted and processed asynchronously (the document is validated on receipt, then applied), so composerID reads the object or its processing status back rather than assuming a synchronous create. Pagination and filter parameters are indicative until confirmed against the tenant's API version.
Base URLhttps://api.basware.com (versioned paths, v1 at the time of writing; test and regional hosts exist, so confirm the tenant's environment at onboarding)
Objectspurchase requisitions (purchase requests), purchase orders, goods receipts, invoices, matching results, and master data (suppliers, cost centres, GL accounts, users, projects)
Events / webhooksNot relied on. Basware's portal lists a notification capability for document events, but its coverage of purchase documents could not be verified offline, so composerID treats Basware as poll-first: it reads purchase orders and matched invoices back by externalCode on a schedule, and enables push only once the tenant confirms the event types it can deliver.
Rate limitsPer-client throttling with HTTP 429 on excess. Published ceilings could not be verified offline; treat any figure as indicative and back off exponentially on 429.
Readiness
Docs confidence: Public

“Docs confidence” describes how deterministic our mapping templates can be before we connect to a tenant. Even with public docs, implementations vary, especially around custom fields, approval flows and object extensions.

Deterministic mapping

Common Workforce Model fields map to known API fields. Best for standard objects (requisitions, assignments, timesheets, POs).

Tenant discovery

composerID can scan tenant configuration (custom fields, picklists, required fields) where the platform permits it, then generate a tenant‑specific MappingProfile.

Enrichment loop

If the target platform requires a field the Intent record doesn't yet have, composerID emits an enrichment_request back to the intake layer.

Mapping
Minimum viable mapping for Basware

An opinionated baseline. The platform adapter enforces additional requirements via preflight. “Tenant required” fields are discovered during connection and added to the MappingProfile.

Object Canonical fields Platform target Required status Notes
Purchase document (services)
Publish the approved services or outsourced decision
service_category, sow.summary, supplier, cost_center, amount, start_date, end_date, requester Purchase API: purchase order import (externally sourced order); purchase requisition create where the tenant's API version supports it Required Header plus one or more service lines. Coding fields (supplier, cost centre, GL account) must resolve to values read from the Master Data API before publish. Whether requisitions can be created through the API, as opposed to read, is confirmed at onboarding
Intent ID correlation
Carry the Intent ID
intent_id -> externalCode externalCode on the Purchase API document header (purchase order; the requisition where API creation is enabled) Required Stock client-supplied external reference: the key Basware uses to identify documents imported from an external system, unique per source and returned on read. Filtering reads by externalCode is indicative until confirmed at onboarding. UI deep link {tenant_host}/purchase/orders/{external_id} is illustrative
Purchase order and invoice read-back
Close the loop
po_number, status, supplier, amount, externalCode, matched_invoice_refs Purchase API: purchase orders (read); Invoice API and Matching API for invoices matched to the order Read scope only Polled by externalCode. Confirm at onboarding whether an order raised from an API-created requisition inherits the requisition's externalCode; if not, composerID correlates through the requisition reference the order carries
Idempotency & drift: publish + reconcileExpand

Publish operations are idempotent using a deterministic key {intent_id}-{intent_version}-{target_system}. Because humans can change records inside the platform, composerID supports reconciliation: it compares the platform record snapshot to the canonical intent and flags drift.

Tenant specifics
Custom fields & unique mapping

Real deployments rely on program-specific custom fields (for compliance, approvals, GL coding, rate rules or supplier constraints). composerID is designed to generate tenant‑specific mappings rather than forcing you to redesign your intake.

How scanning works

High-level flow

connect_destination() → read required fields + picklists (where permitted) → detect custom fields / extensions → build MappingProfile + validation rules → preflight intent against tenant requirements

What gets produced

Portable artefacts

MappingProfile (tenant-scoped) Capabilities matrix Required-field rules Picklist dictionaries Enrichment prompts Audit spine links (defence_file_ref)
Important: where this platform is tenant-definedExpand

Basware enables APIs per customer tenant and issues the OAuth client for them, so expect an onboarding step with Basware before a first call, and confirm the tenant's environment host and P2P edition. Only the tenant can tell us which publish path exists: whether its Purchase API version accepts requisition creation or only externally sourced purchase order import, whether externalCode on that document is filterable on reads, and whether an order raised from a requisition inherits the code. If neither document exposes a writable externalCode in the tenant's version, composerID falls back to link mode and records the Basware document number against the Intent ID on its side. Master data (suppliers, cost centres, GL accounts, users) is tenant-specific and is read before publish, and the UI route in the deep link is illustrative until checked in the tenant.

Next
Implement the adapter

Use this page alongside the API + Schemas docs to implement: destination connection, preflight validation, publish, webhook back-sync and reconciliation.