---
title: "Subscribe to the employee seat add-on"
method: POST
path: "/accounts/{account}/employee-seats/subscribe"
tags: ["Employees"]
---

# Subscribe to the employee seat add-on

`POST /accounts/{account}/employee-seats/subscribe`

## Request

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

Subscribe to the monthly per-employee add-on, charging the first period with the payment method on file.
- Atomic: 402 `employee_seat_payment_method_required` or `employee_seat_charge_failed` subscribes nothing.
- Owner or admin only (403 `forbidden_action`); 403 `billing_managed_by_provider` if the provider manages billing.

## Path parameters

- `account` string, uuid, required

## Headers

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

## Response `200`

- object
  - `data` EmployeeSeatBillingStatus, required: Billing status of the per-employee add-on for your company (Control Horario). Whether the dedicated `employee-seats` subscription is active, how many seats are billed, how many employees are active and the recurring per-seat cost. Amounts are euro 2-decimal strings and are null when the cost is not resolvable (not subscribed, no active plan, enterprise outside Stripe, sandbox) — never a misleading 0. Employees never count towards the plan `users` seat limit. Read `subscribed` together with `seats_billable` to tell a legitimate no-charge state apart from a billing anomaly.
    - `object` 'employee_seat_billing_status', required: Stripe-like discriminator. Always `employee_seat_billing_status` for this resource.
    - `subscribed` boolean, required: true when the company has the per-employee add-on subscribed (`employee-seats` subscription active).
    - `quantity` integer, required: Number of BILLED seats: while subscribed it follows the number of active employees; 0 when not subscribed.
    - `active_employees` integer, required: Real number of `active` employees of the company. When not subscribed it reveals how many seats an opt-in would bill; when subscribed it matches `quantity`.
    - `unit_amount` string, nullable, required: Taxable base of one seat per billing cycle, in euros as a 2-decimal string, or null when not resolvable.
    - `tax_rate` integer, nullable, required: Applied VAT rate (e.g. 21), or null when not resolved.
    - `tax_amount` string, nullable, required: VAT amount of one seat, in euros as a 2-decimal string, or null.
    - `total_per_seat` string, nullable, required: Base + VAT of one seat, in euros as a 2-decimal string, or null.
    - `recurring_total` string, nullable, required: Projected recurring total (`total_per_seat` × `quantity`), in euros as a 2-decimal string. Null when VAT is not resolved.
    - `currency` string, required: ISO 4217 currency code (uppercase).
    - `billing_interval` 'month' | 'null', nullable, required: The seat is always billed monthly, regardless of the plan interval; null when not subscribed.
    - `next_invoice_at` string, date-time, nullable, required: End of the current covered period of the seat subscription (ISO 8601), or null.
    - `requires_active_plan` boolean, required: true when the company has no active paid plan, so the seat cost cannot be resolved.
    - `seats_billable` boolean, required: true when your company MUST be paying per seat (live paid plan), regardless of whether the `employee-seats` subscription exists — it is independent of `subscribed`. Combine both: `subscribed: true` means seats are being billed normally; `subscribed: false` with `seats_billable: true` and `active_employees > 0` is a BILLING ANOMALY (active employees with no seat billed) that your provider must settle; `seats_billable: false` is a legitimate no-charge state (enterprise by contract, trial or sandbox).

## 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. `employee_seat_mutation_outcome_unknown`: an employee seat operation is still being verified. `details.operation_id` is its reference and `details.operation_kind` is `legacy_employee`; do not repeat the charge and contact support with the reference. `employee_seat_operation_in_progress`: another employee operation is pending. `details.operation_id` identifies it when known; read its state before starting another. `employee_seat_phase_incompatible` with `param` `quantity`: the subscription has scheduled conditions that must be reviewed before its seats change. `details.reason` is `phase_incompatible`. Nothing was charged.
- `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.

---

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