Factuarea API

Test mode & sandbox

Build your integration safely with fact_test_ keys — isolated sandbox data and AEAT, email and webhooks switched off.

Every Factuarea API key belongs to one of two environments, told apart by its prefix:

PrefixEnvironmentOperates onExternal effects
fact_live_live (production)Your real companyReal: legal fiscal numbering, VeriFactu → AEAT, FACe submissions, emails to clients, outbound webhooks
fact_test_test (sandbox)An isolated sandbox companySwitched off (see below)

The prefix is the source of truth for the environment: a fact_test_ key always operates in test mode and a fact_live_ key always in live. No request parameter changes the environment — it is determined entirely by the key you authenticate with.

Always build and test your integration with a fact_test_ key first. Once your flow works end-to-end, switch the prefix to fact_live_ to go to production. The API surface is identical in both environments.

Getting a test key

Test keys are created from the developer dashboard exactly like live keys, selecting the Test environment (app.factuarea.com/settings/developers/api-keys). The generated secret looks like:

fact_test_<24 alphanumeric characters>

Example:

fact_test_3pXnR2VbY7TcA9eFmN5z8KqW

Same format and entropy as a live key (24 base62 characters), same scopes, same rate-limit tier. The only difference is the prefix and what it points to. As with live keys, the secret is shown only once at creation — if you lose it you must rotate.

Using a test key

Send it on every request just like a live key, via Authorization: Bearer or X-API-Key:

curl https://api.factuarea.com/v1/clients \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"

The same endpoints and operations available in live are available in test — nothing is removed or stubbed.

Data isolation: the sandbox company

A fact_test_ key operates on a dedicated sandbox company — a technical "twin" of your real company, provisioned automatically the first time you use test mode, that inherits your real company's plan so feature-gating is faithful. Thanks to multi-tenant isolation by company:

  • Resources created with a fact_test_ key are not visible to a fact_live_ key, and vice versa.
  • Test fiscal numbering uses the sandbox's own series and never consumes or alters the correlative numbering of your production series.

This is structural isolation, not a filter: test and live data live in separate companies, so there is no way for them to mix.

What is switched off in test

When you operate with a fact_test_ key (sandbox environment), effects that reach the outside world are disabled so you can exercise your integration without real-world consequences:

EffectIn liveIn test
VeriFactuThe Alta record is created and transmitted to the AEAT.The Alta record is created locally, but never transmitted to the AEAT.
EmailDocument emails are delivered to real recipients.Document emails are not delivered to real recipients.
WebhooksSubscribed events are delivered to your external HTTP endpoints.Events are recorded with livemode: false (queryable via GET /v1/events) but not delivered to your endpoints.
FACe (FacturaE)Submissions are presented to the real FACe web service.The whole flow is simulated — no SOAP call leaves Factuarea and the registry number is synthetic (FACE-SANDBOX-*). See FACe invoicing.

Everything else behaves identically: validation, totals, document state machines, idempotency, pagination, rate limits and error envelopes are the same as in production.

Because webhooks are not delivered in test, you cannot exercise your webhook receiver against sandbox data. Test your endpoint's signature verification with the dedicated POST /v1/webhook_endpoints/{id}/ping (which is delivered) or against a live key on a controlled event.

With the official SDKs

The TypeScript and PHP SDKs follow the same rule: the key prefix selects the environment — there is no flag. Build against a fact_test_ key, then swap the env var to fact_live_ to go to production. No code changes.

import { Factuarea } from "@factuarea/sdk";

const sandbox = new Factuarea({ apiKey: "fact_test_…" });
sandbox.environment; // "test"

const prod = new Factuarea({ apiKey: "fact_live_…" });
prod.environment;    // "live"

The SDK exposes the resolved environment on .environment, derived from the prefix — handy for guards and logging.

use Factuarea\Sdk\Custom\FactuareaClient;

$sandbox = FactuareaClient::create('fact_test_…'); // sandbox
$prod    = FactuareaClient::create('fact_live_…'); // production

Webhooks are still not delivered in test even via the SDK. To exercise your receiver's SDK verifier in sandbox, use POST /v1/webhook_endpoints/{id}/ping, which is delivered.

Switching environment in the app

Beyond API keys, the Factuarea web app lets you toggle between live and test at any time from the top bar. Switching to test:

  • Re-issues your session without re-login, pointing it at the sandbox company (provisioning it if it doesn't exist yet). The previous token is invalidated.
  • Shows a persistent "MODO TEST" banner across the whole interface so the active context is always obvious.
  • Re-hydrates the client state so listings reflect sandbox data and never show cached production data.

Switching back to live re-issues the session against your real company. The sandbox is never shown as a real company in the company selector — it exists only to back the test environment.

From test to production

When your integration works against fact_test_:

  1. Create a fact_live_ key in the dashboard (same scopes you validated in test).
  2. Swap the key your client uses (environment variable / secret manager).
  3. No code changes are needed — the request shape is identical.

From that point, real effects (fiscal numbering, VeriFactu → AEAT, emails, webhooks) are active again.

On this page