Skip to main content

How to generate and use the Holded API

Connect Holded with other applications using an API Key

Written by Natalia López

What is the Holded API?

The Holded API (Application Programming Interface) allows you to connect your account with other applications to automatically exchange information.

It is the system that enables different programs to work together and share data in a structured way.

For example, you can:

  • Create contacts from another CRM.

  • Generate invoices from an e-commerce platform.

  • Sync products or stock.

The API works through requests that allow you to:

  • Retrieve information (GET)

  • Create data (POST)

  • Update data (PUT)

  • Delete data (DELETE)

These actions are performed through a specific endpoint (the URL that defines the operation). For example:

https://api.holded.com/api/v2/invoices

Although Holded provides native integrations with various applications, if you need custom automation you can use the API to connect Holded with any other software your company uses.


Who can use the API?

The API is available on all paid plans. It is not available on the Free plan.

To generate an API Key, you must:

  • Have an active plan other than Free.

  • Have access to the Developers section.

☝🏼 You can grant access to users with the developer role, or with a custom role with access to the Developers section so they can access and edit the API.


How to generate an API Token

An API Key is the key that identifies your Holded account in each request. It must be included in all API calls to indicate which account the operation belongs to. You can create as many API Tokens as you need.

To generate one, follow these steps:

  1. Go to your account (top left) and click on Settings.

  2. In the Developers section, click on Credentials.

  3. Click Add API Token.

  4. You will be able to select what permissions that API Key has.

    ☝🏼 If you need to access the v1 API you can do so via the Go to Api Keys v1 banner.

  5. Click Create Token.

  6. An alphanumeric code will be generated that you can copy.

Please note that the API Token will only be shown once, when it is created. After that, for security reasons, it will appear masked in Holded in the following format: <XX>.

⚠️ The API Key is private. You must not share it or make it public.


How to access the API documentation

Once the API Key has been generated, you can check the technical documentation to learn about the available endpoints and actions.

To access it:

  1. Click on Developers > Credentials.

From there you can consult:

  • Available endpoints across the different Holded modules: Sales, Inventory, Accounting, Treasury, Contacts, CRM, Projects.

  • Required parameters.

  • Call examples.

  • Responses and error codes.


How to test the API before integrating it

Before implementing a full integration, it is recommended to test the API to ensure the required actions work correctly.

You can test it using external tools such as Postman.

Postman is a testing tool that allows you to send requests to the API and check how it works before integrating it into a final development.

To test it:

  1. Download and install the Postman application.

  2. Select the corresponding method (GET, POST, PUT or DELETE).

  3. Enter the endpoint you want to use.

  4. In the Authorization section, add:

    • Auth Type > Bearer Token

    • Token > API Token generated in Holded.

  5. Add the required parameters in the Body.

  6. Send the request and review the response.

Make sure to add the full Token, not the masked version shown in the format <XX> when copying it from Holded.

If everything works correctly, you will be able to carry out the final integration in your system.


API call limits and usage

Depending on your commercial terms, there is a monthly limit based on your subscription plan.
You can check the limits in the API documentation or on the Holded pricing page.

You can check your monthly API usage directly in your Holded account.

There you can see the calls you’ve made and your account’s limit.


Frequently Asked Questions about the Holded API

Which roles can access the API?
Roles with access to the Developers section, such as the default Developer role.

For custom roles, you can also enable the Developers option, with access to API Tokens or Webhooks.

⚠️ Please note that this option only applies to accessing or editing API V2. Any user with an Owner or Admin role will have access to API V1.


Can permissions be configured for each token?
Yes, they can.

The API doesn’t inherit permissions from user roles, but you can restrict it to certain actions: when creating the API Token, you can choose which modules it can access and whether it has read, write, or full access.


How can I check my monthly API usage?

You can check your monthly API usage directly in your Holded account.

You will be able to review the calls made and the limit you have on your account.


What support does Holded provide for API developments?

API integrations must be developed by a technical specialist.

The support team can clarify doubts regarding specific fields or endpoints, but does not develop custom integrations.

If you do not have a developer, you can contact a Solution Partner.


Until when can I use the API v1?

The API v1 key will remain available until further notice. We will give advance notice before retiring it.


Can I access private projects through a GET projects endpoint?

No, that's not possible. A user's project member role takes precedence over the API token's access to project information. The API can only retrieve information for public projects.


How does pagination work?

When you call a listing endpoint, the response includes:

  • items: the array of results for the current page

  • cursor: an opaque string to pass as a parameter for the next page

  • has_more: a boolean indicating whether more results exist

You can use these as parameters to filter the information you retrieve.

The cursor is a kind of “bookmark” that marks where the next page begins. It’s a string with no human-readable meaning, so you don’t need to interpret it.

To move to the next page, simply take the cursor value and add it as a parameter in your next call. The API reads it, knows where to continue from, and returns the next set of results with a new cursor. Repeat the process until has_more is false.

Imagine you want to retrieve all the journal entries for an account between two dates. There are many results, so the API splits them into pages.

  • First call: no cursor, returns the first page:

GET https://api.holded.com/api/v2/ledger-entries?start_date=2025-12-31&end_date=2026-06-26&account=70500002

The API responds with the first results and indicates at the end that there is more data:

{ "items": [ ... ], "cursor": "697897a629cf44c5f50ff679", "has_more": true }

  • Second call: copy the cursor exactly as is and add it as a parameter:

GET https://api.holded.com/api/v2/ledger-entries?start_date=2025-12-31&end_date=2026-06-26&account=70500002&cursor=697897a629cf44c5f50ff679

The API returns the next page with a new cursor:

{ "items": [ ... ], "cursor": "a1b2c3d4e5f6a7b8c9d0e1f2", "has_more": true }

  • Third call: repeat with the new cursor:

GET https://api.holded.com/api/v2/ledger-entries?start_date=2025-12-31&end_date=2026-06-26&account=70500002&cursor=a1b2c3d4e5f6a7b8c9d0e1f2

This time has_more is false, so there are no more pages:

{ "items": [ ... ], "cursor": null, "has_more": false }


What parameters can I use in the GET journal entries endpoint?

The query parameters currently available are:

  • start_date: required, filters entries from this date

  • end_date: required, filters entries up to this date

  • cursor: optional, enables pagination

  • limite: optional, sets the maximum number of entries to return per page. Default is 25, maximum is 100

  • account (integer): optional, filters entries by chart-of-accounts account number

☝🏼 The date format must be YYYY-MM-DD.

You can find full details in our API reference documentation.


Can I list a project's time entries, including timesheets and allocations?

Note that to use the date parameters on this endpoint, you must use the following structure:

  • startDate: filters records from this date onward (ISO 8601, YYYY-MM-DD)

  • endDate: filters records up to and including this date (ISO 8601, YYYY-MM-DD)


How can I interpret the API's error responses?

The most common error codes are:

400: Bad Request · Invalid parameters or malformed request body

401: Unauthorized · Missing or invalid API key

403: Forbidden · Valid API key but insufficient permissions

404: Not Found · The requested resource does not exist

422: Unprocessable Entity · Valid JSON but semantic validation failed

429: Too Many Requests · Rate limit exceeded. Wait and retry.

500: Internal Server Error · Something went wrong on our end

☝🏼 The API allows 100 requests per minute per API key. When you exceed this limit, you'll receive a 429 response. Wait for the rate limit window to reset before retrying.

Did this answer your question?