Basware Purchase-to-Pay API Manual
APIs for accounts payables, purchasing and master data
Contents
- Introduction
- List of available APIs
- Supported methods for Basware API
- Push notifications
- Usage Scenario 1: Import master data
- Usage Scenario 2: Import external purchase orders for Matching
- Usage Scenario 3: Prebook and transfer invoices to accounting
- Usage Scenario 4: Import and export procurement data
- Usage scenario 5: Error handling and monitoring
- Usage scenario 6: Import companies
- Usage scenario 7: Import users
- Usage scenario 8: Retrieve invoice status
- Usage scenario 9: Transfer enriched invoices for approval in external system
- API testing guidelines
- Common considerations
- Authentication and access rights
- API response codes
- API versioning
- Fair use practices
- Release notes
- Terminology
Introduction
The purpose of this manual is to describe Basware API integration capabilities for Master data imports and Purchase-to-Pay integration scenarios. It contains process-level instructions, end-to-end data flows, as well as recommended practices for implementation and debugging.
Basware API is a REST API available through web service calls. JSON data format is used in the message payloads.
Basware API integrations are available for the following Basware end-systems.
- Basware Network
- Basware Purchase-to-Pay
- Basware Vault
- Basware Supplier Management
P2P APIs are available through the following regions: Europe (EU), USA (US) and Australia (AU). APIs will be set up in the same region as your P2P system. Separate environments are available for test and production systems.
List of available Purchase-to-Pay APIs
The following APIs are available for transferring invoices to accounting, importing master data, user data and external purchase orders for invoice matching, as well as for importing and exporting data to and from P2P Purchase.
Importing master data | Available Basware systems |
|
AdvancedValidations | Import invoice coding row validation rules from ERP | P2P |
Accounts | Import accounts from ERP | P2P |
CostCenters | Import cost centers from ERP | P2P |
ExchangeRates | Import exchange rates from ERP | P2P |
GenericLists | Import additional coding dimensions from ERP | P2P |
PaymentTerms | Import payment terms from ERP | P2P |
Projects | Import projects from ERP | P2P |
TaxCodes | Import tax codes from ERP | P2P |
Vendors | Import vendors from ERP | P2P, Supplier Management |
Importing user master data | ||
Users | Import users |
P2P, Supplier Portal, Supplier Management, Reporting, CloudScan 3.0 |
ApplicationGroups | Control per-application log-in access (assigned to users). | P2P, Supplier portal, Supplier Management, Reporting, CloudScan 3.0 |
AdvancedPermissions | Import user approval rights information | P2P |
Importing external purchase orders for invoice matching | ||
MatchingOrders | Import order header data into matching | P2P (AP Automation) |
MatchingOrderLines | Import and update order lines and goods receipts into matching | P2P (AP Automation) |
Importing and exporting procurement data for P2P Purchase | ||
PurchaseRequisitions | Import purchase requisitions to P2P Purchase from an external system | P2P (Purchase) |
ExportedPurchaseRequisitions | Export purchase requisitions from P2P Purchase | P2P (Purchase) |
PurchaseOrders | Import Purchase Orders to P2P Purchase from an external system | P2P (Purchase) |
PurchaseGoodsReceipts | Import goods receipts to P2P Purchase from an external system | P2P (Purchase) |
ExportedPurchaseOrders | Export purchase orders and GR's from P2P Purchase | P2P (Purchase) |
Contracts | Import contract metadata to P2P Purchase from an external system | P2P (Purchase) |
ExportedContracts | Export contracts from P2P Purchase | P2P (Purchase) |
ExportedContractSpends | Export contract spends from P2P Purchase | P2P (Purchase) |
Transferring approved invoices to accounting | ||
AcccountingDocuments | Prebook invoices or transfer invoices to accounting system | P2P (AP Automation) |
Acknowledge | Mark invoice as fetched | P2P (AP Automation) |
EnrichmentResponses | Mark enriched invoice as transferred for approval in external system | P2P (AP Automation) |
PrebookResponses | Mark invoice as prebooked in accounting system | P2P (AP Automation) |
TransferResponses | Mark invoice as transferred to accounting system | P2P (AP Automation) |
PaymentResponses | Update invoice payment date | P2P (AP Automation) |
Retrieving invoice status |
||
Status | Query high-level invoice status by search criteria | P2P (AP Automation) |
Retrieving API request status / errors |
||
RequestStatus (new API) | Check target system status of sent requests. Asynchronously returns success and error messages from target systems. Replaces errorFeedbacks API. | P2P, Supplier portal, Supplier Management |
ErrorFeedbacks | Error handling. Returns errors asynchronously from Basware receiving systems. | P2P |
Push notifications | ||
Subscriptions | Subscribe to receive push notifications. | P2P |
Tasks | Check status of notifications sent by Basware API. | P2P |
Authentication | ||
Tokens | Retrieve OAUTH2 authentication tokens. | P2P, Supplier Portal, Supplier Management, Reporting, CloudScan 3.0 |
Supported methods for Basware APIs
API methods and fields
Detailed documentation for available methods and field sets for each API are described in the P2P API reference documentation.
Basware APIs support the following methods.
POST - Adds or updates records. Clears existing data from omitted fields
POST method updates the record based on externalCode field. If no record is found with given externalCode, a new record is created. All fields are updated within the record. Existing data in fields is cleared before the update.
PATCH - Updates records. Preserves existing data in omitted fields
PATCH method updates the record based on externalCode field. Difference to POST is that only fields included in the JSON in the request are updated. Data fields not explicitly included in the JSON request are left unchanged.
GET - Gets records from Basware API
GET method lists the records for a particular interface. Returned data contains all JSON fields and their values for the returned records. An externalCode can be specified as parameter to return data for only the specified record.
DELETE - Deletes records from Basware API
DELETE method deletes records from Basware API. The records are deleted from API only. To delete the records also from the data receiving Basware systems, use the data deletion mechanisms provided by each of the Basware receiving systems.
Data update scenarios
Below is an illustration of system behaviour in various data update scenarios.
Push notifications
To receive push notifications, customer needs to publish a webservice which receives notifications in a predefined format. These notifications trigger customer system to fetch documents from Basware API, which enables near real-time transfer of documents. Data export notifications are available for the following APIs. When notification is received, you can immediately retrieve data from the same API(s) as would be polled otherwise.
- AccountingDocuments
- ExportedPurchaseOrders
- ExportedPurchaseRequisitions
- ExportedContracts
- ExportedContractSpends
- RequestStatus
Subscribing to push notifications
Receiving the notifications requires customer to publish a webservice which receives task notifications in below JSON format. This webservice needs to be accessible from public Internet. Each nofitication is signed a using secret key which is self-service changeable by customer.
[
{
"taskId": "sajkhe1i87yhdgdi6sad7iyahljh1ut1",
"taskStatus": "New",
"taskType": "AccountingDocuments",
"taskSubtype": "WaitingForTransfer",
"documentId": "sajkhe1i87yhdgdi6sad7iyahljh1ut1",
}
]
When the webservice to receive notifications is up and running, customer can subscribe to receive webhook notifications. This is done by specifying your webhook endpoint address as well as details on which notifications you want to receive through the 'subscriptions' API.
When subscribing, Basware API will verify the endpoint by posting a test notification with taskType 'ConnectionTest'. Customer system needs to return a 200 'OK' HTTP response to this request for the subscription endpoint to be validated. When subscribed, notifications for any new API tasks will be sent to your specified webservice address.
Recommended usage patterns
When you receive a notification, you should do a GET request to the interface specified by the notification's (field 'taskType'). Since one GET operation can return multiple documents and new notifications may arrive before the GET operation finishes, Basware recommends following usage patterns.
Usage pattern 1: GET multiple documents in a single thread (recommended)
- Start the thread for fetching documents when a webhook notification is received.
- If a thread is already running, do not start another one before the thread completes in order to to prevent receiving same documents twice. Instead, start the new thread after task has completed in order to fetch any remaining documents.
- Use acknowledge or lastUpdated to get the next round of documents.
- Have a (nightly) task which polls for new documents in order to prevent missing documents due to network or other issues.
Usage pattern 2: Get each document by documentId
- GET each invoice individually by invoiceId as soon as the notification arrives.
- Have a (nightly) task which polls for new documents in order to prevent missing documents due to network or other issues.
- Note: Sending webhook notifications is not retried, but you can use the 'tasks' API to check for any notifications whose delivery has failed.
Validating notification signature
In order to secure your webhook endpoints, which receive calls from Basware, Basware signs the webhook events it sends to your endpoints by including a signature in each request’s header. This allows you to verify that the event requests were sent by Basware and not by an unauthorized third party. Here is how to validate the signature with example payload contents.
Request header parameter 'x-bwapi-signature-256':
Name: x-bwapi-signature-256
Value: t=1629118316,v1=55258f455c0c0427527679626967148475a12d68b19248b69a903a9970b35a02
JSON payload:
[{"taskId": "1a2ee1c0-d0ab-486d-8da6-95a8d4ac37ce", "taskStatus": "New", "taskType": "AccountingDocuments", "taskSubType": "WaitingForTransfer", "documentId": "3661018bdfe24eeea2ec271a45eca5b4", "expirationTime": null}]
Validation instructions:
1. Read request header parameter 'x-bwapi-signature-256'
- 't=1629118316' indicates the timestamp (in epoch format). Timezone: UTC.
- 'v1=55258f455c0c0427527679626967148475a12d68b19248b69a903a9970b35a02' contains the signature.
2. Check notification timestamp
- Compare timestamp t=1629118316 to current datetime. Reject the notification if it is too old.
- Useful tool for converting the time: https://www.epochconverter.com/
3. Calculate signature from request payload
- Create a string in format TIMESTAMP.NOTIFICATION_PAYLOAD
- Example: 1629118316.[{"taskId": "1a2ee1c0-d0ab-486d-8da6-95a8d4ac37ce", "taskStatus": "New", "taskType": "AccountingDocuments", "taskSubType": "WaitingForTransfer", "documentId": "3661018bdfe24eeea2ec271a45eca5b4", "expirationTime": null}]
4. Calculate HMAC-SHA256 hash from the generated string using pre-specific secret key.
- The secret key has been specified by customer when subscribing to receive push notifications through /v1/subscriptions API. The key is specified in field 'webhookAuthenticationToken' in /v1/subscriptions API. It can be changed at any time by updating the subscription. Values used in this example below:
- Secret key: ad65rujltr9093ijhdkutiyua09döijhsa76d8799w8pqugdfafjdhfkjhadls
- Resulting hash using above example values: 55258f455c0c0427527679626967148475a12d68b19248b69a903a9970b35a02
- Note the resulting hash is the same as in 'v1' on the header parameter.
- Useful tool for calculating the signature: https://www.devglan.com/online-tools/hmac-sha256-online
5. Compare the calculated signature with value given in header parameter
- Get value from 'X-BWAPI-Signature-256' header parameter, field 'v1'.
- Reject the notification if the values are different.
- Else accept the notification.
Notes: Webhook payloads may contain unicode characters in the future. If your language and server implementation specifies a character encoding, ensure that you handle the payload as UTF-8.
Usage scenario 1: Import master data
Basware solutions require a set of master data that replicate the Customer’s business model in Basware. This data is required to enhance the processing of business documents and makes it possible to bring all, or suitable parts of the validation logic to Basware.
As best practice, master data should be maintained in one central place. This data nearly always sits in an organization’s main ERP system. Basware API is designed for importing master data to Basware services from your central master data store(s). Master data can be made available in all supported Basware services.
Posting and updating basic records
The following diagram illustrates data flow for posting master data, such as basic data records and user data, to Basware API.
This is applicable for the following entity types (APIs):
- Accounts
- AdvancedPermissions
- AdvancedValidations
- ApplicationGroups
- Contracts
- CostCenters
- ExchangeRates
- GenericLists
- PaymentTerms
- Projects
- TaxCodes
- Vendors
POST operation must be used when first sending the record to Basware API. Records can be updated using both POST and PATCH operations. Basware recommends using POST operation to also update the records for most cases. PATCH may be more suitable when, for example, the sending system provides only the changed fields within the modified record.
Note that GenericLists API can be used to populate several different lists. The list key needs to be specified as additional parameter for this API.
Usage scenario 2: Import external purchase orders for Order Matching
In order matching a purchase order, purchase order line, or a goods receipt is linked to an invoice or invoice line. Basware API supports importing external Purchase orders from customer systems to order matching. Purchase orders, purchase order lines and goods receipts can be imported and updated using Basware API.
These orders need to be fully processed, approved, and marked received in external systems. These orders are called matching orders and they are used only for automatic matching to received invoices. Creating, approving and sending orders can be also done in Basware P2P using "Purchase" module, which has another set of APIs to integrate the purchasing process with external purchasing systems (see section "Usage scenario 4: Import and export procurement data").
Posting and updating matching orders
The following diagram illustrates data flow for transferring and updating order data for use in invoice matching. Purchase orders from external systems are received through the MatchingOrders (order headers) and MatchingOrderLines (order lines and goods receipts) API entity types.
Order header needs to be received before the order lines are sent. Both order headers and order lines can be updated through API when they are changed, for example when changing requested delivery date or when items have been received.
Order data validations
There are additional data validations that are applied to external purchase orders for Order Matching. Expand below section to list the validations.
Validations applied in Basware API
- NetSum and grossSum must have a same sign within an object. Example: if an order line has a postive netSum like 100,00 EUR, the grossSum, if defined, must be equal or more than zero.
- Sum for a blanket purchase order line(matchingOrderLines.matchingMode= 2) must be positive(matchingOrderLines.netSum=>0)
- Quantity for a blanket purchase order line(matchingOrderLines.matchingMode= 2) must be one(1).
- Quantity for a purchase order line must be higher than zero(matchingOrderLines.quantity >0)
- A blanket purchase order line(matchingOrderLines.matchingMode= 2) cannot require receipts(matchingOrderLines.isReceiptBasedMatching= true, matchingOrderLines.isReceiptBasedMatching= true)
Validations applied in Basware P2P
- The order must contain at least either net or gross values. Both are also OK.
- The company used on the order needs to exist in P2P.
- A purchase order line that has been already matched, cannot be deleted (matchingOrderLines.isDeleted=true).
- A purchase order line with positive total(matchingOrderLines.netSum=>0) that has been already matched, cannot be changed to have a negative total(matchingOrderLines.netSum<0)
- A purchase order line with negative total that has been already matched(matchingOrderLines.netSum<0), cannot be changed to have positive total(matchingOrderLines.netSum=>0)
- A purchase order line with isService = false that has been already matched, cannot be changed to be a service purchase order line(matchingOrderLines.isBlanketOrderLine= true)
- A purchase order line that NOT require goods receipts(matchingOrderLines.isReceiptRequired= false) and it has been already matched, cannot be changed to require goods receipts(matchingOrderLines.isReceiptRequired= true)
- A purchase order line that requires goods receipts(matchingOrderLines.isReceiptRequired= true) and it has been already matched, cannot be changed NOT to require goods receipts(matchingOrderLines.isReceiptRequired= false)
- A purchase order line that requires goods receipt based matching(matchingOrderLines.isReceiptBasedMatching= true) and it has been already matched, cannot be changed NOT to require goods receipt based matching(matchingOrderLines.isReceiptBasedMatching= false)
- A goods receipt that has been already matched, cannot be deleted(matchingOrderLines.goodsReceipts.isDeleted= true
- A goods receipt with positive total(matchingOrderLines.goodsReceipts.netSum=>0) that has been already matched, cannot be changed to have a negative total(matchingOrderLines.goodsReceipts.netSum<0)
- A goods receipt with positive quantity(matchingOrderLines.goodsReceipts.quantiy=>0) that has been already matched, cannot be changed to have a negative quantity(matchingOrderLines.goodsReceipts.quantity<0)
- A goods receipt with negative total(matchingOrderLines.goodsReceipts.netSum<0) that has been already matched, cannot be changed to have a positive total(matchingOrderLines.goodsReceipts.netSum=>0)
- A goods receipt with negative quantity(matchingOrderLines.goodsReceipts.quantiy<0) that has been already matched, cannot be changed to have a positive quantity(matchingOrderLines.goodsReceipts.quantity=>0)
Usage scenario 3: Prebook and transfer invoices to Accounting
Once an invoice has been approved in P2P, it is routed to AP/finance users for transfer to accounting. In this phase, the invoice and its coding data are transferred to an ERP system for payment. This phase can be configured to be completed automatically.
Prebooking invoices and transferring approved invoices to accounting
Prebooking and transferring invoices from Basware P2P to accounting uses AccountingDocuments API. The progress of both activities is shown in 'ProcessingStatus' field.
Invoice is made available for transfer to accounting when it has been approved in Basware P2P. When an invoice is transferred in Basware P2P it becomes available for a GET operation in AccountingDocuments API, (having processingStatus 'WaitingForTransfer'). When a transfer succeeded message is received through the paymentResponses API endpoint, invoice status in P2P is changed from “Transfer in progress” to “Processed”.
Invoice prebooking is an optional feature that can be enabled if required. In prebooking invoice data can be made available in the AccountingDocuments API before the invoice is approved. Prebooked invoices require a prebookeResponse message from ERP system. When a prebooked invoice is approved in P2P it will be made available in the accountingDocuments API as an invoice 'WaitingForTransfer'. Invoices can can be sent for prebooking automatically based on configurable rules. Manual selection of invoices to be prebooked is not yet supported.
Invoice transfer consists of the following steps
- [GET accountingDocuments]:
[Only if using prebook] Get invoices ready from prebooking (use parameter processingStatus: 'WaitingForPrebook') - [POST accountingdocuments/{invoiceId}/acknowledge]
[Only if using prebook, optional] Send technical acknowledgement (changes API processing status to 'PrebookInProgress') - [POST accountingdocuments/{invoiceId}/prebookResponses]
[Only if using prebook] Indicate to P2P did receiving system ingest the prebooking succesfully (changes API processing status to: 'Prebooked' / 'PrebookFailed') - [GET accountingDocuments]
Get invoices ready for transfer to accounting (use parameter processingStatus: 'WaitingForTransfer') - [POST accountingdocuments/{invoiceId}/acknowledge]
Send technical acknowledgement (changes API processing status to 'TransferInProgress') - [POST accountingdocuments/{invoiceId}/transferResponses]
Indicate to P2P did receiving system receive the invoice transfer succesfully (changes API processing status to: 'Transferred' / 'TransferFailed') - [POST accountingDocuments/{invoiceId}/paymentResponses]
[Optional] Indicate to P2P when invoice has been paid (changes API processing status to: 'Paid')
Expand below sections for status diagrams of invoice transfer flow in accoutingDocuments API. These describe the available status transitions in 'processingStatus' field.
AccountingDocuments processingStatuses: Main flow
Below diagram describes the main flow in terms of invoice status transitions in AccountingDocuments API.
AcccountingDocuments processingStatuses: Exceptions
Below diagram describes the available statuses in exception situations. Some of the exception statuses are currently reserved for future use. These are in grey and there is no interaction path leading to those statuses at the moment. Retransferring an invoice from P2P will start the invoice process again as in the main flow above. Note: If a prebooked invoice is returned, prebook cancellation may need to be triggered in ERP system from 'WaitingToBeReturned' status. Most returned invoices are reprocessed and retransferred again to ERP.
The following diagram illustrates the data flow for retrieving prebooked or approved invoices (AccountingDocuments) from Basware P2P to accounting and handling related response messages.
Usage scenario 4: Import and export procurement data
The procurement subset of APIs is used to integrate Basware Purchase with external purchasing systems. These APIs are not used to import orders for matching. For matching please see Usage scenario 2: Import external purchase orders for Matching. Basware Purchase handles the procurement process. It allows users to approve the purchase requisition, sends created order(s) out to supplier(s), handles any changes done in ordering phase and allows documenting that goods have been received. Orders created in Basware Purchase are also automatically available for invoice matching along with the documented goods receipts.
Procurement data integrations scenarios
- Basware API currently supports importing purchase requisition draft(s) to a specified owner on valid organization. The imported data is pre-validated by Basware Purchase making sure that document contains sufficient data required by purchase process setup. Purchase requisition can contain lines to many suppliers. Result of requisition approval process (requisition approved or cancelled) can be retrieved from Basware API as an exported purchase requisition.
- Basware API also supports importing purchase orders. Purchase orders (single supplier) are already approved before importing so they bypass approval process and are automatically sent to supplier.
- Basware Purchase supports contract based purchasing. Contract metadata can be imported through Basware API contract import. Contracts link buyer and supplier in requisition.
- Contract metadata can be exported along with total contract spend through exported contracts API. Individual spend events linked to contracts are available through exported contract spends API. The API exports spends of invoices, spend plans and purchase orders against contracts. Spend events of matching orders are not collected separately but they are included in the invoice spends. These exports are currently available only for contracts created through contract import API.
- Orders sent to suppliers can be exported from exported purchase orders API. Whenever the order status changes, the data in API is also updated.
- Basware API exported purchase orders also include goods receipts when they are registered in Basware Purchase. The goods receipts can originate from Basware API goods receipt import or Basware Purchase goods receiving UI action.
Below picture illustrates available order and requisition document flows. The operations between P2P and purchasing system are performed using Basware API.
Below diagram illustrates document flows for contract documents. The operations between P2P and contracting system are performed using Basware API.
APIs for importing procurement data:
Importing procurement data is done in similar manner as master data imports. See Usage scenario 1: Import Master data for more details.
APIs for exporting procurement data:
Exporting procurement data is done in a similar manner to invoice transfer (Usage Scenario 3: Prebook and transfer invoices to Accounting). Exported data is made available in the exportedPurchaseRequisitions/ exportedPurchaseOrders / exportedContracts / exportedContractSpends APIs. Export is confirmed by sending an acknowledgement response. Documents which have been acknowledged are marked as 'Exported' and can be filtered out from the next get request.
Usage scenario 5: Error handling and monitoring
You can check request status from end-systems (which receive data asynchronously) through ‘requestStatus’ API. When you POST records to Basware API, the posted data contents are schema validated on API layer and then distributed asynchronously to one or more target system(s).
In case an error occurs when target system(s) process the record, it will be returned through 'requestStatus' API. This API can be queried to check status of a request POSTed to Basware API. Errors returned by target systems are typically data validation errors that cannot be validated on the API layer. Examples of such errors would be "Company not found in target system" or "Cannot resolve username 'JOHNSMITH' to a valid purchase requisition owner". You can choose to query only errors or also success' responses. Retrieving only the errors should be enough for most use cases. Success responses indicate that the request has been succesfully processed in all of the target systems. If this does not occur within three hours, an error response is returned.
There is also an older 'errorFeedbacks' API, which returns only errors from P2P ('success' responses are not available). The 'errorFeedbacks' API is likely to be deprecated at a later time. There will be a 12 months notice period before eventual deprecation. Currently both APIs are functioning side by side and are returning same errors.
Retrieving request status messages from requestStatus API
Do a GET to 'requestStatus' API in order to retrieve target system processing status(es) for a POSTed request. Most often the request status response will be available within less than one minute. There are some conditions, such as a heavy initial data loads, where this can take longer. If there is no response from a target system within two hours, the request is set to ’Error’ status automatically. Checking this is done hourly, so max time until timeout is just below three hours.>
Request status is shown as 'error' if one or more of the POSTed records could not be imported to one or more of the target systems. Note that you need to query the API separately for both 'success' and 'error' statuses. If parameter 'status' is not used in the GET requestStatus query, the API defaults to returning only messages which have received 'error' status. Basware recommends following ways to programmatically query the API.
Option 1: GET by status + acknowledge
- Get by statuses: 'error', 'success'.
- This needs to be done in two GET requests.
- POST acknowledge for all requestIds (to which status response is received)
- Acknowledged status responses are no longer offered on the next GET request.
- Acknowledging changes the status: 'Error' -> 'AcknowledgedError', 'Success' -> 'AcknowledgedSuccess'.
- Repeat from step 1.
Option 2: GET by lastUpdated timestamp.
- GET with 'lastUpdated' timestamp
- Include a stored 'lastUpdated' timestamp in GET request. Get by statuses: 'error', 'success'.
- This needs to be done in two GET requests.
- Store the 'lastUpdated' timestamp locally.
- Store the latest 'lastUpdated' timestamp separately for 'error' and 'success' statuses.
- Repeat from step 1.
Option 3: Get by requestId
- Save the returned requestId when doing a POST/PATCH request to Basware API
- RequestId is returned as a header parameter in response message.
- Query the API using the requestId until a response is received.
Basware recommends doing GET requestStatus 1 minute after sending a request. If several requests are sent over time, you can do GET requestStatus once a minute until the last request has been sent. It's also a good practice to additionally poll requestStatus API every 10..60 minutes to receive responses for potentially long-running requests. If status responses to all request have been received, this polling can be stopped until a new request is sent to Basware API.
Using legacy errorFeedbacks API
[Legacy] Retrieving error messages from errorFeedbacks API
Note: The 'errorFeedbacks' API has been replaced by 'requestStatus' API and is likely to be deprecated at a later time. There will be a 12 months notice period before eventual deprecation. Currently both APIs are functioning side by side and are returning same errors.
In case an error occurs while using an API an error message is returned either in the API response message or through the ErrorFeedbacks API.
Errors from data validation in Basware API are returned immediately in the API response. These are mainly errors resulting from data structure validation and simple validations on data values.
Errors occurring when data is distributed from Basware API to the receiving Basware systems are returned asynchronously through the ErrorFeedbacks API. These include errors from validations performed in the receiving systems.
The following diagram illustrates data flow for receiving error messages.
Recommended practice is to query the errorFeedbacks API using the timestamp of the last error that has been retrieved. This will return any new errors that have occurred since the last time errors have been fetched. Errors will become available in the API at the same time as the receiving Basware systems process data. Most requests will be processed within 60 seconds. If there is considerable load errorFeedbacks will be available only after the receiving Basware systems have finished processing the data.
Usage scenario 6: Import companies
Importing companies is a network-only usage scenario (companies cannot be imported to P2P). Companies are imported through the 'companies' API. The sequence of API messages is same as when posting master data records.
The company identifier type (field identifiers.schemeId) needs to be specified from available values. Please expand the element under the flow diagram for a table of available values.
Available company identifier types
Expand below section to list available company identifier types used in companies API.
Available Global identifier types
SchemeId | Name |
Description |
Type |
External Link |
Alternative name(s) |
Alternative form(s) |
DUNS |
DUNS | A proprietary system developed and managed by Dun & Bradstreet | General | - | - | - |
EMAIL-RFC2822 |
Email address | General | - | - | - | |
GLN |
Global Location Number (GLN) | - | General | - | - | - |
IBAN |
IBAN | Bank account in IBAN format | General | - | - | - |
ISO6523-ACTORID-UPIS |
ISO 6523 | Globally unique identifiers based on ISO 6523 and PEPPOL. Prefixes denote issuing authorities (ICD) and may be known by regional names such as OVT in Finland (prefix 0037) with format of <prefix>:<organization identifier> or <prefix><organization identifier> | General | PEPPOL | - | - |
UNKNOWN |
- | No known schemeId | - | - | - | - |
Available Regional identifier types
SchemeId | Name |
Description |
Type |
External Link |
Alternative name(s) |
Alternative form(s) |
EU:VAT |
European VAT | A value added tax identification number, or VAT identification number (VATIN), is an identifier used for value added tax purposes. | Tax | Learn more > | VAT, AT:VAT, BE:VAT, BG:VAT, CY:VAT, CZ:VAT, DE:VAT, DK:VAT, EE:VAT, EL:VAT, ES:VAT, FI:VAT, FR:VAT, GB:VAT, HR:VAT, HU:VAT, IE:VAT, IT:VAT, LT:VAT, LU:VAT, LV:VAT, MT:VAT, NL:VAT, PL:VAT, PT:VAT, RO:VAT, SE:VAT, SI:VAT, SK:VAT | Country VAT code specific |
Available Country specific identifier types
SchemeId | Name |
Description |
Type |
External Link |
Alternative name(s) |
Alternative form(s) |
AT:ORGNR |
Austrian Firmenbuch-nummer | Organization number in Austria is a unique combination of 6 digits and a letter. | Business Identifier | Learn more -> | - | - |
AT:ABN |
Australian Business Number (ABN) | An ABN (Australian Business Number) is a unique number issued by the ATO (Australian Taxation Office) to all entities that are in business. | Business Identifier | Learn more -> | ABN | ISO (some can be converted to AU:ACN) |
AT:ACN |
Australian Company Number (ACN) | ACN (Australian Company Number) | Business Identifier | Learn more -> | AU:CAN, AU:ORGNR | ISO |
AT:TFN |
Australian Tax File Number (TFN) | A Tax File Number is a personal reference number used in tax and super systems. Tax File Numbers are issued by the Australian Taxation Office. | Business Identifier | Learn more -> | TFN | - |
BE:KBO |
Belgium KBO (CBE) | The KBO number is a unique 10 digit identifier issued to companies by the Kruispuntbank van Ondernemingen. | Business Identifier | Learn more -> | BE:ORGNR, BE:CBE | BE:VAT, ISO |
BE:KBO |
Belgium KBO (CBE) | The KBO number is a unique 10 digit identifier issued to companies by the Kruispuntbank van Ondernemingen. | Business Identifier | Learn more -> | BE:ORGNR, BE:CBE | BE:VAT, ISO |
CA:BN |
Canadian Business Number | A Business Number (BN) is a unique identification number that identifies a business in Canada. Business Numbers are issued by The Canada Revenue Agency. | Business Identifier | - | - | |
CA:GST |
Canadian GST | The Goods and Services Tax (GST) is a value added tax in Canada. | Tax | Learn more -> | - | - |
CA:VAT |
Canadian VAT | Canada does not use a VAT system, but bases all taxes on BN. | Tax | Learn more -> | - | - |
CH:ORGNR |
Swiss Unternehmens - Identifikations-nummer (UID) | Every company active in Switzerland receives a uniform corporate identification number (UID). | Business Identifier | Learn more -> | - | - |
CH:VAT |
Swiss VAT | A value added tax identification number, or VAT identification number (VATIN), is an identifier used for value added tax purposes. | Tax | Learn more -> | - | - |
CN:BRN |
Chinese 统一社会信用代码 (Business Registration Number or Unified Social Credit Code) | A unique company identification and tax number (TIN) for all Chinese mainland registered companies. | Tax | - | - | |
CZ:ORGNR |
Czech Republic IČO | The IČO of company Identification number is an 8 digit code (older organizations may be composed of 6 digits). | Business Identifier | Learn more -> | - | - |
DE:ORGNR |
German Steuer-nummer | Steuernummer is a unique identifier issued to each taxable individuals or entities by the German Federal Central Tax Office. | Tax | Learn more -> | - | - |
DK:CVR |
Danish CVR | The CVR nummer is a unique identifier issued by the Central Government Register. The CVR provides financial information, mission information, company filings, information about management, and corporate governance. | Business Identifier | Learn more -> | DK:ORGNR, CVR | - |
EE:ORGNR |
Estonian Organization Number | Company registry code in Estonia is a unique 8 digit number. | Business Identifier | Learn more -> | - | - |
ES:CIF |
Spanish Certificado de Identificación Fiscal (CIF) | CIF (Certificado de Identificación Fiscal) is the tax identification number for companies issued by the Registro Mercantil Central. | Tax | Learn more -> | ES:ORGNR | - |
ES:NIF |
Spanish Número de identificación fiscal (NIF) | NIF (Número de identificación fiscal), or Tax Identification Number, or Tax File Number, is used to identify a taxpayer in Spain. | Tax | Learn more -> | - | - |
FI:Y-TUNNUS |
Finnish Y-Tunnus | A Business ID ("Y-tunnus" in Finnish) is a unique eight-digit number issued to companies by the Finnish Patent and Registration Office. | Business Identifier | Learn more -> | FI:ORGNR, Y-TUNNUS | FI:VAT, ISO |
FR:SIRENE |
French SIRENE | A SIREN number is a unique French business identification number issued by the INSEE. | Business Identifier | Learn more -> | FR:ORGNR | ISO |
FR:SIRET |
French SIRET | SIRET codes are given the establishments and facilities of French businesses and nonprofit associations. | Business Identifier | Learn more -> | - | - |
GB:UTR |
United Kingdom Unique Taxpayer Reference (UTR) | A UTR (unique taxpayer reference) number is a 10-digit number completely unique to each and every UK taxpayer. | Business Identifier | Learn more -> | UTR | - |
GB:ORGNR |
United Kingdom Company Registration Number (CRN) | Company Registration Number is a unique identifier issued by the Companies House upon the registration of a company. | Business Identifier | Learn more -> | UK:ORGNR | - |
IE:ORGNR |
Irish Company Registration Number | Company registration number in Ireland is a unique 6 digit number. | Business Identifier | Learn more -> | - | - |
IN:GSTIN |
Indian GST Tax Identification Number (GSTIN) | Under the GST regime, all registered taxpayers are consolidated into one single platform for compliance and administration purposes and are assigned registration under a single authority. All of these businesses will be assigned a unique Goods and Services Tax Identification Number (GSTIN). | Tax | Learn more -> | - | - |
IT:FISCALE |
Italian Codice Fiscale | The Italian Fiscal Code Card ("Codice Fiscale" in Italian) is an identification number for companies issued by the Italian Tax Office. | Business Identifier | Learn more -> | IT:ORGNR | - |
IT:IPA |
Italian Indice della Pubblica Amministrazione (IPA) | An index of public administration (Indice della Pubblica Amministrazione - abr. IPA) is an identifier given by the Public Admininstration. | Business Identifier | Learn more -> | - | - |
LI:VAT |
Liechtenstein VAT | A value added tax identification number, or VAT identification number (VATIN), is an identifier used for value added tax purposes. | Tax | Learn more -> | - | - |
MX:VAT |
Mexican VAT | A value added tax identification number, or VAT identification number (VATIN), is an identifier used for value added tax purposes. | Tax | Learn more -> | - | - |
MY:GST |
Malaysia GST | The Goods and Services Tax (GST) is a value added tax in Malaysia. | Tax | Learn more -> | - | - |
NL:KVK |
Dutch KvK | The KvK number is a unique identifier allocated by the Dutch Chamber of Commerce. The KvK-nummer must contain 8 digits. | Business Identifier | Learn more -> | NL:ORGNR | ISO |
NO:ORGNR |
Norwegian Organisations-nummer | A unique nine-digit identifier for organizations issued by the Brønnøysund Register Centre. | Business Identifier | Learn more -> | - | NO:VAT, ISO |
NO:VAT |
Norwegian VAT | A value added tax identification number, or VAT identification number (VATIN), is an identifier used for value added tax purposes. | Tax | Learn more -> | - | ISO |
PL:KRS |
Polish Krajowy Rejestr Sądowy (KRS) | The object of the National Court Register is to provide readily-available and reliable information on the legal status of a registered entity (The Central Information of the KRS), the material elements of its financial condition and the manner of its representation. | Business Identifier | Learn more -> | KRS | - |
PT:NIF |
Portuguese Número de Indentificação Fiscal (NIF) | Tax Identification Number ("Número de Indentificação Fiscal", or "NIF" in Portuguese), also referred to as the Tax File Number, identifies a taxable entity in Portugal. | Tax | Learn more -> | PT:ORGNR | PT:VAT, ISO |
SE:ORGNR |
Swedish Organisations-nummer | Organization Number ("Organisations-nummer" in Swedish) is a 10 digit identifier for organizations issued by the Bolagsverket. | Business Identifier | Learn more -> | - | GLN, ISO |
SK:ORGNR |
Slovakian IČO | The IČO of company Identification number is an 8 digit code (older organizations may be composed of 6 digits). | Business Identifier | Learn more -> | - | - |
SK:ORGNR |
Slovakian IČO | The IČO of company Identification number is an 8 digit code (older organizations may be composed of 6 digits). | Business Identifier | Learn more -> | - | - |
UstidNr |
German Handelsregister-nummer | Handelsregister-nummer is a unique indentifier issued by the Commercial Register ("Handelregister" in German) to a legal entity. | Business Identifier | Learn more -> | - | - |
US:TIN |
United States Tax Identity Number (TIN) | A Taxpayer Identification Number (TIN) is an identification number used by the Internal Revenue Service (IRS) in the administration of tax laws. It is issued either by the Social Security Administration (SSA) or by the IRS. | Tax | Learn more -> | TIN | - |
Usage Scenario 7: Import users
Users can be imported through the 'users' API. It is possible to import user(s) to any of the following Basware applications: Purchase-To-Pay (P2P), Supplier portal (network), Supplier Management (network), CloudScan 3.0, SmartPDF. The log-in-to-application rights are managed through both 'users' and 'applicationGroups' APIs.
Before importing users, you need to have one or more application Group(s) set up for the users. Application groups provide log-in access to applications when applicationGroups are assigned to users. Each user contains a section specifying which applicationGroups the user has access to. After the application groups are set up, POST user(s) while specifying their assigned applicationGroups.
If some of your end users require access to more Basware systems than other users, you will need to define multiple applicationGroups. An example of this would be access to P2P and Vendor management for some users while most users access only P2P. If you need to define invoice approval rights for users on coding row level, you can also import these using 'advancedPermissions' API.
User management can be also done as self-service through the user management UI modules of individual applications. For SmartPDF, CloudScan 3.0 and Basware Reporting, UI based user management is handled centrally through Basware Admin web application.
Note: If you are not importing users from scratch but have an existing P2P tenant where users have already been created, it is still possible to move user maintenance to Basware API. See FAQ article "Can I migrate user maintenance to users API on an existing P2P tenant" for what needs to be taken into consideration.
Usage scenario 8: Retrieve invoice status
High-level invoice status can be queried through Basware API. The 'accountingDocuments/status' API receives search criteria (company code, invoice number, invoice date and optionally gross sum) and returns the status: ‘In Approval Process’, ‘Ready For Payment’, ‘Paid’ or ‘Rejected’. If further information is required from the invoice, the returned 'invoiceId' identifier(s) can be used to retrieve full invoice details through 'accountingDocuments' API.
A typical use case is providing self-service access through buyer supplier portal for suppliers to self-service query invoice statuses, by integrating the API to an existing buyer supplier portal. This will reduce queries that need to be handled manually by the AP team. This feature can be used for both API transferred invoices as well as invoices transferred outside of Basware API through a file-based integration. Following high-level statuses are returned:
- InApprovalProcess - Invoice has been received in Basware P2P and is being processed. This includes all invoice statuses before successful transfer to ERP.
- ReadyForPayment - Invoice is approved for payment and has been transferred to ERP system.
- Paid - Invoice has been paid.
- Rejected - Invoice has been rejected.
To enable this feature for your organization, please contact your Basware consultant or Basware Support. Invoice statuses are available for invoices that have had above status changes after the API has been enabled.
Usage scenario 9: Transfer enriched invoices for approval in external system
In addition to handling full invoice approval flow in Basware Purchase-to-Pay, it is also possible to use Basware P2P for invoice preprocessing without approval flow. Basware Invoice Enrichment offers business rules, duplicate checks, manual and automatic enrichment, search, invoice dispute, document removal capabilities on documents before they are transferred to an ERP or AP system for further processing and approval.
Transferring these enriched invoices is done through accountingDocuments API which is also used for transferring approved invoices to accounting. The 'p2pProcessingMode' parameter is used to distinguish between enriched invoices and those that are fully processed and approved for payment. Parameter value 'Standard' retrieves invoices processed using the standard P2P flow, which are already approved for payment. Value 'InvoiceEnrichment' retrieves enriched invoices, whose approval for payment is expected to be done in another system. Upgrading invoice transfer from invoice enrichment to full invoice processing in P2P requires removing p2pProcessingMode parameter and no longer sending the enrichmentResponse.
Transfer of enriched invoice transfer consists of the following steps
- [GET accountingDocuments]:
Get enriched invoices (Use parameters p2pProcessingMode: 'InvoiceEnrichment', processingStatus: 'WaitingForEnrichmentTransfer'). - [POST accountingDocuments/{invoiceId}/acknowledge]:
[Optional] Send technical acknowledgement (changes API processing status to 'EnrichmentTransferInProgress'). - [GET accountingDocuments/{invoiceId}/attachments/{attachmentId}]:
Retrieve invoice image file(s) - [POST accountingDocuments/{invoiceId}/enrichmentResponses]:
Indicate to P2P did receiving system ingest the invoice succesfully (changes API processing status to 'EnrichmentTransferred' / 'EnrichmentTransferFailed'). - [POST accountingDocuments/{invoiceId}/transferResponses]:
[Optional] Indicate to P2P when invoice has been transferred to accounting and approved for payment (changes API processing status to 'Transferred'). - [POST accountingDocuments/{invoiceId}/paymentResponses]:
[Optional] Indicate to P2P when invoice has been paid (changes API processing status to 'Paid').
Below diagram illustrates the flow for transferring enriched invoices to invoice processing system and handling related response messages.
API testing guidelines
This section aims to support creating your API implementation test plan as well as to provide guidelines on how to test. Please select the scenarios applicable to your implementation onto your test plan, as well as add customer-specific cases. While going through the scenarios, notice which ones you understand and clarify the ones you're not sure about with your consultants.
In a typical integration scenario, there are two or three actors: The customer, a Basware product consultant, and an ERP system consultant. There may also be an external company building the integration. Ideally the integration is verified before customer testing workshop(s) to work from a technical point of view and customer focuses on verifying the business logic of the integration.
As the integration endpoint(s) integrating with Basware API are generally custom built, it is important to verify the applicable scenarios to ensure smooth end-to-end functioning of the overall integration in production.
Use cases for testing - General guidelines:
Click on below section(s) to view related test cases. The tables can be copy/pasted to Excel for easy tracking of scenarios.
Usage scenario 1: Import master data
Related APIs: Accounts, AdvancedValidations, CostCenters, ExchangeRates, GenericLists, Projects, PaymentTerms, TaxCodes, Vendors.
Test scenario | How to verify |
Basic use cases |
|
Import record(s) | Check record(s) from target system(s). Verify each data field was imported. |
Deactivate/activate existing record(s) | Post record(s) with active=true/false. Verify from target system(s). |
Import multiple records | Check record from target system(s). Verify record count. |
Verify language translations (accounts, cost centers) | If language translations are user, set target system language to match imported translation and verify translation from UI. |
Verify inheritance to lower org levels works as expected (Vendors, Accounts) | Check record visibility in target system in desired organization levels. |
Use cases for vendors API |
|
Update bank account | Check changed bank account(s) in target system(s). |
Multiple bank accounts on vendor |
Post a vendor having multiple bank accounts, verify they are shown in target system(s) |
Verify correct subset of vendors is available for purchasing in P2P Purchase | Check correct set of vendors is displayed in P2P Purchase. Vendor visibility in P2P Purchase is defined through field 'orderingMethod' on vendors API. |
Verify vendors payment terms |
Verify vendor shows correct payment term. Payment terms need to be posted before vendors because they are validated during vendor import. |
Manual maintenance of specified fields (can be used e.g. for maintaining ordering information in P2P) | Modify vendor through API, check manually maintained field(s) retained their value(s). Note: This feature needs to be configured by a P2P consultant in P2P. |
Verify vendor in Basware Network |
If you are importing vendors to Basware Network, verify the vendors are imported correctly also in this system. |
Use cases for advancedValidations API |
|
Verify data contents and record count | Import data, check results in P2P. |
Verify coding row validation rules work | Create coding rows to which different validation rules are applied. Verify the validation rules are applied correctly in P2P (example: Cost center 1234 always requires a project code to be specified). Note: This feature needs to be configured by a P2P consultant in P2P. |
Initial data load |
|
Verify record count in target system matches with sent record count | Compare record count sent with amount of records received. |
Usage Scenario 2: Import external purchase orders for Matching
Related APIs: MatchingOrders, MatchingOrderLines.
Test scenario | How to test |
Verify order type(s) are selected correctly |
|
Type 1: Standard order - line has quantities and positive currency amounts. | Send 'standard' quantity based orders with 'matchingMode' = Standard. Verify in P2P, the order has both quantity and currency amounts. |
Type 2: Framework/budget/blanket order - line has no quantities, only currency amounts. | If you have framework / budget orders, send these with matchingMode = Blanket. Verify that correct order type is selected for these orders. Verify in P2P that the order has always '1' as the quantity amount. |
Type 3: Return PO - Has negative unit price and positive quantity. Typically used to return items to supplier which did not originate from the supplier, such as returning bottles or forklift pads. | If you have return orders, send these with matchingMode = Return. Verify that correct order type is selected for these orders. Verify in P2P that the order has negative unit price and positive quantity. |
Verify order data contents in P2P |
|
Values in each fields are correctly imported | Fill all the fields being imported to P2P. Verify with a checklist that each field value was imported correctly on a sample order. |
Numbers are imported correctly | Verify numbers, including negative and decimal numbers with 2-digit precision, are imported correctly to P2P. This is mainly important when orders are imported from a position-based file, where there are multiple ways to indicate both that value is negative as well as decimals. |
Vendor is recognized and available for matching |
Check that vendors vendors have been imported (or manually created) before importing orders. If you have vendor specific matching categories in P2P, match the order in such a category to verify matching has recognized the vendor. Note: Vendors need to be imported before orders, as upon order import the vendor is verified. |
Order lines include planned additional costs |
If you have planned additional costs on the order lines and want to match against those, make sure they are sent to Basware API. Verify the additional cost lines in P2P. |
ExternalCodes are unique within the document (also on lines and coding lines) | Verify with programmer that externalCodes are generated so they are both unique as well as maintain their values during document updates. Verify this also on sample order(s) in matchingOrders and matchingOrderLines APIs. |
Include invoices amounts and quantities |
|
Verify invoiced sums and quantities | If you are importing partially invoiced orders, verify the invoicedQuantity and invoiced[Net/Gross]Sum fields are filled. Verify alsot that only the uninvoiced amounts remain available for matching in P2P. Note: These fields exist on both order lines and goods receipts. |
Update existing order(s) |
|
Add new order line(s) to an existing order | Verify new line(s) arrived in P2P. |
Close order line(s) | Send a line with isClosed = true and send a corresponding invoice to automatic matching. The invoice should no longer go to 'waiting for goods receipts' status when there is unmatched quantity on the order line (and no unmatched goods receipts). |
Delete order line(s) | Send line with isDeleted = true (and having no goods receipts). Verify you cannot match against an invoice against the line. |
Verify there is a ~5 second delay between API operations to same order |
Test below cases likely to produce multiple API operations and verify the entire order data is updated in P2P within ~ 1 minute after the operation.
The order is locked when is is being updated in P2P. If there are API operations to same order while the previous operation is still being carried out in P2P, those will result in timed retries. Many such operations simultaneously can result in tens of minutes wait time before entire data is updated to P2P. |
Add goods receipt(s) to existing order line(s) |
|
Technical option 1: POST whole matchingOrderLine including all goods receipts (recommended) |
Add a new goods receipt in ordering system, verify goods receipt(s) arrived in P2P. In this option the goods receipt is added through matchingOrderLines API by using a POST operation to update entire contents of the order line, along with goods receipts. |
Technical option 2: PATCH existing matchingOrderLine to add new goods receipt |
Add a new goods receipt in ordering system, verify goods receipt(s) arrived in P2P. In this option the goods receipt is added through matchingOrderLines API by using a PATCH operation to add a new goods receipt to existing matchingOrderLine contents. This option is generally not recommended unless sending system is not able to send full order line data. Drawbacks include that same order line can no longer be updated using POST operations unless that POST operation includes the previously PATCHed goods receipts (else the goods receipts would be removed from the order line). |
Cancel goods receipt(s) | |
Option 1: Using negative quantity on another goods receipt line | Indicate goods receipt "cancellation" by sending a new goods receipt having a negative quantity. Verify invoice gets matched as desired, taking the negative gr into account. |
Option 2: Using 'referenceGRExternalCode' to indicate cancelled goods receipt | Indicate goods receipt cancellation by sending a new gr having a negative quantity and a reference to the gr being cancelled (field: 'referenceGRExternalCode'). Verify the quantity to match shown on original goods receipt shows the sum of both the original gr as well as the cancellation. |
Verify order source system is specified |
|
SourceSystem is specified in 'sourceSystem' -field to enable different matching rules based on ERP. | Verify 'sourceSystem' field is populated on order header (matchingOrders API). This is important especially if you will have different matching rules based on the source system of the order. |
Verify product code matches with invoices |
|
Product code matches with what is on invoice(s) | Send orders for several suppliers. Verify that product codes used in matching matches with product codes the supplier specifies on their invoices. |
Verify criteria for best fit grouping is sent |
|
Delivery notes are grouped to enable "best fit" matching | Verify that 'bestFitGrouping' field contains a grouping criteria, such as delivery note, datetime of receival or technical receipt number. This can be used to group goods receipts during matching. |
Verify contents of matched coding lines |
|
Dimensions and cost allocation | Match an invoice against the order line and verify all coding dimensions, including taxes, show correct values in P2P. |
One product allocated to multiple coding lines (multiple account assignment) | Post an order line having multiple coding rows. Verify the costs are split (between different cost centers, accounts, etc) on matched coding lines as expected. |
Verify quantity unit handling |
|
Unit price reflects quantity unit correctly in cases where boxes of n pcs are converted to individual pcs, etc. | If boxes / packages of n units are being converted to individual units in the integration, verify that the unit price reflects the correct unit (such as a box of items vs. a single item). |
Quantity unit on order line matches to quantity on vendor invoice(s). | Send orders for several suppliers. Verify the quantity unit sent on orders matches with the quantity unit on supplier invoices. |
Verify order line specific matching rules |
|
Is a goods receipt required for matching (true / false) | Send order lines with both 'isReceiptRequired' true and false (applicable only if you have both types). Verify P2P requires / does not require the receipt for matching. |
Coding row generation: Per goods receipt / per PO line. | Send order lines with both 'isReceiptBasedMatching' true and false (applicable only if you need both coding row generation options). Verify the generated coding rows in P2P when matching an invoice line to an order line having more than one goods receipt. |
Is over receival allowed (generally used for products whose weight will vary, such as meat and fish) | Send order lines with both 'isOverreceivalAllowed' true and false (applicable only if you have both over receivable and non over receivable items). On an over receivable line, send a larger quantity amount in the (sum of) goods receipts than is specified on order line and verify P2P allows matching. |
Is additional approval required on self approved order lines | When additional approval is required after matching on self approved order lines, indicate this on order line (field: 'isSelfApproved' = true) and matching configuration in P2P. Verify P2P requires the additional approval. |
Initial data load |
|
Verify order count in target system matches with sent record count |
Compare record count sent with amount of records received. Note: The initial import can take several hours depening on the amount of PO data. Vendors need to be imported before orders, as upon import the vendor is verified. |
Usage Scenario 3: Prebook and transfer invoices to accounting
Related APIs: AccountingDocuments (including acknowledge, prebookResponses, transferResponses, paymentResponses). Verify transfer results in target system.
Scenarios for Non-PO invoices:
Test scenario | How to verify |
Verify invoice / transaction types |
|
Standard invoice - with positive sum | Transfer invoice to ERP and verify results. |
Credit note - with negative sum | Transfer invoice to ERP and verify results. |
Foreign invoice - with foreign currency | Transfer invoice to ERP and verify results. |
Mixed invoice - with both positive and negative sums on coding lines | Transfer invoice to ERP and verify results. |
Downpayment - PO reference on invoice but processed as a non-PO invoice. | Transfer invoice to ERP and verify results. Some ERPs use a separate transaction for receiving this type of data. |
Invoice having fixed asset transactions | Transfer invoice to ERP and verify results. Some ERPs use a separate transaction for receiving this type of data. |
Prebooking (see 'prebooking' section below) | Prebook invoice to ERP and verify results. Also includes |
Verify invoice data contents |
|
Values in each field are transferred correctly to ERP | Fill all the fields in P2P which are imported to ERP. Verify with a checklist that each field value was imported correctly on a sample invoice. |
Numbers are transferred correctly to ERP | Verify numbers, including negative and decimal numbers with 2-digit precision, are imported correctly to ERP This is mainly important when invoices need to be imported from a position-based file, where there are multiple ways to indicate both that value is negative as well as decimals. |
VAT scenarios |
|
Invoice with partially deductible VAT | Transfer invoice to ERP and verify results. |
Invoice with reverse VAT code | Transfer invoice to ERP and verify results. |
Invoice with 100% VAT | Transfer invoice to ERP and verify results. |
Invoice with multiple VAT codes (multiple coding lines) | Transfer invoice to ERP and verify results. |
US tax handling (based on addresses and product codes) | May be posted directly as a lump sum to VAT account, sometimes without VAT codes. |
Verify technical items in customer side of the integration |
|
When a next page of invoices is available in Basware API, it is automatically fetched and transferred to ERP |
Transfer more invoices in one operation from P2P than are fetched in one GET accountingDocuments API operation. Technical option 1: GET one page of invoices, noticing a continuationToken is returned. Acknowledge the invoices before doing next GET operation. Keep doing GET operations until continuation is no longer returned, which indicates last page of invoices. Technical option 2: GET one page of invoices, noticing a continuationToken is returned. Keep GET:ting next pages until last page (continuationToken is no longer returned). Verify that the integration keeps calling GET accountingDocuments using a continuationToken to keep fetching next page(s) of results. The default pageSize is up to 100, and can be set to a smaller value during testing. |
Integration polls for invoices in appropriate statuses |
Check have the invoice processingStatuses which are polled from accountingDocuments API been explicitly decided. Options: WaitingForTransfer (to get invoices waiting for transfer), WaitingForPrebook (if prebooking in use), WaitingToBeReturned (invoices returned to start of processing), WaitingToBeRemoved (removed in P2P), WaitingForPrebookCancellation (reserved for prebook cancellation functionality, not yet implemented), WaitingToBeCompleted (manually marked as 'transfer completed'). Without specifying the statuses, all invoices will be returned, also ones which have been previously transferred. |
Prebooking to ERP |
|
Prebooking | Prebook invoice to ERP, verify data contents. |
Prebook response | Send a prebook response from ERP. Note: Failed prebook responses are not supported at this time, but a workaround is available. |
Remove prebook entry in ERP (optional) | Invoice may be removed / reprocessed in P2P. In such cases the processingStatus in accountingDocuments API will show as WaitingToBeReturned / WaitingToBeRemoved / WaitingForPrebookCancellation. In such a case you may want to remove the existing prebooking entry in ERP. Note: Prebook cancellation along with 'WaitingForPrebookCancellation' API status is not yet implemented and is reserved for future use. |
Finalizing invoice in ERP when actual transfer to accounting is done | Transfer an invoice to accounting after it has been approved in P2P for transfer to ERP. This invoice needs to have been previously prebooked to ERP. Verify the results in ERP. |
Transfer to ERP |
|
Transfer invoice to accounting (done above several times) | Transfer invoice to ERP, verify data contents. |
Transfer response case 1: Transfer accepted | Send 'success' transfer response from ERP after ERP has succesfully received the invoice. Verify invoice status is shown as 'Processed' in P2P. |
Transfer response case 2: Transfer failed | Send 'failed' transfer response from ERP after ERP has failed to receive the invoice. Verify invoice status is shown as 'Transfer failed' in P2P and an error message from ERP is shown in invoice history log in P2P. |
Payment response | |
Payment response | Send a payment response after a previously transferred invoice gets paid, verify the payment data is visible on the invoice in P2P. |
Scenarios for PO invoices (invoices matched to orders):
Test scenario | How to verify |
Verify invoice and updated order data in receiving system(s) |
|
Verify any order -related fields are received correctly in ERP. | Match an invoice to an order in P2P and transfer the invoice to ERP. Check results especially for matching -related fields (order number, coding generated based on order data, sums, etc). |
Invoiced quantities are updated correctly in ordering / warehouse management system (update available inventory) | Match an invoice to an order in P2P and transfer the invoice to ERP. If you are transferring invoiced quantities back to an ordering / inventory management system, verify they are reflected correctly in the receiving system. |
Verify ERP handling for different coding line types | |
Rows with quantity difference(s) | Match an order to an invoice having quantity difference(s) on some rows. Verify data is received correctly in receiving system(s). |
Rows with over receival allowed |
Match an order having more quantity received than was ordered to an invoice. This commonly happens when ordering variable weight products, such as fish / meat. Verify data is received correctly in receiving system(s). |
Rows with price difference(s) |
Match an order to an invoice having price difference(s) on some rows. Verify data is received correctly in receiving system(s). Price differences can be allocated to coding lines in several ways (verify the ones used):
|
Invoice line matched against a negative GR | If you match invoices against negative goods receipts (such as a credit note for a return), verify data is received correctly in receiving system(s). |
Coding lines created manually after automatic matching | Match an order to an invoice. Add manually created coding line(s), which do not have an equvalent line on the order. Verify data is received correctly in receiving system(s). |
Verify handling of additional costs |
|
Option 1: Additional cost line(s) exist on order (planned additional cost) |
Match an order already containing a product line for additional cost to an invoice. IN this case, it is recognized from invoice and matched as any other order line. Verify data is received correctly in receiving system(s). |
Option 2: Additional cost line(s) do not exist on order (unplanned additional cost) |
Add coding (automatically or manually) for invoice lines which are not contained in any order line. Verify data is received correctly in receiving system(s). Allocation options (verify the ones used):
|
Verify above for each of the used order types |
|
Type 1: Standard order - line has quantities and positive currency amounts. | |
Type 2: Framework/budget/blanket order - line has no quantities, only currency amounts. | |
Type 3: Return PO - Has negative unit price and positive quantity. Typically used to return items to supplier which did not originate from the supplier, such as returning bottles or forklift pads. | |
Verify above for applicable order creation channels |
|
Approved order - imported through matchingOrders API |
"Matching order" imported through 'matchingOrders' and 'matchingOrderLines' APIs. These orders are already approved and ready for matching. |
Approved order - imported through Basware Anyerp adapter | "Matching order" imported using Basware Anyerp adapter. These orders are already approved and ready for matching. |
Requiring approval - manually created in P2P Purchase | Order created manually in Basware P2P Purchase. This order needs to be approved in P2P Purchase before it can be matched to an invoice. |
Requiring approval - imported through purchaseRequisitions API | Order imported as a requisition to P2P Purcase through 'purchaseRequisitions' API. The requisition needs to be approved and converted to an order in P2P Purchase before it can be matched to an invoice. |
Requiring approval - imported through purchaseOrders and purchaseGoodsReceipts APIs | Order imported through to P2P Purcase through 'purchaseOrders' API. Goods receipts need to be done manually in P2P Purchase or imported through 'purchaseGoodsReceipts' API. |
Requiring approval - imported through Basware anyerp adapter | P2P Purchase requisition / order imported through Basware Anyerp adapter. |
Usage Scenario 4: Import and export procurement data
Related APIs: Contracts, PurchaseRequisitions, PurchaseOrders, PurchaseGoodsReceipts, ExportedPurchaseRequisitions, ExportedPurchaseOrders.
Import scenarios:
Test scenario | How to verify |
Import contracts | |
Contract(s) are imported successfully | Import through contracts API, verify from P2P that each data field matches sent values and appropriate fields are visible in P2P. |
Supplier(s) are recognized on contract | Import contract, verify that P2P shows imported suppliers on contract. |
Currency amount type is specified correctly (gross vs net) | Verify sums and unit prices in P2P, compare with prices in source system. Amount type (gross or net) is specified through field 'amountType' in contracts API. |
Link to external contract URL opens up correctly | If external URL link to contract is included on the contract, click on it to verify it can be accessed from P2P. |
Import purchase requisitions | |
Purchase requisitions(s) are imported successfully | Import through purchaseRequisitions API, verify results from P2P. Verify each data field matches sent values and appropriate fields are visible in P2P. Verify data is valid (lines, coding, taxes, products, etc.). Check if there are validation errors in P2P or in errorFeedbacks / requestStatus APIs. |
Owner, supplier(s) and category code(s) are validated in P2P | Verify these fields have values in P2P right after import. These fields will be empty if their validation failed against existing data in P2P. |
All lookup list values have been validated in P2P | Verify all lookup lists have values and that those were not cleared. P2P may clear values that are not found on lookup lists (such as cost centers, etc). Some of the values may be required before requisition is sent to approval process. |
ExternalCodes are unique within the document (also on lines and coding lines) | Verify with programmer that externalCodes are generated so they are both unique as well as maintain their values during document updates. Verify this also on sample order(s) in purchaseOrders API. |
Currency amount type is specified correctly (gross vs net) | Verify sums and unit prices in P2P, compare with prices in source system. Price type (gross or net) is specified through field 'priceType' in contracts API. |
Delivery address(es) are correct | Verify requisition has correct delivery address(es). One address can be specified for the whole requisition or different addresses can be specified for individual requisition lines. |
Requisitions are mapped correctly to spend categories (spend categories are created manually in P2P) | Check spend category mappings in P2P as well as the categories used in spend reports in Basware Analytics. |
Requisition is sent to approval automatically after import | Verify imported requisition was automatically sent to approval in P2P. Note: This is controlled by 'sendToProcess' field in purchaseRequisitions API. |
Approving requisition creates order(s) which can be processed in P2P or exported to ERP | Approve an imported requisition in P2P Purchase. One or more orders should be created based on the requisition data. Depending on settings and imported data, the order may require additional approval. |
Requisition is grouped into order(s) as expected, based on grouping criteria (when the requisition is approved) | Import a requisition having multiple lines. Use different values for fields used to group requisition lines into order(s). These include for example supplier, payment- and delivery condition (if configured as order split criteria). |
Order is sent sent to supplier (when requisition is approved) |
Approve an imported requisition in P2P Purchase. An order should be created. Verify the order is automatically sent to supplier. Verify both sending methods:
|
Copy of order is sent to owner when requisition is approved (if configured in field 'orderRecipientType') | If owner should receive a copy of the order sent to vendor in email when the order is placed, verify this is specified in purchaseRequisitions API 'orderRecipientType' field and a copy of the order is received in email. |
Order(s) created from requisition(s) matches correctly against data on vendor invoice(s) | Import a requisition to which a previous supplier invoice has been received. Import the supplier invoice to a test P2P instance and verify matching results. |
Import purchase orders |
|
Purchase order(s) are imported successfully | Import through purchaseOrders API, verify results from P2P. Verify each data field matches sent values and appropriate fields are visible in P2P. Verify data is valid (lines, coding, taxes, products, etc.). Check if there are validation errors in P2P or in errorFeedbacks / requestStatus APIs. If the order cannot be found in P2P as an order, it might be found as a requisition having invalid data. In this case, check which data was invalid from the requisition. Orders are technically handled as requisitions that are auto-approved and then a corresponding order is automatically created. |
Purchase order with more than 200 rows is imported correctly (requires several API requests). | Import an order having more than 200 lines. First POST the first page with processingStatus = 'Uncompleted'. Next, PATCH the order with additional lines. On the last PATCH request send processingStatus = 'ReadyForImport'. Verify the order got succesfully imported to P2P with expected amount of order lines. |
Supplier(s), delivery receiver(s), category code(s) and owner are validated in P2P | Verify these fields have values in P2P right after import. These fields will be empty if their validation failed against existing data in P2P. |
ExternalCodes are unique within the document (also on lines and coding lines) | Verify with programmer that externalCodes are generated so they are both unique as well as maintain their values during document updates. Verify this also on sample order(s) in purchaseOrders API. |
Currency amount type is imported correctly (gross vs net) | Verify sums and unit prices in P2P, compare with prices in source system. Price type (gross or net) is specified through field 'priceType' in contracts API. |
All lookup list values have been validated in P2P | Verify all lookup lists have imported values and that those were not cleared. P2P may clear values that are not found on lookup lists (such as cost centers, etc) |
Verify order was automatically sent to supplier |
Import a purchaseOrder. An order should be created and sent to supplier (although this can be changed in P2P settings). Verify the order is automatically sent to supplier. Verify both sending methods:
|
Delivery address(es) are correct | Verify requisition has correct delivery address(es). One address can be specified for the whole requisition or different addresses can be specified for individual requisition lines. |
Order matches correctly against data on vendor invoice(s) | Import an order to which a previous supplier invoice has been received. Import also corresponding goods receipts (or create them manually in P2P if goods receipt import is not used). Import the supplier invoice to a test P2P instance and verify matching results. |
Import purchase goods receipts |
|
Add new goods receipt(s) |
Import a purchaseOrder through purchaseOrders API or create one manually in P2P. Next, POST goods receipt(s) to it using purchaseGoodsReceipts API. Verify the goods receipt(s) are available in P2P.
For importing goods receipts to the correct purchase order, you need to know the externalCode of the purchase order as well as of the purchase order line. For purchaseOrders imported through purchaseOrders API, corresponding imported values can be used directly. For other orders, these values can be retrieved through exportedPurchaseOrders API. |
Cancel existing goods receipt(s) |
Send a purchaseGoodsReceipt cancellation (reversal) to an existing goods receipt line. Verify in P2P the goods receipt is cancelled and has the cancelled amount substracted from what is available for matching. Goods receipt cancellation is indicated by fields referenceGRDocumentExternalCode, referenceGRLineExternalCode, quantity in purchaseGoodsReceipts API. |
Export scenarios:
Test scenario | How to verify |
Export purchase requisitions to ERP |
Note: Requisition export needs to be enabled in P2P (in purchase config) |
Export approved purchase requisition(s) |
|
Export rejected purchase requisition(s) |
|
Verify appropriate process is in place to handle cases where requisition was rejected by ERP | Export a document which gets rejected by ERP (for example due to an expired project code). Go through how such documents will be modified and re-imported to ERP. |
Export purchase orders to ERP |
Note: Order order export needs to be enabled in P2P (in purchase config) |
Export purchase order(s) created from requisition |
Export an order through exportedPurchaseOrders API. Verify that order data is received correctly in ERP.
|
Export purchase order(s) created through purchaseOrders API |
|
Verify appropriate process is in place to handle cases where order was rejected by ERP | Export a document which gets rejected by ERP (for example due to an expired project code). Go through how such documents will be modified and re-imported to ERP. Note that order is already sent to supplier even if ERP rejects the order. |
Cancel existing purchase order(s) | Cancel an existing order, verify the order has been appropriately cancelled in ERP. |
Add goods receipt(s) to existing purchase order(s) |
Verify ERP receives goods receipts correctly in applicable scenarios:
|
Usage scenario 5: Error handling and monitoring
Related APIs: RequestStatus, ErrorFeedbacks.
Test scenario | How to verify |
Handling synchronous errors |
|
API client retries when transient error is received | Verify from people who built the integration that there is a mechanism for retrying when transient error occurs. You could also log when these happen and then check the logs. |
Non-transient errors are logged and sent to personnell | Create a data error, such as a field having too long value. Make sure there is a mechanism in place to notify relevant people during production use of such cases. |
Handling asynchronous errors option 1: RequestStatus |
|
Option 1a: GET by status + acknowledge |
Option 1: Get only errors (default) Option 2: Get also acknowledgements of succesful processing of requests (queried through a separate status) |
Option 1b: GET by lastUpdated timestamp |
Option 1: Get only errors (default) Option 2: Get also acknowledgements of succesful processing of requests (queried through a separate status) |
Option 1c: GET by requestId | |
Handling asynchronous errors option 2: errorFeedbacks (legacy) |
|
Option 2a: GET by status + acknowledge | |
Option 2b: GET by lastUpdated timestamp |
Usage scenario 6: Import companies
Related APIs: Companies.
Test scenario | How to verify |
Import companies to Basware network |
|
Import companies to Basware network (note: network tenant model required) | If P2P is also used, make sure company structure is aligned or backfill from P2P. |
Usage scenario 7: Import users
Related APIs: Users, ApplicationGroups, AdvancedPermissions.
Test scenario | How to verify |
Verify login mechanism(s) |
|
Forms login (username and password) |
POST a user which gets authenticated by username and password. Verify the user can login. |
SSO login (requires SSO setup) |
POST a user which gets authenticated by Single Sign-On. Verify the user can login. Option 1: Single identity provider in use Option 2: Multiple Identity Providers in use |
Multi-factor authentication (requires Basware Access) |
POST a user which has Multi-Factor Authentication enabled. Verify the user can login and user needs to enter additional account verification in order to login. |
Basic scenarios (users API) |
|
Check data fields |
POST user through users API, verify user data in target system(s). Pre-requisite: user access is granted to the target system through applicationGroups. |
Change user data, verify results |
POST an update to an existing user, verify user data in target system(s). Note: The usr needs to be changed through the API. Any user field manually changed in one target system will not be reflected in any other system. |
Deactivate / activate user based on loginAllowed: true / false | POST user, change 'loginAllowed' field value. Verify user can / cannot login in target systems. Pre-requisite: user access is granted to the target system through applicationGroups. |
Deactivate / activate user based on validFrom, validTo dates | POST user, change 'loginAllowed' field value. Verify user can / cannot login in target systems. Note: Network consumer does not support validFrom and validTo -dates. Pre-requisite: user access is granted to the target system through applicationGroups. |
P2P user groups are imported correctly | Create user groups in P2P and assign external codes to them through P2P UI. Post users having 'externalGroupCode' field values match to the values defined in P2P. Also remove existing user groups and verify results in P2P. Note: There is a parameter in P2P which needs to be enabled to remove existing groups from users. |
Login access to applications (applicationGroups API) | |
Verify user can access applications as specified through application groups | Create applicationGroups through applicationGroups API. If you require access to more than one Basware application, specify this in the applicationGroup(s). Post users having appropriate applicationGroups assigned to them in users API, verify the users can / cannot login to applications as expected. |
Coding row approval rights (advancedPermissions API) | |
If coding row approval rights are used, verify the user can approve coding lines according to specified criteria. |
If you use coding row approval rights, load these through advancedPermissions API. Verify the data was loaded correctly in P2P (data contents, counts). Verify the users can / cannot approve coding lines according to the criteria specified. |
Validate user in different target systems |
|
Purchase-to-Pay | Verify user data in application. |
Network | Verify user data in application. |
Reporting | Check user who should be able to login to the application can login and user who should not be able to cannot login. This application does not show user data. |
CloudScan 3.0 | Check user who should be able to login to the application can login and user who should not be able to cannot login. This application does not show user data. |
Common considerations when using Basware API
Please take the following into account in order to achieve smoothly running integrations.
Records are identified for update based on ‘externalCode’ field value
ExternalCode field is present in all record types. This field is used to identify the record to be updated and must be unique per record within an interface (single Account, Cost Center, etc.). More specifically, it must be unique within an Entity Type (Accounts, CostCenters, etc).
Exception to this is GenericLists, where the externalCode must be unique within the target list (specified by the ‘listKey’ parameter).
Maximum length of the externalCode is 36 characters – this needs to be maintained in cases where externalCode is concatenated from other key values, such as [companyCode]_[AccountCode]. The max length of these values combined must not exceed 36 characters.
Inactivating records is done by updating the record
Records are inactivated by updating the record with field ‘active’ = ‘false’. There is no explicit delete (or delete/insert) functionality.
Changed records are forwarded from Basware API to receiving Basware systems
To improve end-to-end integration throughput, received data is compared record-by-record to current data stored in the Basware API. Only records with changed data (compared to what is already in Basware API) are forwarded to receiving systems.
Basware API is primarily designed to receive incremental data changes. It is still possible to send a full data set (such as full list of suppliers) once per night.
GET method returns the latest version of data posted to Basware API
Changes made manually to master data, for example through user interfaces, are not reflected in returned results. GET is mainly intended as a tool to check what has been posted to Basware API.
Number of records per message is limited per API
Consecutive API calls are needed for processing large amounts of records. The record limit varies by endpoint. It is 100 for AccountingDocuments and MatchingOrderLines, 200 for purchaseOrders, PurchaseRequisitions, vendors and 500 for most other endpoints. Please distribute the payload over multiple requests to stay below the respective limits.
Please send the ‘x-amz-meta-continuationtoken’ parameter value returned in previous GET response header as parameter in the GET request header in order to retrieve the next batch of items.
API responses make use of HTTP redirects
Programs using Basware API need to handle redirects either at the application layer or the HTTP layer. Please verify all HTTP request headers are correctly included in the redirected request (the second request after receiving a redirect) including HTTP standards such as Authorization and Date.
JSON parsing requirements for API clients
Basware reserves the right to introduce new non-mandatory fields to existing API data schemas (new fields may be added to Accounts, Vendors, AccountingDocuments, etc). Please make sure your API client is configured to read data from records returned from API using named JSON fields and does not assume the fields come in a predefined sequence of elements.
Basware also reserves the right to send only those fields in API responses, where the field value is not null. Please make sure your API client checks whether the field exists in the received JSON before attempting to parse it’s contents.
The above kinds of changes are considered minor (non-breaking) changes and may be performed by Basware upon discretion at any time. Changes where, for example, a mandatory field is added or removed, or existing field names are changed, are considered major (breaking) changes and will be published under a new API version (‘v2/accounts’ instead of ‘v1/accounts’, etc)
Automatically populated fields in API
The following fields are automatically populated and should be omitted with POST and PATCH requests. They will be visible with GET requests and therefore are present in API schema definitions.
- LastUpdated (All APIs)
- Buvid (Vendors)
Authentication and access rights
Authentication
Basware P2P APIs support following authentication types to authenticate API clients. You can choose the authentication type when requesting Basware to create your API user.
- Basic HTTP authentication
- OAUTH2 (client credentials flow)
All communication is secured by using the HTTPS protocol (HTTP over TLS, TLS version 1.2 or later). You must make all API requests over HTTPS. API requests made without authentication will fail.
Using basic authentication
HTTP Basic authentication relies on passing a username and password along with each API request. The username and password are encoded into the HTTP Authorization request header.
Using OAUTH2 authentication
Basware P2P APIs support the OAUTH2 client credentials flow. The client credentials flow works by first requesting an access token from a dedicated API endpoint /v1/tokens using a client id and client secret (sent as Basic Auth header), then passing that token in subsequent API operations. This token is passed as a bearer token in the Authorization request header. You must specify the API operations permitted by the token when requesting the access token. Tokens have a limited validity time (default 1 hr), after which a new token needs to be requested. Token validity time can be specified while requesting the oAUTH2 credentials from Basware. Minimum allowed token validity time is 5 minutes and maximum is 24 hrs.
There is a separate swagger page for the APIs used to retrieve OAUTH2 tokens. Most integration tools have Oauth2 support built-in for both requesting an access token and using it in subsequent calls.
API operations permitted by an access token are called scopes. Available scopes are limited by access rights granted to API user. When returning requested scopes Basware API will ignore any missing or misspelled scopes. Scopes need to be always specified. For best security, recommended practice is to request only the scope(s) required for each API operation during production use. Multiple scopes can be specified by separating them with a blank space.
Each scope in Basware API consist of API name + allowed operation. Following operation are available:
- 'read' operation grants access to GET operations
- 'write' operation grants access to POST and PATCH operations
- 'delete' operation grants access to DELETE operations.
Available scopes used are listed below.
Scopes for P2P APIs
accountingDocuments.read accountingDocuments.write accountingDocuments.delete
accounts.read accounts.write accounts.delete
advancedPermissions.read advancedPermissions.write advancedPermissions.delete
advancedValidations.read advancedValidations.write advancedValidations.delete
applicationGroups.read applicationGroups.write
companies.read companies.write
contracts.read contracts.write contracts.delete
costCenters.read costCenters.write costCenters.delete
errorFeedbacks.read errorFeedbacks.write errorFeedbacks.delete
exchangeRates.read exchangeRates.write exchangeRates.delete
exportedPurchaseOrders.read exportedPurchaseOrders.write exportedPurchaseOrders.delete
exportedPurchaseRequisitions.read exportedPurchaseRequisitions.write exportedPurchaseRequisitions.delete
lists.read lists.write lists.delete
matchingOrderLines.read matchingOrderLines.write matchingOrderLines.delete
matchingOrders.read matchingOrders.write matchingOrders.delete
paymentTerms.read paymentTerms.write paymentTerms.delete
projects.read projects.write projects.delete
purchaseGoodsReceipts.read purchaseGoodsReceipts.write purchaseGoodsReceipts.delete
purchaseOrders.read purchaseOrders.write purchaseOrders.delete
purchaseRequisitions.read purchaseRequisitions.write purchaseRequisitions.delete
requestStatus.read requestStatus.write
taxCodes.read taxCodes.write taxCodes.delete
taskStatus.read
users.read users.write users.delete
vendors.read vendors.write vendors.delete
Scopes for push notification APIs
subscriptions.read subscriptions.write subscriptions.delete
tasks.read
Note that scopes need to be separated by a blank space. If copy/pasting multiple lines from the list above, please remove the new line characters. Scope 'taskStatus.read' is required to query status of long-running DELETE operations.
Please make sure to have a mechanism implemented to automatically fetch a new token when your existing token expires. This is especially important for long-running tasks, such as a large initial load of matching orders which may take more time than the max validity time of one token (24hrs). Basware API does not support refresh tokens. You'll need to request a new token each time using the client id and client secret (same way as when getting the token for the first time).
API consumers can validate token signature using metadata from API endpoint /.well-known/jwks.json. Each token returned by Basware API is signed by by one of the public keys listed in the returned payload. The access tokens are returned as jwt tokens. Their contents can be viewed through jwt.io.
If you are currently using basic authentication and want to switch to using OAUTH2, you can request OAUTH2 authenticated API user credentials from Basware. You will receive a new set of credentials. Your existing basic authentication API credentials will continue to work alongside the new OAUTH2 ones. When you have fully made the switch, please request Basware to disable your previous API user credentials.
Access rights
API user access rights control what the user can do when interacting with Basware API. One user can be granted several kinds of access (read, write, delete) to several API endpoints. It is possible for example to have read access to AccountingDocuments and read+write access to Contracts on the same API user. You can request an API user having a combination of read/write/delete access to any of the APIs listed in this manual. If no restrictions are specified API users will have full access (read+write+delete) to all P2P APIs. Changes to API access rights will take effect within 5 minutes from making the change.
Available access rights are:
- 'read' grants access to GET operations
- 'write' grants access to POST and PATCH operations
- 'delete' grants access to DELETE operations.
For full access, each of the above needs to be granted to user. Write alone does not grant access to GET operations and delete alone does not grant access to GET/POST/PATCH.
If the API user uses OAUTH2 for authentication, there are two levels of granting access. The first level is on the API user, specifying what access is granted overall for the user. The second level is controlled by the customer when requesting scopes on OAUTH2 access tokens. The scopes on the token determine which API operations are allowed when passing the token. If scopes are requested to API operations which is not granted to an API user, such scopes will not be granted through access tokens either.
Common scenarios where access restrictions are needed are:
- Restricting access for technical partners, who GET/POST data only to one API, such as Contracts.
- Restricting access for a reporting integration, which for example is only allowed to GET records
API response codes
The various response codes are outlined in the API definition per endpoint and method. Overall API response guideline:
- 200/OK: Credentials validated, task executed successfully
- 302/Redirect: Request redirected
- 404/Not Found: Credentials validated, that particular data item does not exist (e.g. unknown Account)
- 403/Forbidden: Credentials invalid
- 405/Method Not Allowed: Typically occurs on POST Acknowledge, when the invoice has been already acknowledged. Each invoice can be acknowledged only once.
- 411/Length Required: URI is not correct, check for typos (case-sensitive). This usually occurs on POSTs.
- 502/Bad Gateway:
- Case 1: Too many simultaneous requests, please retry in a few seconds. This is the case when same request(s) to the same endpoint normally go through.
- Case 2: URI or endpoint does not exist, check for typos (case-sensitive). This is the case when same request(s) to the same endpoint always get 502.
- 503/Service unavailable: Too many simultaneous requests, please retry in a few seconds.
API Versioning
Every time there is a backwards-incompatible change to the API, a new major version will be released. This major version is part of the URL path. The current major version is v1.
Unless informed by our technical support department that we are discontinuing support for a particular API version, you do not need to switch API versions. We will let you know at least 12 months in advance if an old API version is to be deprecated.
Major change
Change that requires changes from the API consumer before the new version can be taken into use. This change would for example be a change to existing fields or adding new mandatory fields.
Minor change
Minor change is a new version of the API that is backward compatible and does not require changes from the API consumer. Minor change would consist of for example adding a new non-mandatory field. Please make sure your API client accepts new non-mandatory fields.
Fair use practices
Data import APIs
Data import APIs are intended only for importing data from Customer systems to Basware systems. Data imports are one directional, APIs will not reflect any changes done in Basware P2P.
Main use cases
- Import new data entities (Method: POST)
- Update existing data entities (Method: PATCH/POST)
Development phase / Supporting use cases
- Getting data entities by external code (Method: GET) – This use case is mainly intended for development phase usage. Not to be used as part of production usage.
- Deleting data from API layer – This use case is mainly intended for development phase usage. Not to be used as part of production usage.
Posting all entities vs changed entities
Best practice is to update entities one by one as they change as opposed to batch operations. If batch operation (posting all entities, not only changed ones, every time) is used then that should be done infrequently. Optimal frequency depends on how many data entities there are in total and should be discussed with Basware especially if there are very high number of entities
Invoice transfer APIs
Invoice transfer APIs are meant for transferring invoice data to ERP system when an invoice is ready for payment. The process includes polling the AccountingDocuments API for new invoices, fetching invoices and posting transfer and payment responses.
Polling for invoices that are ready for transfer
- GET with status ‘ReadyForTransfer’ from AccountingDocuments API
- It is recommended to use one polling process only to avoid duplicate requests
- Polling frequency best practice is once per minute
Rate limits for APIs
The API platform has been built to scale up and down automatically. Sudden peaks in usage can potentially cause timeouts as it may take a moment for the platform to scale up. Please avoid very high concurrency especially when starting an integration flow. Please ensure you have retry mechanisms in place to handle any failed requests.
We may temporarily or permanently block access if you are calling the API too frequently or you are requesting an unreasonable amount of data in a short time period. The limits should only affect scripts that are malfunctioning or attempting to make too many requests in parallel.
Update frequency for Matching Order Lines
- Do not POST or PATCH updates to the same MatchingOrderLine more often than every 10 seconds.
Release notes
Release notes are updated after API release to production.
Release to production | API | Change category | Notes | Type |
---|---|---|---|---|
20.8.2020 | v1/matchingOrderLines | Data validation change | Ignore deleted goods receipts when validating PO line quantities | Bug fix |
20.8.2020 | v1/Users | Other | Password field is no longer returned in API responses | Bug fix |
17.9.2020 | v1/vendors | New fields | Added new non-mandatory fields vendorClass, deliveryLocation and orderingMessageLanguage | New feature |
17.9.2020 | v1/errorFeedbacks | Other | ErrorFeedbacks API returns messages in correct order when not using lastUpdated -parameter | Bug fix |
1.10.2020 | v1/purchaseGoodsReceipts | Data validation change |
Validate correct set of field are posted for both standard and reverse GRs. New validation: If field 'referenceGRDocumentExternalCode' doesn’t have a value, then:
|
New feature |
19.10.2020 | - | Swagger update |
Updated Swagger documentation
|
Documentation |
19.10.2020 | v1/exportedPurchaseRequisitions | New API | Introduced new API for exporting purchase requisitions from Basware P2P. | New feature |
26.10.2020 | v1/purchaseRequisitions | Data validation change | Increased max number of purchase requisition lines from 100 to 200. | New feature |
07.12.2020 | v1/vendors | Data validation change | Increased max length of 'groupName' field (in customFields block) to 500 chars. |
New feature |
07.12.2020 | v1/users | Data validation change | Increased max length of 'externalGroupCode' field (in groups block) to 260 chars. | New feature |
14.12.2020 | - | Swagger update |
Updated Swagger documentation
|
Documentation |
20.1.2021 | - | Swagger update |
Updated Swagger documentation
|
Documentation |
20.1.2021 | - | Other |
Made Basware APIs available in Canada region (api.ca.basware.com) |
New feature |
25.1.2021 | v1/applicationGroups | Data validation change |
Added CloudScan to list of applications supported in applicationGroups. |
New feature |
3.3.2021 | v1/requestStatus | New API |
Introduced new API for tracking request status in target systems, supporting both 'error' and 'success' responses. |
New feature |
17.3.2021 | v1/genericLists | Data validation change |
'Inherit' field is no longer mandatory. |
Bug fix |
17.3.2021 | v1/purchaseGoodsReceipts | Data validation change |
'lineReceivings' block is now mandatory. Added API validation as field is required by target system (P2P). |
Bug fix |
16.4.2021 | v1/genericLists | Data validation change |
Added target list specific field validations. |
New feature |
27.4.2021 | v1/users | Other |
Fields not included in PATCH method payload no longer get default values. |
Bug fix |
5.5.2021 | v1/contracts | New fields |
Added new non-mandatory fields orderSpend, spendPlanSpend, invoiceSpend. |
New feature |
12.5.2021 | v2/projects | New API |
Released v2/projects API. |
New feature |
12.5.2021 | - | Swagger update |
Updated swagger to OAS3 specification. |
Documentation |
10.6.2021 | - | Swagger update |
Fixed functionality to POST requests through Swagger page |
Bug fix |
22.6.2021 | - | Developer site update |
Updated API developer site with
|
Documentation |
4.8.2021 | v1/accountingDocuments | New fields |
Added field 'OriginService' to accountingDocuments API. |
New feature |
14.8.2021 | v1/subscriptions, v1/tasks | New API |
Enabled pilot use of push notifications APIs. |
New feature |
16.8.2021 | - | Other |
Deprecated usage of TLS1.0/1.1. |
Other |
28.8.2021 |
v1/purchaseOrders, v1/purchaseRequisitions, v1/exportedPurchaseOrders, v1/exportedPurchaseRequisitions |
New fields |
Added support for blanket orders to purchasing APIs. New fields: validityPeriodStartDate, validityPeriodEndDate, orderType, releaseOrdersRequired, hidePricesFromSupplier, parentOrderNumber, parentOrderexternalCode, parentOrderExtNumber, parentOrderLineExternalCode. |
New feature |
6.9.2021 |
v1/purchaseRequisitions |
New fields |
Enhanced ways owner of requisition can be identified: Added new field "ownerExternalCode". Made existing field "ownerLogin" not mandatory. Added validation that at least one of the following owner -identifying fields are not empty (same validation as used in purchaseOrders API): ownerExternalCode, ownerLogin, ownerEmail. |
New feature |
6.9.2021 |
- |
Swagger update |
Minor clarifications based on consultant feedback. |
Documentation |
14.9.2021 |
v1/contracts, v1/purchaseOrders, v1/matchingOrderLine, v1/lists |
Other |
Fixed bug introduced by a previous enhancement where PATCH operation reset values for those enum fields which were not included in the PATCH payload. |
Bug fix |
23.9.2021 |
v1/accountingDocuments, v1/matchingOrderLines, v1/contracts |
New fields |
Added new field 'contractNumber' to accountingDocuments and matchingOrderLines APIs. Changed length of 'referenceCode' field in contracts APi from 100 to 255 chars. |
New feature |
28.10.2021 |
v1/requestStatus |
Other |
Fixed handling of lastUpdated field value in requestStatus API in the case when a request times out. |
Bug fix |
3.11.2021 |
v1/purchaseOrders, v1/exportedPurchaseOrders, v1/purchaseRequisitions, v1/exportedPurchaseRequisitions |
New fields |
Added field 'otherOrderingEmail'. Updated descriptions of ordering email related fields. |
New feature |
12.11.2021 |
v1/requestStatus |
Other |
Reliability improvement to requestStatus of concurrent API operations done to same record. |
Bug fix |
18.11.2021 |
v1/purchaseOrders, v1/exportedPurchaseOrders, v1/purchaseRequisitions, v1/exportedPurchaseRequisitions |
New fields |
Added new fields 'CountrySubEntity', 'CountrySubEntityDescription' to the address blocks in P2P Purchase APIs. |
New feature |
14.12.2021 |
v1/tokens |
New API |
Added OAUTH2 support for Basware P2P APIs. |
New feature |
5.1.2022 |
- |
Swagger update |
Made following unused fields hidden: GenericLists, Accounts, Costcenters APIs -> 'parents' -block. Users API: 'spendingLimits, PurchaseManagerUserLocations, PurchaseManagerModuleAccess, PurchasingGroups' -blocks. GenericLists API: 'inherit'. Minor documentation updates based on feedback. |
Documentation |
7.4.2022 |
v1/exportedcontracts, v1/exportedContractSpends |
New API |
Introduced new APIs for exporting contracts and contract spends from Basware P2P. |
New feature |
14.4.2022 |
v1/exportedPurchaseRequisitions |
Other |
Field 'sendingMethod' made not mandatory in 'orderGrouping' block. |
Bug fix |
26.4.2022 |
- |
Swagger update |
Show oAuth2 as a supported authentication method. Small clarifications to documentation. |
Documentation |
4.5.2022 |
v1/accountingDocuments, v1/purchaseOrders, v1/exportedPurchaseOrders, v1/purchaseRequisitions, v1/exportedPurchaseRequisitions |
Other |
Improved handling of HTTP redirects. Feature is manually activated per tenant. |
New feature |
9.5.2022 |
v1/users |
New fields |
Added new field 'accessEnabledLogin. |
New feature |
11.5.2022 |
v1/accounts |
New fields |
Added new fields 'taxCode', 'text1' - 'text5'. |
New feature |
24.5.2022 |
v1/taxCodes |
New fields |
Added new field 'taxGroup', removed validation on 'taxPercent' and 'taxPercent2'. |
New feature |
13.6.2022 |
- |
Other |
Introduced new API redirect method by default for new API customers. The redirect now points to a Basware domain. No change to redirect method for existing customers. |
Other |
14.6.2022 |
v1/vendors |
New fields |
Added new field 'linkedBbanOrIban' to allow linking IBAN to BBAN when importing account data to P2P. |
New feature |
17.6.2022 |
v1/accountingDocuments |
New fields |
Added new fields 'text84' and 'text85' to 'codingRows' block. |
New feature |
18.6.2022 |
v1/accountingDocuments |
Bug fix |
Added limit to store only last 100 responses per accountingDocument. |
Bug fix |
3.8.2022 |
- |
Swagger update |
oAUTH2 URL in swagger dynamically pointed to correct API environment. |
Bug fix |
10.8.2022 |
- |
Swagger update |
Drop-down menu added to change between swagger instances. |
New feature |
31.8.2022 |
v1/users, v1/vendors, v1/purchaseRequisitions, v1/purchaseOrders, v1/purchaseGoodsReceipts, v1/exportedPurchaseRequisitions, v1/exportedPurchaseOrders |
Bug fix |
Relaxed email validation in Basware API to allow special characters such as !#$%&'*+-/=?^_`{|}~ in email addresses. |
Bug fix |
12.9.2022 |
v1/requestStatus |
Enhancement |
Added support for 'Basware Access' consumer. |
New feature |
21.9.2022 |
v1/users, v1/vendors, v1/purchaseRequisitions, v1/purchaseOrders, v1/purchaseGoodsReceipts, v1/exportedPurchaseRequisitions, v1/exportedPurchaseOrders |
Bug fix |
Fixed regression issue related to above where some of the emails were not validated correctly. |
Bug fix |
6.10.2022 |
v1/contracts |
Enhancement |
Increased maximum value allowed in field 'total'. |
New feature |
7.10.2022 |
v1/applicationGroups |
Enhancement |
Added new application codes for SmartPDF service. |
New feature |
11.10.2022 |
v1/requestStatus |
Enhancement |
Added field 'genericListKey' to indicate which of the lists was used with 'lists' API. |
New feature |
19.10.2022 |
v1/exportedPurchaseRequisitions, v1/exportedPurchaseOrders |
Bug fix |
Removed email validations from PO/PR export APIs. |
Bug fix |
8.11.2022 |
(all apis) |
Enhancement |
Reduced min length of companyCode fields to 1. |
New feature |
13.11.2022 |
v1/purchaseRequisitions, v1/purchaseOrders |
Enhancement |
Added 'refundLine' field in order to support refund lines. |
New feature |
5.1.2023 |
v1/purchaseGoodsReceipts |
Enhancement |
Moved 'deliveryNoteNumber' field to header in Swagger. Posting it on line level keeps being allowed (takes value from first line). |
New feature |
5.1.2023 |
- |
Swagger update |
Improved readability through more consistent use of typeface. |
New feature |
6.1.2023 |
v1/requestStatus |
Bug fix |
Showing company requests sent to P2P as skipped instead of remaining in progress. |
Bug fix |
12.1.2023 |
v1/requestStatus |
Bug fix |
Fixed bug causing request status not to be updated correctly in some cases. |
Bug fix |
17.1.2023 |
v1/purchaseRequisitions, v1/purchaseOrders, v1/purchaseGoodsReceipts |
Enhancement |
Added validation to prevent using duplicate externalCode values on child objects withing a record. |
New feature |
24.1.2023 |
v1/lists |
Enhancement |
Allow using negative values in numeric fields. |
New feature |
27.1.2023 |
- |
Swagger update |
Minor clarifications to swagger documentation based on received feedback. |
New feature |
31.1.2023 |
v1/accountingDocuments |
Bug fix |
Fixed rare issue when posting several responses at the same time to same document. |
Bug fix |
2.2.2023 |
v1/requestStatus |
Bug fix |
Restored missing matchingOrders status entries occurring in a specific scenario. |
Bug fix |
14.3.2023 |
v1/purchaseGoodsReceipts |
Enhancement |
Zero is now allowed as a price on a refund line. |
New feature |
16.2.2023 |
v1/vendors |
Enhancement |
Increased max length of fields 'orderingLanguage' and 'orderlingMessageLanguage' to 10 chars. |
New feature |
10.3.2023 |
v1/purchaseRequisitions, v1/purchaseOrders, v1/exportedPurchaseRequisitions, v1/exportedPurchaseOrders |
New fields |
Added new field 'leadTime'. |
New feature |
13.3.2023 |
v1/requestStatus |
Bug fix |
Fixed bug causing request status not to be updated when multiple requests sent simultaneously to update the same record. |
Bug fix |
23.3.2023 |
v1/accountingDocuments |
New fields |
Added additional header fields Text31-60, Num21-30, 'RemovalReason', 'RemovalReasonComment'. |
New feature |
11.5.2023 |
v1/costCenters |
Bug fix |
Fixed issue with companyCode filter on GET requests |
Bug fix |
16.5.2023 |
v1/accountingDocuments |
Bug fix |
Fixed requestStatus handling of accountingDocument responses. |
Bug fix |
24.5.2023 |
v1/matchingOrderLines |
New fields |
Added new fields 'notifyFault' and 'comment'. |
New feature |
7.6.2023 |
v1/accountingDocuments |
New fields |
Added new field section 'invoiceLines'. |
New feature |
13.6.2023 |
v2/projects |
Bug fix |
Fixed 'companyCode' filter on GET operation |
Bug fix |
18.6.2023 |
v1/requestStatus |
Bug fix | Fixed pagination issue when GET requestStatus response size exceeded 6mb. | Bug fix |
2.8.2023 |
v1/requestStatus |
Bug fix |
Fixed acknowledge operation for items with status 'NotProcessed' |
Bug fix |
8.8.2023 |
v1/accountingDocuments |
Data validation change | Increased max length of 'conditionType' field to 250 chars. | New feature |
24.8.2023 |
- |
Swagger update |
Minor updates to swagger documentation based on received feedback. |
New feature |
2.9.2023 |
- |
Enhancement |
Security enhancements to handling of traffic to Basware API. |
New feature |
13.9.2023 |
v1/requestStatus |
Bug fix |
Fixed issue with 'Projects' API versioning on requestStatus API. |
Bug fix |
25.9.2023 |
v1/purchaseRequisitions, v1/purchaseOrders, v1/exportedPurchaseRequisitions, v1/exportedPurchaseOrders |
New fields |
Added field 'manufacturerProdutCode' to P2P Purchase APIs. |
New feature |
12.12.2023 |
v1/accountingDocuments/status |
New API |
Introduced new API for checking invoice status. The API receives search criteria such as Company code, Invoice Date and Invoice Number and returns high-level document status such as 'In approval process', 'Ready for payment'. |
New feature |
4.1.2024 |
- |
Bug fix |
Fixed regression on checking task status of API delete operations. |
Bug fix |
7.1.2024 |
v1/matchingOrderLines |
Enhancement |
Implemented support for very large order lines (>6mb) |
New feature |
23.1.2024 |
v1/accountingDocuments/{invoiceId}/paymentResponses |
Bug fix |
Fixed regression on sending paymentResponse to invoices transferred to accounting before 2021. |
Bug fix |
2.4.2024 |
v1/accountingDocuments |
New fields |
Added following fields for government tax clearing: clearingReferenceId, clearingCountry, clearingDate |
New feature |
12.4.2024 |
v1/accountingDocuments/{invoiceId}/attachments |
New API |
Introduced new API for retrieving invoice images and attachments for invoices transferred to accounting. |
New feature |
16.4.2024 | v1/accountingDocuments | Bug fix |
Fixed regression when using removalReason value 'other'. |
Bug fix |
18.4.2024 | - | Bug fix |
Fixed regression on routing API requests in test environment. |
Bug fix |
4.4.2024 | v1/dataExtracts | New API |
Introduced new API for extracting raw data from P2P automation. These APIs are documented under the 'Data Access APIs' section. |
New feature |
3.5.2024 | v1/accountingDocuments | Bug fix |
Fixed regression regarding negative tax amounts on an invoice. |
Bug fix |
30.5.2024 | v1/accountingDocuments | Enhancement |
Introduced additional values to 'removalReason' field. |
New feature |
13.6.2024 | v1/accountingDocuments/{invoiceId}/enrichmentResponses | New API |
Introduced API support for transferring unapproved invoices for later approval for payment in ERP. |
New feature |
Release notes are available from 20.8.2020 onward.
Terminology
Entity type: Named structured types with a key. They define the named properties and relationships of a record. Examples: accounts, costCenters, matchingOrderLines.
Record: Instances of entity types (e.g. account, opportunity).
Accounting system: Computer program used for keeping accounts. Commonly included in an ERP system as a module.
ERP: Enterprise resource planning (ERP) is defined as the ability to deliver an integrated suite of business applications. ERP tools share a common process and data model, covering broad and deep operational end-to-end processes, such as those found in finance, HR, distribution, manufacturing, service and the supply chain.
Basware P2P: Basware Purchase-to-Pay, in this manual refers to Basware Purchase-to-Pay solution.
Basware AP Automation: Accounts Payable Automation solution. Part of Basware P2P.
Basware Purchase: Basware Purchase solution. Part of Basware P2P.