Factuarea API

FAQ

Quick answers to the questions that come up most when integrating the Factuarea public API — keys, test mode, money, dates, idempotency and rate limits.

Short answers to the questions that come up most when building against the Factuarea public API. Each one links to the guide that covers it in full.

Access & keys

How do I get access to the API?

The API is in private beta: write to info@factuarea.com from the email associated with your company, including your legal name, tax ID, use case and estimated invoice volume. We respond within ≤ 5 business days. See Request beta access.

Is this key live or test?

Read the prefix: fact_live_ operates on your real company (production), fact_test_ on an isolated sandbox. The prefix is the single source of truth — no request parameter changes the environment. See Test mode & sandbox.

I lost my API key secret. Can I recover it?

No. The backend stores only a bcrypt hash of the secret, which is shown only once at creation. Rotate the key from the dashboard to issue a new secret and redeploy it. See Authentication › Rotation.

How do I rotate a key with zero downtime?

Rotate from the dashboard: the old and new secrets both stay valid for a grace period, so you can roll out the new one without dropped requests. Revoke a key only when you suspect a leak — that invalidates it instantly (401 api_key_revoked). See Authentication › Rotation and revocation.

Test mode

Is test data isolated from production?

Yes — structurally, not by a filter. A fact_test_ key operates on a dedicated sandbox company, so resources created in test are never visible to a fact_live_ key (and vice versa), and test fiscal numbering never touches your production series. See Test mode › Data isolation.

Why aren't my webhooks firing in test mode?

In test, external effects are switched off: VeriFactu → AEAT, FACe, emails and webhook delivery are all neutralized. Events are still recorded with livemode: false and are queryable via GET /v1/events, but they are not delivered to your endpoints. Use POST /v1/webhook_endpoints/{id}/ping to exercise your receiver. See Test mode › What is switched off.

Documents

What's the difference between delete, annul and void an invoice?

DELETE /v1/invoices/{id} only works on drafts. Once an invoice is issued it cannot be deleted: use POST /v1/invoices/{id}/annul (records a documented reason, and creates the AEAT anulación record when VeriFactu is enabled) or POST /v1/invoices/{id}/void (irreversible, records a void_reason, rejected if the invoice has already been corrected). See Migrate from Holded › Intentional differences.

Money & dates

How are monetary amounts represented?

In euros, with two decimal places, Stripe-style — the canonical form is a decimal string like "1234.56". Parse money as a fixed decimal, never a binary float, and let the API compute totals from raw line inputs. See Amounts & dates › Money.

What format do dates use?

Calendar dates such as issued_on and due_on use YYYY-MM-DD (for example 2026-05-15). Timestamps such as created and expires_at are ISO 8601 in UTC with a Z suffix — e.g. 2026-05-15T10:23:18Z. See Amounts & dates.

What timezone do quotas use?

The monthly rate-limit quota resets on day 1 at 00:00 Europe/Madrid, while timestamps are returned in UTC. See Amounts & dates › Timezone for quotas and Rate limits.

Idempotency & retries

What happens if I replay an Idempotency-Key?

Within the 24h TTL, the API returns the cached response (status, headers and body) without re-running the handler, adding the Idempotent-Replayed: true header. A cached 4xx is replayed too. Reusing the key with a different body responds 409 idempotency_key_reused. See Idempotency.

Does an idempotent replay count against my rate limit?

No. A key replayed within its TTL doesn't count against your quota. Different keys with the same payload each count, one by one. See Idempotency › What idempotency is NOT.

What's the maximum Idempotency-Key length?

Between 1 and 64 characters. Any opaque unique value works (UUID v7 recommended, but UUID v4, ULID or nanoid are fine). See Idempotency › Key format.

Rate limits & errors

How do I know my remaining quota?

Every response (including 429) carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 adds Retry-After with the seconds to wait. Limits depend on your key's tier. See Rate limits.

How should I retry a failed request?

4xx (except 429) → don't retry, fix the request. 429 → honor Retry-After. 5xx → exponential back-off with jitter, up to 5 attempts. See Errors › Retry strategy.

Where do I report a problem with a specific request?

Grab the request_id from the error envelope (also in the X-Request-Id header) and send it to support — it lets us correlate logs, metrics and traces. See Support.

On this page