Factuarea APIDevelopers

Factuarea API

The Factuarea REST API to automate your multi-tenant invoicing SaaS for Spanish businesses.

The Factuarea REST API exposes invoicing resources (contacts, products, invoices, quotes, pro-forma invoices, delivery notes, recurring invoices, expenses) over HTTPS with API key authentication. The entire public surface lives at https://api.factuarea.com/v1 and primarily returns JSON. Downloads use the XML, CSV or binary format declared by each endpoint; 204 and 304 responses have no body. Resources expose an opaque id, generally a UUID v7; provider identifiers are documented separately.

Quick start

The API comes with your plan

The public API is included in every Factuarea plan — no beta program, no separate add-on. During the 10-day trial you already get API access on the free tier; paid plans raise the rate-limit tier. See Rate limits.

Create your first API key

Open Dashboard → Developers → API Keys and create a key with the scopes you need (for example invoices:read,contacts:read to start). Copy the secret only once — you won't be able to see it again.

Pick the Test environment to get a fact_test_ key that operates on an isolated sandbox with no real-world effects. Build against it first, then create a fact_live_ key to go to production. See Test mode & sandbox.

Verify your key

Before anything else, confirm the key works. GET /v1/me introspects the credential and needs no scope: any valid key can read itself. It returns the account the key belongs to (its environment, whether it is an account provider and the privileged scopes Factuarea granted it), the scopes and rate-limit tier of the key itself, the tax IDs it reaches and, for a provider key, the accounts of your clients your account reaches. The id of each tax ID is the {company} segment of every company-scoped route:

curl https://api.factuarea.com/v1/me \
  -H "Authorization: Bearer fact_test_xxxxxxxxxxxxxxxxxxxxxxxx"

You should see a 200 with a me snapshot. This one comes from a live key of an account provider, so every block is filled:

{
  "data": {
    "object": "me",
    "account": {
      "id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a00",
      "name": "Asesoría Martínez",
      "environment": "live",
      "is_provider": true,
      "privileged_scopes": [
        "accounts:read",
        "accounts:write"
      ]
    },
    "api_key": {
      "id": "019e81ef-e1d4-7208-a51d-94c2c2a54a84",
      "name": "Producción",
      "prefix": "fact_live_1OSf9KdP",
      "scopes": [
        "account:read",
        "series:read",
        "series:write"
      ],
      "tier": "scale",
      "environment": "live",
      "created_at": "2026-01-15T09:30:00Z",
      "last_used_at": "2026-05-25T18:00:00Z",
      "expires_at": null
    },
    "scope": [
      {
        "id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01",
        "tax_id": "B12345674",
        "name": "Acme Corporation"
      },
      {
        "id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a02",
        "tax_id": "B87654323",
        "name": "Acme Logística S.L."
      }
    ],
    "client_accounts": [
      {
        "id": "0199a1f0-1c22-7a10-b111-5a5b5c5d5e5f",
        "name": "Construcciones Ruiz",
        "origin": "granted",
        "access_level": "view",
        "status": "active",
        "paid_by_provider": false,
        "environment": "live"
      },
      {
        "id": "0199a1f0-1c22-7a10-b111-6a6b6c6d6e6f",
        "name": "Talleres García",
        "origin": "provisioned",
        "access_level": "operate",
        "status": "provisioned",
        "paid_by_provider": true,
        "environment": "live"
      }
    ],
    "client_accounts_visible": true,
    "client_accounts_has_more": false
  }
}
  • account is the account of the key. Its id is the {account} segment of the account routes, and is_provider says whether it provisions managed accounts for its clients.
  • scope lists the tax IDs the key reaches, each with its id, its tax_id and its name. It is always enumerated, also when there is exactly one.
  • client_accounts lists the accounts of your clients that your account reaches: granted when they gave you access, provisioned when you provisioned them and still manage them. It is filled only when the key carries the privileged accounts:read scope; otherwise it comes back empty and client_accounts_visible is false.

If you get 401 invalid_api_key, re-check the value. The scopes array tells you exactly what this key can do — a later call that fails with 403 insufficient_scope is missing one of them. Every field is described in Accounts and tax IDs.

Make your first data request

Now list a real resource. GET /v1/companies/{company}/contacts returns a standard envelope with data (results), has_more and next_cursor (cursor pagination). Swap {company} for the id of one of the tax IDs in scope — your own, one that another account granted you access to or one of a managed account, as Reach a tax ID explains — and filter by role. A single contact per tax ID carries the customer and supplier roles it needs:

curl "https://api.factuarea.com/v1/companies/{company}/contacts?roles[]=customer" \
  -H "Authorization: Bearer fact_test_xxxxxxxxxxxxxxxxxxxxxxxx"

Ready to issue your first invoice end-to-end? Follow the Quickstart. If you receive an error, look it up in Errors by the returned code.

Configure webhooks (optional)

If your integration needs to react to events (invoice paid, quote accepted, etc.), configure a webhook endpoint signed with HMAC SHA256. See Webhooks.

What the API covers

Contacts

One identity, cumulative customer/supplier/lead roles, profiles, imports and archive/restore.

Catalog

Products and services with decimal stock, UNECE units, presentations, variants, supplier offers and customer-specific price lists.

Sales documents

Invoices, quotes, pro-forma invoices, delivery notes, recurring invoices — with lines, retentions and equivalence surcharge.

Document actions

Send by email, mark as paid/accepted, generate PDF, void, create corrective invoice, convert between types.

Expenses

Expenses with PDF upload, mark_paid, mark_received.

Document series

Legal numbering series per document type, with fiscal safeguards when updating them through the API.

FACe invoicing (B2G)

FacturaE 3.2.2 XML download and FACe submissions — submit, track the processing status and request cancellations.

Time tracking (control horario)

Employees, work schedules, the time-clock ledger, monthly closes, absences, presence and public holidays — the RD-ley 8/2019 working-time register.

Automations

Event-driven rules — an event fires, a condition decides and an ordered list of actions runs, with sealed versions, a dry run and run history.

Tasks & projects

Projects with a board of columns, tasks linked to your invoices, quotes and contacts, logged time turned into draft invoices and a combined agenda — also as 22 project and 52 task MCP tools.

MCP server for AI agents

The whole API as 668 Model Context Protocol tools, with OAuth 2.1 and API-key auth — connect Claude and other agents in seconds.

Contract design

The API follows the patterns you would expect from a modern provider:

  • Opaque identifiers — resource IDs generally use UUID v7 strings. Signature-audit redaction retains a numeric audit ID, and external provider identifiers use their own formats. See Pagination for cursor semantics.
  • Normalized errors — every error returns an envelope with type, code, message, param, doc_url and request_id. See Errors.
  • Idempotency keys — supported on every POST to prevent duplicates on retries. See Idempotency.
  • Rate limits per tier — per-minute and monthly quotas, with X-RateLimit-* headers on every response. See Rate limits.
  • URL versioning — /v1/*. Breaking changes trigger /v2/* with a documented deprecation policy. See Versioning.
  • Webhooks with dual-secret rotation — HMAC SHA256, exponential retry with up to 8 attempts. See Webhooks.

SDKs

We ship official TypeScript and PHP SDKs (@factuarea/sdk and factuarea/factuarea-php) with retries, idempotency, cursor pagination, typed errors and webhook verification built in. If your language isn't covered, any standard HTTP client (curl, Postman, axios, requests, Guzzle) works — the API is plain REST over JSON.

The public REST API complements the Factuarea web client (app.factuarea.com) — it doesn't replace it. Operations not exposed by the API (plan management, branding, global company tax configuration) still live in the app.

Integrations and guided workflows

Connect ecommerce stores, configure WooCommerce or Shopify, and consume events with n8n. Start with the integration index. For email, read sending documents; for agents, read the MCP protocol and fiscal resources and prompts.

On this page

Need a hand?Contact support