✓ Verified 🌐 Web Scrapers ✓ Enhanced Data

Holded Skill

Operate Holded ERP through holdedcli to read and update data safely.

Rating
4.2 (71 reviews)
Downloads
4,322 downloads
Version
1.0.0

Overview

Operate Holded ERP through holdedcli to read and update data safely.

Complete Documentation

View Source →

holded-skill

Use holdedcli to read and modify Holded data with a safe, repeatable workflow.

Operational Flow

  • Confirm technical prerequisites.
  • Discover available actions with holded actions list.
  • Inspect the selected action with holded actions describe --json.
  • Classify the action as read or write.
  • If it is a write operation, ask for explicit confirmation before execution.
  • Run with --json and summarize IDs, HTTP status, and applied changes.

Prerequisites

  • Verify that the binary exists: holded help
  • Verify credentials: holded auth status or HOLDED_API_KEY
  • Prefer structured output whenever possible: --json

Safety Rules

  • ALWAYS check deductibility rules BEFORE creating any document. See "Accounting Rules for Spain" section below.
  • Treat any POST, PUT, PATCH, or DELETE action as write.
  • Treat any GET action (or HEAD when present) as read.
  • Before any operation, always run holded actions describe --json (after holded actions list) to validate accepted parameters.
  • For purchase receipts, always enforce 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.
  • Ask for explicit user confirmation every time before any write action.
  • Do not execute writes on ambiguous replies (ok, go ahead, continue) without clarification.
  • Repeat the exact command before confirmation to avoid unintended changes.
  • If the user does not confirm, stop and offer payload adjustments.

Mandatory Confirmation Protocol

Before any write action, show:

  • Holded action (action_id or operation_id).
  • Method and endpoint.
  • --path, --query, and body parameters (--body or --body-file).
  • The exact command to run.
Use this format:

text
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.

Execution Pattern

Read Operations

  • Locate the action with holded actions list --json (use --filter).
  • Verify accepted path/query/body parameters with holded actions describe --json.
  • Run holded actions run ... --json.
  • Return a clear summary and relevant IDs for follow-up steps.

Write Operations

  • Locate and validate the action.
  • Run holded actions describe --json to verify required/optional parameters.
  • Prepare the final payload.
  • If creating a purchase receipt/ticket, verify docType=purchase and "isReceipt": true, and use --skip-validation flag.
  • Request mandatory confirmation.
  • Run the command after confirmation.
  • Report result (status_code, affected ID, API response).

Base Commands

bash
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:

bash
holded actions run invoice.update-contact \
  --path contactId=<id> \
  --body-file payload.json \
  --json

Purchase receipt rule (mandatory for purchase tickets):

bash
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:

  • Use --skip-validation flag because holdedcli validates against Holded's schema which doesn't include isReceipt.
  • Use subtotal in items (not price) - this is the field name Holded's API expects.
  • Timestamps must be in seconds (Unix epoch) and in Europe/Madrid timezone.
Timestamp calculation (Python):
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

Accounting Rules for Spain

⚠️ ALWAYS check these rules BEFORE creating any expense document:

Expense TypeIVA DeductibleExpense DeductibleAccount
Restaurants/Meals❌ No✅ Yes (with justification)629
Displacement❌ No✅ Yes629
Fuel⚠️ Mixed✅ Yes625/622
Office supplies✅ Yes✅ Yes600/602
Insurance⚠️ Mixed✅ Yes625
Before creating any document, ALWAYS verify:
  • Is the expense tax deductible?
  • Is the IVA deductible? (usually NO for restaurants, displacement)
  • If in doubt, ASK before creating the document.
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.

Error Handling

  • If MISSING_API_KEY appears, configure API key through --api-key, HOLDED_API_KEY, or holded auth set.
  • If ACTION_NOT_FOUND appears, list the catalog and search with --filter.
  • If INVALID_BODY appears, validate JSON before execution.
  • If API_ERROR appears, report status_code and the API snippet.

References

  • Read {baseDir}/references/holdedcli-reference.md for quick commands and criteria.
  • Use dynamic action discovery and parameter inspection via:
  • holded actions list --json
  • holded actions describe --json

Installation

Terminal bash

openclaw install holded-skill
    
Copied!

💻Code Examples

Do you confirm that I should run exactly this command? (reply with "yes" or "confirm")

do-you-confirm-that-i-should-run-exactly-this-command-reply-with-yes-or-confirm.txt
Execute only after an explicit affirmative response.

## Execution Pattern

### Read Operations

1. Locate the action with `holded actions list --json` (use `--filter`).
2. Verify accepted path/query/body parameters with `holded actions describe <action> --json`.
3. Run `holded actions run <action> ... --json`.
4. Return a clear summary and relevant IDs for follow-up steps.

### Write Operations

1. Locate and validate the action.
2. Run `holded actions describe <action> --json` to verify required/optional parameters.
3. Prepare the final payload.
4. If creating a purchase receipt/ticket, verify `docType=purchase` and `"isReceipt": true`, and use `--skip-validation` flag.
5. Request mandatory confirmation.
6. Run the command after confirmation.
7. Report result (`status_code`, affected ID, API response).

## Base Commands

--json

---json.txt
**Important notes:**
- Use `--skip-validation` flag because holdedcli validates against Holded's schema which doesn't include `isReceipt`.
- Use `subtotal` in items (not `price`) - this is the field name Holded's API expects.
- Timestamps must be in seconds (Unix epoch) and in **Europe/Madrid timezone**.

**Timestamp calculation (Python):**
example.txt
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")
example.sh
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
example.sh
holded actions run invoice.update-contact \
  --path contactId=<id> \
  --body-file payload.json \
  --json
example.sh
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
example.py
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

Tags

#search_and-research #cli #data

Quick Info

Category Web Scrapers
Model Claude 3.5
Complexity One-Click
Author jaumecornado
Last Updated 3/10/2026
🚀
Optimized for
Claude 3.5
🧠

Ready to Install?

Get started with this skill in seconds

openclaw install holded-skill