Holded is a cloud business-management program for small companies and freelancers: invoicing, accounting, inventory, projects, CRM and staff all live in the same account. It was born in Barcelona in 2016 and has been part of the Norwegian Visma group since 2021. In Spain it is one of the most widely used ERPs among small businesses, partly because it is paid monthly and needs no installation.
What many people do not know is that Holded has an API: a door through which another program can read and write the account. With it, almost everything that someone copies by hand from one place to another today can happen on its own. This post explains what that door is, what you can automate with it and what you cannot.
What is inside Holded
It helps to start with the modules, because the API reaches as far as they do:
- Sales: quotes, proformas, orders, delivery notes, invoices, recurring invoices and credit notes.
- Purchases: purchase orders, goods receipts, supplier invoices, expenses and purchase refunds.
- Contacts: customers and suppliers, with their tax details, groups and tags.
- Inventory: products, variants, warehouses, price lists and stock movements.
- Accounting and treasury: accounts, journal entries, payments, taxes and banks.
- Projects, CRM and staff: tasks, opportunities, employees, time tracking and payroll.
Each module keeps its data in Holded. The problem for many companies is not missing information. It is that using it outside Holded means exporting it by hand, and getting data from other programs in means typing it.
What the Holded API is
The API is the official way for an external program to talk to Holded without going through the screen. You turn it on by generating a key from the account's own settings, and that key carries permissions per resource: a program can, for example, read purchase invoices and touch nothing else.
The current version is v2. With it, a program can:
- Read any list or document: invoices, purchases, contacts, products, stock, payments, journal entries, employees or time records.
- Write: create a purchase order with its numbering, register a contact with its tax ID and VAT type, upload a supplier invoice with its PDF, move stock or record a payment.
- Receive alerts through webhooks: Holded calls an address whenever an invoice, order, contact, product, payment or stock movement is created, updated, deleted or approved. A draft document can change many times; the "approved" event marks the moment the figure becomes final.
There is a monthly quota of calls that depends on the plan and can be checked from the API itself, plus a limit of requests per minute that the documentation sets at one hundred. For a small business that is plenty if the integration is done well: it syncs only what is new and keeps what it has already read.
What you can automate
There are four families, and in all of them what changes is that nobody types.
A dashboard built on Holded's data. Sales for the month and the year, margin, average ticket, active customers, stock below the minimum, outstanding receivables. It is read from Holded through the API and shown on a screen that management opens whenever they want, instead of requesting a report and building it in a spreadsheet. We describe it in dashboards and tools your ERP does not have.
Documents that create themselves. A purchase order generated when stock drops below a threshold, with its numbering and its supplier, ready to send. A supplier invoice that arrives by email and lands in Holded with the contact created, the tax ID in the right field, the country, the correct VAT type and the PDF attached. An online-shop order that appears in Holded as a sales order. It is exactly what a person would do, without the person.
Returns that come out of the ERP. Holded's invoices hold the value and the country of each operation. If a tool adds what is missing, such as the weight and the tariff code of each product, it can prepare returns like Intrastat without anyone looking up again each month what they already looked up the month before.
Holded connected to your other programs. An online shop, a CRM, a logistics system or an internal application that is not in Holded's integrations catalogue, or whose integration does not do what your company needs. With the API you build the missing piece, in both directions if necessary.
And in all of them, webhooks avoid the "every five minutes I ask whether there is anything new" pattern: Holded notifies when something happens, and the tool reacts.
What the API does not do
This is the part least talked about and the one that most decides whether an integration works out. These are things we have verified against real accounts:
- Long lists come in pages, with a cursor you have to follow to the end. An integration that does not know this reads only the first block and loses data without any error.
- Amounts arrive as text, not as numbers, and not all modules use the same decimal separator: sales and purchase documents use a point and payroll records use a comma. Convert them badly and an amount can silently become zero.
- Contacts cannot be filtered by modification date. To find out which ones changed you have to walk through all of them or subscribe to the contact-updated event. Invoices and purchases can be filtered by date.
- Updating a contact through v2 replaces the whole contact. Send only the field that changes and the rest is wiped.
- The lines of a purchase invoice do not always say which product they are. If the line was not created from the catalogue, it arrives without a reference. A system that allocates cost per product needs a mapping table and someone to resolve what does not match.
- Some data is not exposed by the API: time off, absences, teams and workplaces from the staff module are visible on screen, but there is no way to read them from outside. Employees, time records and payroll, yes.
- v2 rounds product price and cost to two decimals. If you sell at a unit price below one cent, the previous version of the API keeps it and the new one does not.
None of this prevents automation. What it does is separate an integration done in a hurry, which seems to work and fails silently, from one built by someone who has been there.
What we have built
For a medical-sector distributor that runs on Holded we built a management dashboard connected through the API, purchase orders that create themselves in Holded with their numbering and go out to the supplier, and an Intrastat tool that reads invoices, packing lists and delivery notes and remembers each product's codes and weights.
And we use Holded ourselves: our purchase invoices go in through the API with the contact, the tax ID, the country, the VAT type and the PDF, and several of the lessons in the list above came from that.
If you work with Holded and there is something you still do by hand, we describe it in more detail in Holded development and integrations. Tell us the case and we will tell you what is possible before starting.
