Additional tax IDs
Buy more tax IDs for your account: plan, charge, trial, cap and the preview before you commit.
Your account is opened with one tax ID, its titular company. Every other tax ID the account operates is an additional tax ID, whether you register it, reactivate it or receive it by a tax ID transfer. Additional tax IDs are billed as a monthly add-on, so adding one can charge your account on the spot. This guide covers what you pay, which plans allow them, the cap, the trial rule, the preview and the four codes that reject an addition.
The writes and the preview live on the account axis: {account} is the account.id you
read from GET /v1/me, and {company}
is a company's id, an opaque UUID v7, not its tax_id. The billing read at the
end lives on the company axis.
What counts as an additional tax ID
- The first tax ID never counts. The titular company is the one the account was opened with and the one that contracts the plan. The first tax ID that enters an account with no active tax ID is not an additional tax ID.
- Only
activetax IDs count. The billed quantity is the number of active tax IDs minus the titular company. A tax ID that isinactiveorarchived, and the sandbox company of a tax ID, do not count. - The way in does not matter. A tax ID you register through the API or from the app, one you reactivate and one you receive by transfer cost the same once they are active.
The quantity follows your portfolio on its own, and an hourly reconciliation keeps it aligned with the number of active additional tax IDs. The reconciliation corrects the quantity without charging or crediting anything.
Price and plans
An additional tax ID costs 15.00 EUR per month before VAT. It is always billed
monthly, even when the account's plan is annual, and it lives in its own subscription
of the account (additional-nifs), separate from the one that pays the plan.
The API does not hold the amount: it is the price of the add-on. To know what your
account pays, read unit_amount in gestoria_seats or ask the
preview instead of hard-coding 15.00.
Only some plans allow additional tax IDs:
| Plan | Additional tax IDs |
|---|---|
emprendedor | Not allowed: 403 additional_nif_not_in_plan. |
empresario | Allowed, billed monthly. |
integral | Allowed, billed monthly. |
enterprise | Allowed. If the account is billed by contract, with no paid subscription, nothing is charged. |
The plan of an additional tax ID does not follow the plan of the account. On a Profesional (empresario) or Avanzado (integral) account, every additional tax ID has the Profesional plan (empresario); only the titular tax ID has the plan of the account.
The account also needs a current plan. With none (cancelled or expired) the answer
is 402 additional_nif_plan_required. A trial counts as a current plan, see
the trial rule. The plan is checked inside each operation and not through the
scopes: the companies:* scopes do not depend on the plan.
The cap
Your contract can set a maximum number of active additional tax IDs for the
account. It is kept on the account as max_additional_nifs. By default it is empty,
which means no cap, and only we set it, by contract. The API does not return it.
When adding one more tax ID, or several at once, would leave the account above the cap,
the answer is 422 business_rule_violation with subcode additional_nif_limit_reached,
before anything is charged or changed. A batch is rejected as a whole: it never lets
some of its tax IDs through and stops others.
{
"error": {
"type": "invalid_request_error",
"code": "business_rule_violation",
"subcode": "additional_nif_limit_reached",
"message": "Has alcanzado el máximo de NIF adicionales de tu contrato (5).",
"doc_url": "https://docs.factuarea.com/guides/errors#business_rule_violation",
"request_id": "req_c15e7a1c0d9b3f46a28c060000"
}
}The four writes
Four operations can add an active additional tax ID. They go through the same gate, with the same codes and in the same order.
| Write | Endpoint | Scope |
|---|---|---|
| Register a new tax ID | POST /v1/accounts/{account}/companies | companies:write |
| Reactivate one tax ID | POST /v1/accounts/{account}/companies/{company}/activate | companies:write |
| Reactivate several at once | POST /v1/accounts/{account}/companies/activate | companies:write |
| Accept a tax ID transfer | POST /v1/accounts/{account}/nif-transfers/accept | nif_transfers:write |
What the four share:
Idempotency-Keyis required. A request without it is rejected with422 idempotency_key_requiredbefore any business logic runs.- Who can ask. The credential must reach the titular company of the account, which is
the company that pays. To register or reactivate, the person who issued the key must also
be an
owneroradminof the account with theuser_managementsection available; to accept a transfer, they need an administrative role in at least one tax ID of the receiving account. Otherwise the answer is403 forbidden_action, before anything is charged or changed. - A read-only credential. If the credential only has
viewaccess to the tax ID, reactivating or accepting a transfer returns403 company_read_only. - The batch is all or nothing.
company_idstakes between 1 and 1000 ids. Every tax ID is validated before any charge: it must belong to the account and beinactive(422 business_rule_violationotherwise), and one that is not of the account returns404for the whole batch. The combined additional tax IDs are charged in a single invoice.
curl -X POST https://api.factuarea.com/v1/accounts/$ACCOUNT_ID/companies \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"name": "Talleres García SL",
"tax_id": "B12345674"
}'The 201 is the new company, with status: "active". Its paid_until is the end of the
period it is paid for, or null when it was not charged (a trial, for example). A tax_id
already registered in your account returns 409 resource_already_exists; one that belongs to
another account returns 422 business_rule_violation and is moved with a
tax ID transfer instead.
The gate and its four codes
Before anything is created, reactivated, moved or charged, each write runs the additional tax ID gate. It checks in this order and stops at the first failure:
- Who pays. The account must pay for itself.
- The plan. The account needs a current plan that allows additional tax IDs.
- The cap. The account must stay within
max_additional_nifs. - The charge. In live mode with a paid subscription, the charge must go through.
Every rejection arrives before any charge and writes nothing: no tax ID is created, reactivated or moved, and nothing is charged. The four codes of the gate:
| Code | Status | What it means | What to do |
|---|---|---|---|
billing_managed_by_provider | 403 | Another account pays this account's billing, so it cannot add a tax ID on its own. | Ask the account that pays to add, reactivate or accept the tax ID. See accounts paid by their provider. |
additional_nif_plan_required | 402 | The account has no current plan, so there is no subscription to bill the additional tax ID to. | Subscribe to empresario, integral or enterprise, or resume the cancelled plan, and repeat the same call. |
additional_nif_not_in_plan | 403 | The plan is current but does not allow additional tax IDs (emprendedor). | Move the account to empresario, integral or enterprise and repeat the same call. It is a plan limit, not a missing payment. |
additional_nif_charge_failed | 402 | The immediate charge was declined: the card was refused, it needs authentication or the payment provider was unreachable. | Fix the payment method in the billing portal and repeat the same call. |
Other rejections you can meet on the same writes:
| Code | Status | What it means |
|---|---|---|
business_rule_violation with subcode additional_nif_limit_reached | 422 | The addition would leave the account above its cap. |
payment_method_required | 402 | Live mode, paid subscription and no payment method on file. error.details.payment_setup_url links to where to set one up. |
forbidden_action | 403 | The credential does not reach the titular company, or the person who issued the key does not have the role the write requires. |
company_read_only | 403 | The credential only has view access to the tax ID. |
idempotency_key_required | 422 | The request carries no Idempotency-Key. |
When you are charged
In live mode with a paid subscription the additional tax ID is charged at once on the
account's additional-nifs subscription: prorated for the rest of the current period or, when it
is the first one and the subscription is created, the full first month. With no payment method on
file the write is rejected with 402 payment_method_required:
{
"error": {
"type": "payment_required_error",
"code": "payment_method_required",
"message": "La cuenta no tiene un método de pago configurado para cobrar el NIF adicional: configúralo y vuelve a intentarlo.",
"details": {
"payment_setup_url": "https://billing.stripe.com/p/session/live_YWNjdF8xS2ZHM0RLb0h4RXBGV3lY"
},
"doc_url": "https://docs.factuarea.com/guides/errors#payment_method_required",
"request_id": "req_c15e7a1c0d9b3f46a28c010000"
}
}A declined charge is 402 additional_nif_charge_failed. If the operation itself fails after the
charge, the charge is compensated: you are never left paying for a tax ID that was not added.
Nothing is charged when the account is in its trial, when it is an enterprise account billed by contract with no paid subscription, when it is a test account (the gate makes no call to the payment provider, see test managed accounts) or when the tax ID is still covered.
Coverage. paid_until on the company is the end of the period the tax ID is paid for. Each
paid renewal extends it, for every active additional tax ID, to the end of the new period.
Deactivating a tax ID (POST /v1/accounts/{account}/companies/{company}/deactivate) releases it
without a credit but keeps its coverage, so reactivating it before paid_until is free. After
the coverage expires, paid_until is null and reactivating is charged again. Deactivating is
never billed and never returns 402, and the account must keep at least one active tax ID
(422 business_rule_violation with subcode account_must_keep_one_nif).
The trial rule
While the account is in its trial, additional tax IDs are free, however they are added.
That covers the trial window without a subscription and a plan subscription that is in its trial
period (a card on file, status trialing). The preview answers
included_in_trial: true with no charge.
When the account starts paying, because the trial ends and the first charge goes through or
because it subscribes straight to a paid plan, the additional tax IDs it held for free become
inactive, with no charge and no credit. We do it so that nothing is charged that you did not
choose. Two details:
- A tax ID whose
paid_untilis still in the future stays active, because it was already paid. - The rule only acts in live mode on an account that really charges: a test account keeps its tax IDs.
You then reactivate the ones you want to keep, one by one or in a batch, and each reactivation is charged like any other.
When your plan changes
The life of the plan carries the additional tax IDs along:
- A plan that does not allow them. Moving down to a plan without additional tax IDs, or a
plan that expires (an expired trial, a payment that could not be recovered, a deleted subscription), deactivates the
active additional tax IDs, never the titular company, and releases them without a credit. On
expiry the
additional-nifssubscription is also cancelled at once. Moving between plans that do allow them, such asenterprisetoempresario, changes nothing. - Cancelling the plan schedules the cancellation of the additional tax IDs subscription for the same date, at period end or at once, like the plan. Resuming the plan removes that scheduled cancellation as long as the account still has active additional tax IDs.
- They do not come back on their own. A tax ID deactivated this way is reactivated with a plan that allows it, and the reactivation is charged.
Preview the charge
GET /v1/accounts/{account}/companies/seat-charge-preview returns what the next addition would
cost, computed from the upcoming invoice of the titular company, without charging. It needs
companies:read.
| Parameter | Notes |
|---|---|
count | Preview a batch of N tax IDs, between 1 and 1000 (1 by default). |
company_ids[] | Coverage-aware preview by UUID v7: tax IDs still covered for the period cost 0 with already_covered: true. When you send it, it overrides count. |
curl -G https://api.factuarea.com/v1/accounts/$ACCOUNT_ID/companies/seat-charge-preview \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
--data-urlencode "count=3"{
"data": {
"object": "seat_charge_preview",
"amount": "7.50",
"tax_amount": "1.58",
"total": "9.08",
"tax_rate": 21,
"currency": "EUR",
"next_invoice_date": "2026-04-01T00:00:00Z",
"requires_payment_method": false,
"requires_active_plan": false,
"included_in_trial": false,
"already_covered": false,
"is_first_seat": false,
"recurring_quantity": 3,
"recurring_base_cents": 4500,
"recurring_total_cents": 5445
}
}| Field | Meaning |
|---|---|
amount, tax_amount, total | The proration charged now: taxable base, VAT and their sum, in euros as strings with two decimals. |
tax_rate, currency, next_invoice_date | The VAT rate in percent (null when it could not be resolved), EUR and the date of the next invoice of the add-on. |
already_covered, requires_active_plan, included_in_trial, requires_payment_method | Why the amount is 0, or what is missing. At most one is true. requires_active_plan covers both no current plan and a plan that does not allow additional tax IDs. |
is_first_seat | true when the operation creates the first additional tax ID subscription of the account: the charge is then the full month, and today becomes the monthly billing day. |
recurring_quantity, recurring_base_cents, recurring_total_cents | The monthly fee after the operation: how many additional tax IDs will be billed, their base and the same with VAT. The two _cents fields stay in cents, as their names say, and recurring_total_cents is null when VAT is unknown. |
The preview is a read: it never returns 402 and it does not evaluate the plan or the cap of the
writes. A tax ID that is not additional, a test account, an account with no current plan and one
whose plan does not allow additional tax IDs all preview 0. It returns 403 billing_managed_by_provider
when the provider pays the billing of the account, and 404 when a company_ids value is not a tax ID
of the account.
A preview that looks fine does not promise the write will go through: the cap is only checked when
you add the tax ID. If the payment provider cannot simulate the invoice, the preview falls back to
the price of the add-on before VAT, so tax_rate and recurring_total_cents can be null.
Receive a tax ID by transfer
Accepting a tax ID transfer with
POST /v1/accounts/{account}/nif-transfers/accept adds the incoming tax ID to the receiving
account as an additional tax ID. The gate of the receiving account runs before anything
moves. A rejection leaves the transfer valid and the tax ID in the issuing account, so you can fix
the cause, such as a plan or a payment method, and accept again with the same secret.
In live mode with a paid subscription the tax ID is charged on acceptance, and if the move fails
after the charge, the charge is compensated. The receiving side needs an administrative role in at
least one tax ID of its account, and a credential that reaches the titular company of the receiving
account with write access (403 forbidden_action, or 403 company_read_only when it is read-only).
There is one exception: an account registered without a tax ID receives the tax ID as its titular company, and pays nothing.
Accounts paid by their provider
A managed account whose management is in force and whose billing is
paid by its provider does not buy anything on its own. Its account holder receives
403 billing_managed_by_provider on the four writes and on the preview.
The provider adds the tax IDs instead. People of the provider account with operate access to the
managed account register and reactivate them through the same endpoints, using the managed account's
{account}, and the charge goes to the provider's managed-accounts subscription, prorated at once. The gate still judges the managed
account itself: its own plan (emprendedor gets 403 additional_nif_not_in_plan), its own cap and
the provider's payment method (402 payment_method_required when it has none, 402 additional_nif_charge_failed
when the charge is declined). Test accounts and enterprise managed accounts, billed by contract, are
not charged.
When the client takes over the payment, or the management ends after the claim, the account pays for itself again and everything above applies to its own account holder. What the provider pays is in managed account pricing and payer change.
Read what you pay
GET /v1/companies/{company}/billing (scope account:read) returns the subscription snapshot of the
account. Its gestoria_seats block describes the additional tax ID subscription. The field keeps its
original public name so that existing integrations do not break, and there is no alias: despite the
name, it counts additional tax IDs and nothing else.
{
"gestoria_seats": {
"status": "active",
"quantity": 4,
"active_companies": 4,
"unit_amount": "15.00",
"tax_rate": 21,
"tax_amount": "3.15",
"total_per_seat": "18.15",
"recurring_total": "72.60",
"currency": "EUR",
"billing_interval": "month",
"next_invoice_at": "2026-07-15T10:00:00+00:00",
"ends_at": null
}
}| Field | Meaning |
|---|---|
status | Status of the additional tax ID subscription (active, past_due…), or none when there is no subscription yet, as in a trial. |
quantity, active_companies | Billed units, one per active additional tax ID, and the number of active additional tax IDs. |
unit_amount, tax_amount, total_per_seat, recurring_total | The taxable base of one unit, its VAT, the unit with VAT and the projected monthly total (total_per_seat × quantity). |
billing_interval | Always month, whatever the plan interval. |
Amounts are euros as strings with two decimals, not integer cents. They are null when the cost cannot be
resolved (an enterprise account outside the payment provider, a sandbox, no current plan): never a
misleading 0. The whole block is null when the account has no additional tax ID subscription and no
active additional tax IDs, and in a trial with active additional tax IDs it shows status: "none" and
quantity: 0. A company whose billing is paid by another company answers managed: true with
gestoria_seats: null, so the billing of whoever pays is never leaked.
Next steps
the account, its team, grants per tax ID and tax ID transfers.
register, list, deactivate and archive the tax IDs of your account.
what a provider pays for each managed account.
every code of the gate, with its cause and what to do.