Establishing Integrations via Precoro API
Build reliable integrations with the Precoro API.
TABLE OF CONTENTS
- Necessary Integration Elements
- Best Practices for API Integrations
- How to Set Up New Integrations via API
- How to Configure Continuous Synchronization
- Working with ExternalIDs
- Error Logging with externalIntegrationLog
Necessary Integration Elements
ExternalID is a field used to map records between Precoro and a third-party system (your accounting platform, ERP, master data hub, etc.). Once two records are linked via ExternalID, you can:
- Look up Precoro records by their counterpart's ID without scanning the whole dataset.
- Decide whether to create or update an entity on either side.
- Track sync errors per record using externalIntegrationLog.
A well-designed Precoro integration includes four building blocks:
- ExternalID—the link between systems.
- modifiedSince—incremental polling.
- Webhooks—real-time push from Precoro.
- external_id[]—targeted lookup of specific records.
This guide explains how to configure and use them to set up an efficient and reliable integration.
Best Practices for API Integrations
To ensure smooth synchronization, we recommend carefully planning your integration and following the standards listed below. They'll help you optimize requests and ensure you sync relevant data.
- Comply with API limits. Precoro's API limits prevent excessive load and unoptimized requests; ensure compliance to prevent restricted or blocked. Find more information in this article Using API in Precoro.
- Implement caching. Use caching for frequently accessed or unchanging data (such as suppliers, custom item and document fields, taxes, payment terms, locations, legal entities). This can substantially reduce the API load and boost your application's performance.
- Use incremental updates. Instead of retrieving the entire dataset, use the modifiedSince filter for incremental updates with each API call. This method retrieves only the data that changed since the last sync.
- Use targeted lookups when possible. When you already know which records changed in your external system, fetch them directly with external_id[].
- Implement exponential backoff. Implement an exponential backoff strategy if you encounter rate limiting or other temporary errors. This involves retrying failed requests with an increasing delay between each attempt. The RateLimit-Retry-After parameter can help understand when the API will be unlocked again, allowing you to delay the call until then.
- Use webhooks. Webhooks allow you to receive real-time notifications of changes in Precoro, eliminating the need for frequent polling. Please see How to Set Up and Use Webhooks for more information.
How to Set Up New Integrations via API
For a new company without any existing records in Precoro, you can add new entities directly to Precoro along with the externalId field. This field should contain a unique identifier from the external system for future synchronization and updates.
If you already have some entities (like suppliers) in both Precoro and the external system, you need to sync the data between the two systems and set the externalId in Precoro for matching entities:
- Identify which fields you can use to find corresponding entities in Precoro and the external system (such as name, email, or business registration number).
- Map the entities in both systems based on the selected fields.
- For each mapped entity, set the externalId in Precoro using the PATCH method with the corresponding unique identifier from the external system.
How to Configure Continuous Synchronization
After all entities have an externalId, choose one (or a combination) of the three options below to keep Precoro and your external system in sync.
Pull with modifiedSince Parameter
The modifiedSince parameter retrieves only entities created or modified since a given timestamp. Use it for periodic, scheduled updates.
How to use it:
- Store the timestamp of the last successful sync.
- When initiating a new sync, send an API request with the modifiedSince parameter set to the stored timestamp:
GET https://api.precoro.com/suppliers?modifiedSince=2024-06-06T00:00:00 - Precoro returns only the entities created or modified since that timestamp.
- If the returned entity does not have externalId set, add a new entity to your external system.
- If the returned entity has externalId set, update an existing entity in your external system.
- If you created a new entity in the external system, update the corresponding entity in Precoro via PATCH with externalId.
- Update the stored timestamp to the current time to mark a successful synchronization.
If an entity has been modified multiple times since the last sync, it will still only appear once in the results.
When a new entity is added or an existing entity is updated in your external system, reflect those changes in Precoro:- If the entity does not exist in Precoro, add it via the appropriate POST method.
- If the entity exists in Precoro (indicated by a populated externalId), update it via PATCH (e.g.,
PATCH /suppliers/{id}).
Real-Time Updates with Webhooks
Webhooks push change events from Precoro to your system in near real-time, eliminating the need to poll.
How to use them:
- Subscribe to the relevant Precoro webhooks (suppliers, purchase orders, invoices, etc.). See How to Set Up and Use Webhooks.
- On each webhook notification:
- If the changed entity does not have externalId set, add it to your external system.
- If the changed entity has externalId, update it in your external system.
- If you created a new entity in the external system, update the corresponding entity in Precoro via PATCH with externalId.
- If the entity does not exist in Precoro, add it via the appropriate POST method.
- If the entity exists in Precoro (indicated by a populated externalId), update it via PATCH (e.g.,
PATCH /suppliers/{id}).
Targeted Lookup with external_id[]
When your external system already knows which records changed (e.g., you receive a webhook from your accounting platform), you don't need to scan Precoro. Fetch only the needed records about by their externalId.
Step 1: Store your external ID in Precoro when creating or updating a record
When creating or updating an entity in Precoro, include the externalId field with the ID from your external system:
PATCH https://api.precoro.com/suppliers/{id}
{
"externalId": "SUP-98765"
}
This links the Precoro record to the corresponding record in your accounting system.
Step 2: Retrieve records by external ID
When you need to look up a specific record (before deciding whether an update is needed), pass one or more external IDs using the external_id[] parameter:
GET https://api.precoro.com/suppliers?external_id[]=SUP-98765
To look up multiple records in a single request, pass several values:
GET https://api.precoro.com/suppliers?external_id[]=SUP-98765&external_id[]=SUP-11234&external_id[]=SUP-44401
Please note: A maximum of 200 external_id values can be passed in a single request.
Step 3: Compare and update only what has changed
Use the returned records to compare the current state in Precoro with the state in your external system. To avoid redundant updates, only send a PUT request if there is an actual difference.
Example: Syncing suppliers from your accounting system
Three suppliers were updated in the integrated system. Here's how to efficiently update the data in Precoro:
- Look up the affected suppliers by their external IDs:
GET https://api.precoro.com/suppliers?external_id[]=SUP-001&external_id[]=SUP-002&external_id[]=SUP-003 - Compare each returned supplier's fields against your accounting system's data.
- For suppliers where data is different, send a PUT request with the updated values:
PUT https://api.precoro.com/suppliers/{id} - For suppliers where nothing has changed, skip the update.
Working with ExternalIDs
Precoro supports PATCH External ID for the following entities, allowing you to update the ExternalID field for existing records:
| Suppliers | PATCH <https://api.precoro.com/suppliers/{id}> |
| Invoices | PATCH <https://api.precoro.com/invoices/{idn}> |
| Purchase Orders | PATCH <https://api.precoro.com/purchaseorders/{idn}> |
| Payments | PATCH <https://api.precoro.com/payments/{idn}> |
| Taxes | PATCH <https://api.precoro.com/taxes/{id}> |
| Payment Terms | PATCH <https://api.precoro.com/paymentterms/{id}> |
| Custom Item Fields options | PATCH <https://api.precoro.com/itemcustomfields/{id}/options/{id}> |
| Custom Document Fields options | PATCH <https://api.precoro.com/documentcustomfields/{id}/options/{id}> |
| Items | PATCH <https://api.precoro.com/items/{id}> |
| Locations | PATCH <https://api.precoro.com/locations/{id}> |
| Legal Entities | PATCH <https://api.precoro.com/legalentities/{id}> |
Documents in requests are retrieved based on IDN (not ID).
The external_id[] filter is available for the following document and entity types:
| Entity | Endpoint |
|---|---|
| Invoices | GET /invoices |
| Purchase Orders | GET /purchaseorders |
| Receipts | GET /receipts |
| Suppliers | GET /suppliers |
| Items | GET /items |
| Locations | GET /locations |
| Legal Entities | GET /legalentities |
| Taxes | GET /taxes |
A maximum of 200 external_id values can be passed in a single request.
Error Logging with externalIntegrationLog
The externalIntegrationLog parameter helps you to record error messages during synchronization of purchase orders, invoices, and receipts.
Here's how to use it:
-
If an error occurs during synchronization with an external system, log the error using the externalIntegrationLog property.
-
View error information in Precoro:
-
The error message will be displayed on the document details page.
-
If the externalIntegrationLog is populated, Precoro adds the document to the Not sent to Integration_Name infocard and assigns this document a corresponding status. Use the status and infocard to spot any synchronization problems.
-
To log an error message, include the externalIntegrationLog property in the API request payload along with ExternalID. If there are no errors during synchronization, leave the externalIntegrationLog property empty/null.
-png.png?width=670&height=341&name=Untitled%20(14)-png.png)
-png.png?width=670&height=315&name=Untitled%20(15)-png.png)
-png.png?width=670&height=543&name=Untitled%20(9)-png.png)
-png.png?width=670&height=621&name=Untitled%20(10)-png.png)