Install
openclaw skills install holded-skillOperate Holded ERP through holdedcli to read and update data safely. Use when the user asks to read, search, create, update, or delete Holded entities (contacts, invoices, products, CRM, projects, team, accounting) or run Holded API endpoints from the terminal.
openclaw skills install holded-skillUse holdedcli to read and modify Holded data with a safe, repeatable workflow.
holded actions list.holded actions describe <action> --json.--json and summarize IDs, HTTP status, and applied changes.holded helpholded auth status or HOLDED_API_KEY--jsonPOST, PUT, PATCH, or DELETE action as write.GET action (or HEAD when present) as read.holded actions describe <action> --json (after holded actions list) to validate accepted parameters.docType=purchase and include "isReceipt": true in the JSON body. Since holdedcli validates against Holded's schema (which doesn't include isReceipt), you must use --skip-validation flag.ok, go ahead, continue) without clarification.Before any write action, show:
action_id or operation_id).--path, --query, and body parameters (--body or --body-file).Use this format:
This operation will modify data in Holded.
Action: <action_id> (<METHOD> <endpoint>)
Changes: <short summary>
Command: holded actions run ... --json
Do you confirm that I should run exactly this command? (reply with "yes" or "confirm")
Execute only after an explicit affirmative response.
holded actions list --json (use --filter).holded actions describe <action> --json.holded actions run <action> ... --json.holded actions describe <action> --json to verify required/optional parameters.docType=purchase and "isReceipt": true, and use --skip-validation flag.status_code, affected ID, API response).holded auth set --api-key "$HOLDED_API_KEY"
holded auth status
holded ping --json
holded actions list --json
holded actions list --filter contacts --json
holded actions describe invoice.get-contact --json
holded actions run invoice.get-contact --path contactId=<id> --json
For long payloads, prefer --body-file:
holded actions run invoice.update-contact \
--path contactId=<id> \
--body-file payload.json \
--json
Purchase receipt rule (mandatory for purchase tickets):
holded actions describe invoice.create-document --json
holded actions run invoice.create-document \
--path docType=purchase \
--body '{"isReceipt": true, "date": 1770764400, "contactId": "<contactId>", "items": [{"name": "Description", "units": 1, "subtotal": 29.4, "tax": 0}]}' \
--skip-validation \
--json
Important notes:
--skip-validation flag because holdedcli validates against Holded's schema which doesn't include isReceipt.subtotal in items (not price) - this is the field name Holded's API expects.Timestamp calculation (Python):
from datetime import datetime, timezone, timedelta
# For 11/02/2026 00:00 in Madrid:
dt = datetime(2026, 2, 11, 0, 0, 0, tzinfo=timezone(timedelta(hours=1)))
print(int(dt.timestamp())) # 1770764400
⚠️ ALWAYS check these rules BEFORE creating any expense document:
| Expense Type | IVA Deductible | Expense Deductible | Account |
|---|---|---|---|
| Restaurants/Meals | ❌ No | ✅ Yes (with justification) | 629 |
| Displacement | ❌ No | ✅ Yes | 629 |
| Fuel | ⚠️ Mixed | ✅ Yes | 625/622 |
| Office supplies | ✅ Yes | ✅ Yes | 600/602 |
| Insurance | ⚠️ Mixed | ✅ Yes | 625 |
Before creating any document, ALWAYS verify:
Common mistake to avoid: Never set tax: 10 or tax: 21 for restaurant expenses - IVA is NOT deductible for meals unless it's a business event with proper justification.
MISSING_API_KEY appears, configure API key through --api-key, HOLDED_API_KEY, or holded auth set.ACTION_NOT_FOUND appears, list the catalog and search with --filter.INVALID_BODY appears, validate JSON before execution.API_ERROR appears, report status_code and the API snippet.{baseDir}/references/holdedcli-reference.md for quick commands and criteria.holded actions list --jsonholded actions describe <action> --json