Developers
Frihet exposes a full REST API, a webhook system, and an MCP server so you can integrate your ERP with any tool. Automate workflows, sync data with your existing systems, or build custom integrations. See all Frihet features and available integrations.
Core resources
REST API
RESTful API with API key authentication. Access invoices, expenses, clients, products, quotes, and vendors programmatically.
- Full CRUD endpoints for 8 core resources: invoices, expenses, clients, vendors, products, quotes, deposits, and webhooks
- CRM subcollections: contacts, activities, and notes per client
- 4 intelligence endpoints:
/summary,/context,/monthly,/quarterly - Special actions: download PDF/XML, send by email, mark as paid, credit notes, late fees, expense invoicing, deposits
- Batch creation: up to 50 records per request
- Filtering by status, date range, full-text search, and pagination (offset + cursor)
- 100 requests/minute limit per key
- Standardized JSON responses with strict validation (Zod)
Webhooks
Receive real-time notifications when events occur in your Frihet account. 15 event types with HMAC-SHA256 signatures to verify the authenticity of every payload.
- 15 event types (invoices, payments, quotes, expenses, clients, products)
- Cryptographic HMAC-SHA256 signature on every delivery
- Automatic retries with exponential backoff (3 attempts)
- Circuit breaker: 3 consecutive failures automatically pause the webhook
- Delivery logs accessible from the dashboard
MCP Server
Official MCP server published on npm as @frihet/mcp-server (v1.17.0), registered as io.frihet/erp in the MCP Registry. 157 tools to connect your AI assistant (Claude, Cursor, Windsurf) directly to your ERP.
- 157 tools, 11 resources, 10 prompts (invoices, expenses, clients, CRM, products, quotes, vendors, intelligence, webhooks, e-invoicing, Stay, POS, banking, fiscal, time, recurring, HR, payroll, onboarding, permissions, period close, audit GL, gestoría)
- Local transport (stdio) and remote (mcp.frihet.io)
- Structured logging, per-tool metrics, automatic rate-limit retry
- Authentication via API key or OAuth flow
- Open source (MIT) on GitHub
Claude Code Skill
Official skill that adds business intelligence on top of the MCP server. Conversational commands, Spanish tax context, workflow recipes, and formatted financial reports.
- Commands:
/frihet invoice,/frihet expense,/frihet report,/frihet clients - Quarterly VAT summary to prepare Modelo 303
- Monthly close, overdue follow-up, quote-to-invoice conversion
- Install:
npx skills add Frihet-io/frihet-mcp
Integrations
Each integration has its own page in the Integrations section of these docs. You can extend them with the REST API and webhooks. For automations, see Zapier, n8n and Make.
Security
Security is a priority throughout Frihet's integration layer.
- AES-256-GCM encryption for sensitive stored data (integration tokens, webhook secrets)
- HMAC-SHA256 on every webhook delivery to verify payload authenticity
- SHA-256 hashing of API keys on the server — the plaintext key is shown only once at creation
- API key format validation before processing (
fri_prefix, 40–60 character length, restricted charset) - Rate limiting of 100 requests per minute per API key, backed by persistent storage
- Strict data validation with Zod — unknown fields are rejected
- URL validation on webhooks: only HTTPS endpoints are allowed (except localhost in development)
- Private IP blocking to prevent SSRF attacks on webhook URLs
- Document ID validation to prevent path traversal and injection
- Configurable key expiration — create keys with an expiry date
- Security headers on all responses:
X-Content-Type-Options,X-Frame-Options,X-XSS-Protection
SDKs and CLI
Official SDKs to integrate Frihet into your stack:
| Package | Install | Description |
|---|---|---|
@frihet/sdk | npm i @frihet/sdk | TypeScript SDK — frihet.invoices.create(), full types, auto-retry |
frihet | npm i -g frihet | CLI — frihet invoices list --status overdue |
import Frihet from '@frihet/sdk';
const frihet = new Frihet({ apiKey: 'fri_...' });
const invoice = await frihet.invoices.create({
clientName: 'Acme Corp',
items: [{ description: 'Consulting', quantity: 10, unitPrice: 150 }],
});
Repository: github.com/Frihet-io/frihet-sdk
Limits and quotas
| Resource | Limit |
|---|---|
| API requests | 100/minute per key |
| Request body size | 1 MB maximum |
| Maximum offset | 10,000 |
| Webhook payload size | 100 KB maximum |
| Webhooks per account | 20 maximum |
| Webhook retries | 3 attempts per delivery |
| Results per page | 100 maximum (50 default) |
| Active API keys per user | 5 maximum (via OAuth) |
Getting started
Follow this read-only walkthrough (GET /v1/clients?limit=5) to verify your connection and API key in under two minutes without modifying any data in your account.
1. Prerequisites and environment variable
- In Frihet ERP, go to Integrations → API Keys and click Create key (see API Keys for permission and expiration details).
- Copy the generated key (
fri_..., shown only once at creation) and store it in an environment variable in your terminal so you never expose it in code or screenshots:
export FRIHET_API_KEY="fri_your_key_here"
2. First read request: verify connection and HTTP status
Send a read-only GET request to https://api.frihet.io/v1/clients?limit=5 with -i so you can inspect the HTTP status code and X-RateLimit-* headers without truncating the JSON body:
curl -i -s "https://api.frihet.io/v1/clients?limit=5" \
-H "X-API-Key: $FRIHET_API_KEY"
The JSON blocks below are synthetic examples validated against the OpenAPI schema (/openapi.json) to help you interpret your terminal output; they are not live executions from this page.
3. Expected result: account with data vs empty account
200 OKresponse with registered clients: confirms your API key is valid and returns the paginated collection (data,total,limit,offset):
{
"data": [
{
"id": "cli_01J8X9M2K4",
"name": "Estudio Norte S.L.",
"email": "facturacion@example.com",
"taxId": "B12345674",
"createdAt": "2026-10-15T09:30:00.000Z",
"updatedAt": "2026-10-15T09:30:00.000Z"
}
],
"total": 1,
"limit": 5,
"offset": 0
}
200 OKresponse on a new account or an account with no clients ("data": []): if you have not created any clients yet, you will receive"data": []and"total": 0with HTTP status200. This also confirms that your connection and API key are working properly:
{
"data": [],
"total": 0,
"limit": 5,
"offset": 0
}
4. Error diagnosis and recovery (401, 403, 429)
401 Unauthorized(missingX-API-Keyheader, empty$FRIHET_API_KEYvariable, invalidfri_prefix, or expired/revoked key):
{
"error": "Invalid or expired API key",
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Recovery: check in your terminal that the variable is set (test -n "$FRIHET_API_KEY" && echo "OK") or generate a new key under Integrations → API Keys (API Keys).
403 Forbidden(the API key or active plan does not have permission for the requested resource):
{
"error": "Insufficient permissions",
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Recovery: verify the permissions attached to your key and your account plan in API Keys.
429 Too Many Requests(exceeded the 100 requests per minute limit for the key):
{
"error": "Rate limit exceeded",
"message": "Maximum 100 requests per minute",
"retryAfter": 60,
"meta": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Recovery: wait the number of seconds indicated in retryAfter or the Retry-After header (or until the X-RateLimit-Reset timestamp) before retrying.
5. Next action
- Explore creation endpoints, filters, and cursor pagination in the REST API reference or the interactive OpenAPI explorer (
/api-reference). - If you prefer using an AI agent (Claude Code, Cursor, Windsurf, ChatGPT, or Hermes) instead of manual HTTP calls, follow Connect your agent or the MCP Server reference.
- Set up real-time event notifications in Webhooks or check Quick troubleshooting and support.