---
title: "Provision a managed account"
method: POST
path: "/accounts"
tags: ["Account"]
---

# Provision a managed account

`POST /accounts`

## Request

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

Provision a SEPARATE account for one of your clients, with its tax ID, plan and your `access_level`; your account pays it.
- Returns 201 with the claim voucher shown EXACTLY ONCE, or emailed with `send_email: true`.
- Repeating an `external_ref` returns 200 with no new voucher; `Idempotency-Key` is required.
- Requires the privileged `accounts:write` scope.

## Headers

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

## Request body

- ProvisionManagedAccountV1Request: Provision a managed account for one of your clients. Required: `external_ref` (your own reference, unique per provider: repeating it returns the same account), `plan` (`emprendedor`, `empresario` or `integral`), `tax_id` (Spanish tax ID) and `legal_name`. `access_level` is the level your account keeps on it (`none` by default). `owner_email` is required with a live key and whenever `send_email` is `true`; `send_email` is `false` by default, so the claim voucher comes back ONCE in the response for you to deliver. The rest of the fiscal profile (`display_name`, address, `language`) is optional. The provider is always the account of the key and never comes from the body; the environment of the new account is the one of the key.
  - `external_ref` string, required: Your own reference for the account (up to 128 characters), unique per provider. Provisioning it again returns the same account (200) without a new voucher.
  - `plan` 'emprendedor' | 'empresario' | 'integral' | 'enterprise', required: Plan of the managed account: `emprendedor`, `empresario` or `integral`. `enterprise` returns 422 `managed_account_plan_not_self_serve`.
  - `access_level` 'none' | 'view' | 'operate': Access level your account keeps on the managed account: `none` (default, provisioning only), `view` (read-only) or `operate`.
  - `tax_id` string, required: Spanish tax identifier (NIF, CIF or NIE) of the managed account.
  - `legal_name` string, required: Legal name of the managed account.
  - `display_name` string, nullable: Visible name of the account and of its tax ID; without it, the legal 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.
  - `language` 'es' | 'en' | 'ca' | 'null', nullable: Language of the account and of its claim voucher: `es` (default), `en` or `ca`.
  - `owner_email` string, email, nullable: Email of the holder of the account. Required with a live key and whenever `send_email` is `true`.
  - `send_email` boolean: Email the claim link to `owner_email` (`true`) or return the voucher once in the response (`false`, default).

## Response `201`

Managed account provisioned. The `Location` header contains the canonical URL of the new managed account; the body carries its claim voucher once.

- object
  - `data` ManagedAccountWithClaim, required: The response of provisioning a managed account: the fields of `ManagedAccount` PLUS its claim voucher. `claim_token` and `claim_url` are returned ONCE, only for a new live account provisioned with `send_email: false`. They are `null` when the link was emailed to the holder (`send_email: true`), for a test account, when the `external_ref` was already provisioned (200) and in an idempotent replay: the voucher is never stored in the clear, not even in the idempotency cache. `claim_expires_at` is not a secret: it is returned also when the link was emailed and in an idempotent replay of that request. `reactivated` tells that the call reactivated a management that had ended before the holder claimed the account.
    - `id` string, uuid, required: Opaque identifier (UUID v7) of the managed account. It is the `{account}` of the managed account routes.
    - `object` 'managed_account', required: Always `managed_account`.
    - `external_ref` string, required: Your own reference for this account, unique per provider. Provisioning it again returns this same account.
    - `status` 'provisioned' | 'claimed' | 'active', required: Status of the ACCOUNT: `provisioned` (created by you, not claimed yet), `claimed` (its holder took it) or `active`. The end of the management is read in `management`, not here.
    - `environment` 'live' | 'test', required: Environment of the account: always the one of the key that provisioned it. A test account is never charged and cannot be claimed.
    - `plan` 'emprendedor' | 'empresario' | 'integral' | 'enterprise', required: Current plan of the managed account. `enterprise` is only assigned by Factuarea by contract.
    - `pending_plan` 'emprendedor' | 'empresario' | 'integral' | 'null', nullable, required: Plan requested by a downgrade that takes effect at the end of the current period, or `null`.
    - `billing_interval` string, required: Billing interval of the managed account (managed accounts are billed monthly).
    - `access_level` 'none' | 'view' | 'operate', required: Access level of your account on this account: `none` (provisioning only), `view` (read-only) or `operate`.
    - `display_name` string, required: Visible name of the account.
    - `language` 'es' | 'en' | 'ca' | 'null', nullable, required: Language of the account and of its claim voucher, or `null` when not recorded.
    - `companies` object[], required: Tax IDs of the managed account.
      - `id` string, uuid, required: Opaque identifier (UUID v7) of the tax ID, the `{company}` of the company axis.
      - `tax_id` string, required: Spanish fiscal identifier (NIF, CIF, NIE). Structural format: NIF `^\d{8}[A-Z]$`, NIE `^[XYZ]\d{7}[A-Z]$`, CIF `^[A-Z]\d{7}[A-Z0-9]$`. AEAT control-digit (checksum) validation is enforced when the request opts in via the `Factuarea-Version` header on or after the activation version; without that opt-in the legacy permissive behaviour is preserved.
      - `name` string, required: Name of the tax ID.
    - `claimed` boolean, required: Whether its holder already claimed the account.
    - `claimed_at` string, date-time, nullable, required: When its holder claimed the account (ISO 8601), or `null`.
    - `management` object, required: Management of the account by your account.
      - `status` 'active' | 'ended', required: `active` while your account manages it; `ended` once the management ended.
      - `ended_at` string, date-time, nullable, required: When the management ended (ISO 8601), or `null`.
    - `paid_by_provider` boolean, required: Whether your account pays this account. `false` once its holder took over the payment.
    - `created_at` string, date-time, required: When the account was provisioned (ISO 8601).
    - `claim` object, nullable, required: The PENDING claim voucher of the account, WITHOUT its secret or its link (those are returned once, by the provisioning and by the reissue). `null` when the account is already claimed, is a test account or has no pending voucher.
      - `status` 'valid' | 'expired', required: `valid` while the voucher has not expired; `expired` once `expires_at` passed (reissue it).
      - `issued_at` string, date-time, required: When the voucher was issued (ISO 8601).
      - `expires_at` string, date-time, required: When the voucher expires (ISO 8601).
      - `ttl_days` integer, required: Days of validity the voucher was issued with.
      - `sent_by_email` boolean, required: Whether the voucher left by email to the holder.
      - `masked_email` string, nullable, required: Email of the holder, masked, or `null` when the voucher was not sent by email.
    - `payment_assumed_at` string, date-time, nullable, required: When the holder took over the payment of the account (ISO 8601), or `null` while your account still pays it (`paid_by_provider`).
    - `plan_renews_at` string, date-time, nullable, required: End of the current billing period of the plan (ISO 8601): when a pending downgrade takes effect and the next periodic invoice is issued. `null` when the account is not charged to your account.
    - `claim_token` string, nullable, required: Plaintext claim voucher, returned ONCE. Treat it as a credential: whoever holds it can claim the account. `null` when there is no voucher to deliver (see the schema description).
    - `claim_url` string, uri, nullable, required: Claim link carrying the voucher, to deliver to the holder yourself, returned ONCE. `null` when there is no voucher to deliver.
    - `claim_expires_at` string, date-time, nullable, required: Expiry of the voucher (ISO 8601). It is returned also when the link was emailed to the holder (`send_email: true`): the expiry is not a secret. `null` only when no voucher was issued (test account, idempotent retry or reactivated management).
    - `reactivated` boolean, required: `true` only when provisioning REACTIVATED a management that had ended before the holder claimed the account (it carries no voucher, so `claim_expires_at` is `null`); `false` for a new account or one already in force.

## 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`).
- `409`: The request conflicts with data that already exists or with a request running at the same time. `provisioning_account_claimed`: the holder already claimed this managed account, so its voucher can no longer be reissued and its `external_ref` can no longer be provisioned again. The account belongs to its holder; read it with the retrieve operation while the management is in force. `managed_account_external_ref_in_other_environment`: a managed account of the other environment (live or test) already uses this `external_ref`. References are unique per provider across both environments: use another one. `resource_conflict`: another request was reserving identifiers for the same kind of record at that moment and this one could not complete its reservation. Nothing was written; send the request again after a few seconds.
- `422`: Validation failed, or a managed account rule rejected the operation: `managed_account_plan_not_self_serve` (`enterprise` is only assigned by Factuarea by contract), `managed_account_provider_in_trial` (a paid plan while your account is in trial), `managed_accounts_limit_reached` (the managed account limit of your account), `managed_account_not_claimable` (a test account has no claim voucher), `access_level_raise_forbidden` (once the holder claimed the account only the holder can raise your level), `enterprise_contract_transition_required` (moving to or from `enterprise` is a contract change) and `business_rule_violation` with subcode `nif_already_claimed_by_another_account` (provisioning a tax ID that already belongs to another account). The `error.param` field identifies which input is invalid, if any. `idempotency_key_reused`: the `Idempotency-Key` was already used with a different body; send a new key or the same body. `invalid_param_format` on `Idempotency-Key`: the key must be 1 to 255 printable ASCII characters. `idempotency_key_required`: this operation requires the `Idempotency-Key` header; the message names the rejected operation.
- `429`: Rate limit exceeded. Retry after the duration in `Retry-After`.
- `500`: Unexpected server error.

---

[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)
