---
title: "Register a tax ID in the account"
method: POST
path: "/accounts/{account}/companies"
tags: ["Companies"]
---

# Register a tax ID in the account

`POST /accounts/{account}/companies`

## Request

- Base URL: `https://api.factuarea.com/v1`
- URL: `https://api.factuarea.com/v1/accounts/{account}/companies`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Register a new tax ID in the account; `name` and `tax_id` are required.
- Duplicate `tax_id` returns 409; one owned by another account returns 422 `business_rule_violation`.
- Beyond the first active one it is ADDITIONAL: plan, cap and 402 `payment_method_required` apply.
- Preview the cost with `GET /v1/accounts/{account}/companies/seat-charge-preview`.

## Path parameters

- `account` string, uuid, required

## Headers

- `Idempotency-Key` string, required
- `Factuarea-Version` string, date

## Request body

- CreateCompanyV1Request: Register a tax ID (NIF) in your account. `name` and `tax_id` are required; the rest of the profile (business name, fiscal address, contact details) is optional. `tax_id` is validated as a Spanish tax ID (NIF/CIF/NIE) and must be unique within your account; `country_aeat_zone` is derived from the postal code. The new company joins your account and is adopted into the scope of the calling key, so you can operate on it right away. A tax ID already registered in another account is rejected: the account that holds it has to hand it over to yours with a tax ID transfer instead.
  - `name` string, required: Trade name of the company registered under this tax ID (1-255 characters).
  - `tax_id` string, required: Spanish tax identifier (NIF, CIF or NIE). Immutable after creation and unique within your account.
  - `business_name` string, nullable: Legal/registered business name.
  - `address` string, nullable: Fiscal address.
  - `city` string, nullable: City of the fiscal address.
  - `postal_code` string, nullable: Postal code (derives the AEAT zone).
  - `province` string, nullable: Province.
  - `country` string, nullable: Country.
  - `email` string, email, nullable: Contact email.
  - `phone` string, nullable: Contact phone number.

## Response `201`

Tax ID registered in the account. The `Location` header contains the canonical URL of the new company.

- object
  - `data` Company, required: A company (tax ID) of your account, registered and operated through the `/v1/accounts/{account}/companies` endpoints. `readiness` (whether it can issue right now, with the same contract as `GET /v1/accounts/{account}/companies/{company}/issuing-readiness`) is present only when the list is requested with `include=readiness`; otherwise the key is absent.
    - `id` string, uuid, required: Opaque identifier (UUID v7) of the tax ID.
    - `object` 'company', required: Always `company`.
    - `name` string, required: Commercial name of the tax ID.
    - `business_name` string, nullable, required: Legal/registered business name (razón social), or `null` if not set.
    - `tax_id` string, required: Spanish fiscal identifier (NIF/CIF/NIE). Unique within your account.
    - `status` 'active' | 'inactive' | 'archived', required: Status of the tax ID in the account: `active` (operational), `inactive` (deactivated, data preserved, can be reactivated) or `archived` (no longer accepts operations).
    - `status_since` string, date-time, nullable, required: When the tax ID entered its current `inactive` or `archived` status (ISO 8601). `null` for an `active` tax ID and for one whose change predates the lifecycle events: the date is never invented.
    - `address` string, nullable, required: Street address of the fiscal domicile, or `null`.
    - `city` string, nullable, required: City of the fiscal domicile, or `null`.
    - `postal_code` string, nullable, required: Postal code of the fiscal domicile, or `null`.
    - `province` string, nullable, required: Province of the fiscal domicile, or `null`.
    - `country_aeat_zone` 'peninsula' | 'canarias' | 'ceuta' | 'melilla' | 'null', nullable, required: AEAT territorial zone of the company (`peninsula`, `canarias`, `ceuta`, `melilla`), or `null`.
    - `country` string, nullable, required: Country of the fiscal domicile as recorded in the company profile (free text, up to 100 characters), or `null` when it was not set.
    - `email` string, email, nullable, required: Contact email, or `null`.
    - `phone` string, nullable, required: Contact phone, or `null`.
    - `logo_url` string, uri, nullable, required: Absolute URL of the company logo, or `null` if not set.
    - `paid_until` string, date-time, nullable, required: Paid coverage of this company as an additional tax ID of the account (ISO 8601): reactivating it before this date is free. `null` when it was never charged or the coverage expired.
    - `suspension_reason` 'payer_blocked' | 'management_ended' | 'null', nullable, required: Why the system suspended this `inactive` tax ID, or `null` when it is not suspended by the system (active, archived, or deactivated by the account itself). `payer_blocked`: the account paying for this managed account has its billing blocked; it resumes when the payer settles. `management_ended`: the management of this managed account ended before anyone took over the payment; it resumes when the holder of the account takes over the payment.
    - `created_at` string, date-time, required: When the tax ID was registered in the account (ISO 8601).
    - `updated_at` string, date-time, nullable, required: When the tax ID was last updated (ISO 8601), or `null`.
    - `readiness` IssuingReadiness: Whether a NIF can issue documents right now, and what stands in the way when it cannot. `can_issue` is the verdict and `blockers` the reasons: an empty `blockers` with `can_issue` false would be a bug, because a refusal that cannot be named cannot be fixed.
      - `can_issue` boolean, required: The verdict. `true` only when every condition below is met.
      - `blockers` string[], required: Machine-readable reasons the NIF cannot issue, in no particular order. Empty when `can_issue` is `true`. `verifactu_certificate_missing` means VeriFactu is enabled for the NIF but it has no valid certificate (none, revoked or expired). New reasons may be added over time: treat an unknown one as a blocker you cannot fix through the API.
      - `census_status` string, required: State of the AEAT census check for this NIF.
      - `has_default_series` boolean, required: Whether the NIF has a default document series to number with.
      - `fiscal_profile_complete` boolean, required: Whether the fiscal profile (tax id, address, territorial regime) is complete.
      - `operable` boolean, required: Whether the NIF is active and operable, as opposed to deactivated.
      - `missing_modules` string[], required: Modules the plan does not grant that issuing would need. Empty when nothing is missing.
      - `checked_at` string, date-time, required: Instant the verdict was computed (ISO 8601). It is a reading of a moment, not a stored flag.

## Other responses

- `400`: `parameter_unknown` with `subcode` `retired_active_profile_header`: the retired `X-Active-Profile` header was sent; the company goes in the path. `parameter_invalid_format` on `Factuarea-Version`: the header is not a `YYYY-MM-DD` date. `unsupported_api_version`: the `Factuarea-Version` date is not a supported version.
- `401`: Missing or invalid API key.
- `402`: The operation requires a payment that could not be completed: either no payment method is on file (`error.details.payment_setup_url` links to the Billing Portal where it can be set up), the immediate charge was declined by the payment provider, the account lacks the plan or add-on this operation bills against, the annual document limit is reached (`plan_limit_exceeded`, with `error.details.period_end` indicating the end of the period — wait until it has ended or upgrade the plan to continue now), or the account has reached its maximum usage (`storage_quota_exceeded`, raised by upload operations such as signing a delivery note or attaching a file to an expense — contact support before retrying). Nothing was created or modified — resolve the cause and retry the same request. Version note: `error.type` is `payment_required_error` from `Factuarea-Version: 2026-09-01` onwards; earlier versions receive `invalid_request_error` for the three codes that predate that cut (`payment_method_required`, `employee_seat_payment_method_required` and `employee_seat_charge_failed`; every other 402 code, such as `addon_required`, `plan_limit_exceeded` or the additional tax ID codes, is newer and always carries `payment_required_error`). `error.code` is stable across every version.
- `403`: The request is authenticated but not allowed: the API key lacks the required scope (`insufficient_scope`), the plan does not include the public API or this feature (`addon_not_active`, `feature_not_available_in_plan`), or the module is not available with a test key (`module_not_available_in_sandbox`).
- `404`: The requested resource does not exist or belongs to another company. `account_not_found`: the account in the path does not exist or is not the account of the API key.
- `409`: The request conflicts with data that already exists or with a request running at the same time. `resource_already_exists` with `subcode` `managed_company_tax_id_already_exists`: that NIF is already registered; `details.existing_resource_id` is the company that holds it. `customer_offer_phase_incompatible` with `param` `quantity`: the conditions already acquired for the additional tax ID seat cannot be preserved by this purchase. `details.reason` is `phase_incompatible`. No company is created or activated and no charge is attempted. `customer_offer_operation_in_progress`: an operation for the same concept is still pending. Continue that operation instead of starting another. `customer_offer_legacy_outcome_unknown`: a previous billing operation of the account is still being verified. `details.operation_id` is that operation; read its state before repeating the request.
- `422`: Validation failed. The `error.param` field identifies which input is invalid.
- `429`: Rate limit exceeded. Retry after the duration in `Retry-After`.
- `500`: Unexpected server error.
- `503`: The managed-company seat charge could not be verified. No company is created or activated and no charge is attempted; do not treat an unavailable amount as zero.

---

[API](https://skmtc.dev/factuarea/apis/factuarea-public-api.md) · [All operations](https://skmtc.dev/factuarea/apis/factuarea-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/factuarea/apis/factuarea-public-api/revisions/718e77934422?raw)
