Factuarea APIDevelopers
Contract

Contracted seats, offer packages and the trial

The bill follows the seats you contract: creating an employee takes a free seat, reducing takes effect at renewal with no credit and you choose who is deactivated. Four new operations set and preview the seats, the REST API and MCP buy the missing seats on their own, offer packages keep their prices while their minimums hold, and the trial answers its own reason.

31 October 2026 — The invoice of the employee seats and of the additional tax ID seats is now the invoice of the contracted seats. Creating, activating or reactivating takes a free seat and never charges on its own; only buying seats charges. Deactivating frees a seat without lowering the bill, and a reduction takes effect at renewal, with no credit, choosing who is deactivated when you go below the occupied seats. Buying or creating what a reduction was going to remove cancels it.

Offer packages, up to three lines under one code that is redeemed from the application or by support, keep their agreed price while their minimums hold and the subscription is paid, and end as a whole, with every line back at the catalogue price, if not. No operation is removed.

Operations in this release

OperationoperationIdMCP toolWhat changes
PATCH /v1/accounts/{account}/employee-seatspublic-api.v1.employee-seats.updateupdate_employee_seatsNew. Sets the contracted employee seats.
GET /v1/accounts/{account}/additional-nif-seatspublic-api.v1.additional-nif-seats.statusget_additional_nif_seatsNew. Reads the contracted additional tax ID seats.
GET /v1/accounts/{account}/additional-nif-seats/previewpublic-api.v1.additional-nif-seats.previewpreview_additional_nif_seat_changeNew. Previews a change of those seats.
PATCH /v1/accounts/{account}/additional-nif-seatspublic-api.v1.additional-nif-seats.updateupdate_additional_nif_seatsNew. Sets the contracted additional tax ID seats.
Employee seat statuspublic-api.v1.employee-seats.statusget_employee_seat_billingquantity is the contracted seats. New seats block. reducible_to is always 0. pending_reduction carries deactivations and offer_package_loss.
Employee seat previewpublic-api.v1.employee-seats.previewpreview_employee_seat_chargeNew contracted_seats, seats_to_buy, free_seats_used, included_in_seats, deactivations_required, cancels_pending_reduction and offer_package_loss. already_covered is always false.
Employee seat cancelpublic-api.v1.employee-seats.cancelcancel_employee_seat_addonOptional deactivate and accept_offer_package_loss. Without deactivate, every active employee is deactivated at renewal.
Employee seat subscribe and change quantitypublic-api.v1.employee-seats.subscribe, public-api.v1.employee-seats.change-quantitysubscribe_employee_seat_addon, change_employee_seat_quantityThey converge on the contracted seats.
Creating and reactivating employeespublic-api.v1.employees.create, public-api.v1.employees.reactivatecreate_employee, reactivate_employeeThey take a free seat and buy the missing ones. Send Idempotency-Key.
Creating, activating and receiving tax IDspublic-api.v1.companies.create, public-api.v1.companies.activate, public-api.v1.companies.activate_batch, public-api.v1.account.nif_transfers.acceptcreate_company, activate_company, activate_companies, accept_nif_transferSame behaviour for the additional tax ID seats. Send Idempotency-Key.
Tax ID seat previewpublic-api.v1.companies.seat_charge_previewget_company_seat_charge_previewzero_reason can be included_in_seats.
Employee batchespublic-api.v1.employee-batches.prepare, public-api.v1.employee-batches.refresh_quote, public-api.v1.employee-batches.confirmprepare_employee_batch, refresh_employee_batch_quote, confirm_employee_batchThey use the free seats and buy only the missing ones. The quote now returns seats_to_buy, free_seats_used, original_quantity, projected_quantity and cancels_pending_reduction.
Offer redemptions of employee and managed-company seatspublic-api.v1.employee-seat-offer-redemptions.* and public-api.v1.gestoria-seat-offer-redemptions.*: list, prepare, show, refresh_quote, confirm and cancellist, prepare, get, refresh, confirm and cancel of *_seat_offer_redemptionNew apply_to_existing, minimum_quantity and target_quantity, and the new rejection reasons.

The operations that only adjust their schema are in the table at the bottom and in the schema section.

Contracted seats

The seats block of the status publishes contracted, occupied, free, agreed_minimum, agreed_minimum_ends_at, reducible_to, pending_reduction and enforced. reducible_to is always 0 because a reduction has no floor.

PATCH /v1/accounts/{account}/employee-seats and PATCH /v1/accounts/{account}/additional-nif-seats take {"contracted_seats": N}. A larger number buys seats with a prorated charge with the card of the account, and Idempotency-Key is required. A smaller number is a reduction. The preview takes the same parameter and shows today's amount, the quantity of the next invoice and whether it cancels a pending reduction. See employee seats and additional tax ID seats.

Buying employee seats now needs time tracking: on a plan without it, PATCH /v1/accounts/{account}/employee-seats, POST /v1/accounts/{account}/employee-seats/subscribe and POST /v1/accounts/{account}/employee-seats/change-quantity answer the new 403 employee_seats_not_in_plan before any charge, while lowering or keeping the seats stays allowed. See the error.

Automatic purchase

Without a free seat, the application answers 422 contracted_seats_exhausted and asks you to buy first. The REST API and MCP do not: creating, activating, reactivating and accepting a tax ID transfer buy the missing seats with a prorated charge and then create, with the same 402 errors as before. A retry does not charge twice and the bought seat stays. Send Idempotency-Key on every creation: without it, a retry after a creation that did go through creates another entity. See automatic purchase.

Reduction

A reduction can go down to 0 and takes effect at renewal, with no credit. It is stored as a pending_reduction and the seats stay available until then.

  • Below the occupied seats. deactivate is a list of exactly occupied - contracted active entities. Otherwise the answer is 422 contracted_seats_selection_required.
  • Notice and renewal. A few days before, the owner receives the names. At renewal the task deactivates the chosen ones and sets the quantity.
  • It is cancelled by a purchase, or by a creation, activation, reactivation, batch or transfer that takes what the reduction was going to remove, and by a PATCH to the current quantity. A smaller PATCH replaces it.
  • To 0. It requires choosing all the occupied and cancels the add-on at the end of the period. cancel is a reduction to 0 and, without deactivate, deactivates every active employee.

See reduction.

Offer packages

A package groups up to three lines (plan, employee seats and additional tax ID seats) under one code. It is redeemed from the application or by support; in REST and MCP its code answers 422 customer_offer_not_eligible with details.reason product.

  • apply_to_existing applies a seat offer to the seats the account already has and creates nothing. The quote publishes target_quantity and minimum_quantity.
  • Conditions. The package keeps its prices while the contracted seats of each line stay at or above its minimum and the subscription is paid. Deactivating does not break it; reducing does.
  • The agreed price applies to every contracted seat, including those bought later, also by the automatic purchase.
  • End. It ends as a whole, with every line at the catalogue price from the next renewal and no credit, for reduction_below_minimum, subscription_ended_unpaid, subscription_cancelled, revoked_by_support or duration_elapsed.
  • Confirmation. A reduction that would break a package is previewed with offer_package_loss, and the write needs accept_offer_package_loss: true: without it, 422 offer_package_loss_unconfirmed.

See offer packages and agreed minimum.

The trial

During the trial nothing is charged and employees or tax IDs do not take seats. You can already choose the contracted seats with no charge. A seat or tax ID redemption during the trial answers 422 customer_offer_not_eligible with details.reason trial_active, instead of the previous 409 of the employee batches and of active_population. When the account starts paying, the oldest entities occupy the contracted seats and the ones that do not fit become inactive, with no charge; with no contracted seats, all of them. See the trial of employee seats and the trial rule of tax ID seats.

Errors

  • customer_offer_not_eligible with reason product answers 422 where it answered 403.
  • contracted_seats_selection_required: param deactivate, with details product, requested, occupied, required, selected and invalid. In cancel it is only emitted with a list that does not fit.
  • offer_package_loss_unconfirmed: param accept_offer_package_loss, with details product, package_id, name, effective_at and lines.
  • contracted_seats_exhausted is only emitted by the web application. The REST API and MCP buy instead.
  • contracted_seats_below_minimum is retired: it was never emitted.

The three codes are subcodes of business_rule_violation. See the error reference.

Events

account.seats_updated announces every change of the contracted seats. Its pending_reduction carries the deactivations, and the cause reduction_superseded marks a reduction cancelled by a purchase or an entry. account.offer_package_ended announces the end of a package, with its reason and the concepts of its lines, without amounts. Both go to the account endpoints. See account webhooks.

Schema adjustments and what to do

Several operations only change in the published schema, with nothing different on the wire: those that used not now describe the same rule differently, and nested required fields are now documented. Nothing to do about those.

A series created without number_format now gets {code}-{YYYY}-{0000}, four digits instead of three. Existing series keep their format.

As an integrator:

  1. Send Idempotency-Key on creations, activations, reactivations and transfers, which can now buy seats.
  2. Accept included_in_seats in the zero_reason enum of the previews.
  3. Treat already_covered as always false.
  4. If you cancelled the add-on with active employees, send deactivate: without it all of them are deactivated at renewal.
  5. Expect a purchase or a creation to cancel a pending reduction.
  6. Confirm with accept_offer_package_loss a reduction that would break a package.

The table below lists the operations of this release.

New endpoints4

EndpointDescription
GET/v1/accounts/{account}/additional-nif-seatsRetrieve the additional tax ID seats
PATCH/v1/accounts/{account}/additional-nif-seatsSet the contracted additional tax ID seats
PATCH/v1/accounts/{account}/employee-seatsSet the contracted employee seats
GET/v1/accounts/{account}/additional-nif-seats/previewPreview a change of the additional tax ID seats

Updated endpoints98

EndpointDescription
POST/v1/accounts/{account}/nif-transfers/acceptAccept a tax ID transfer
POST/v1/accounts/{account}/companies/activateActivate several tax IDs of the account
POST/v1/accounts/{account}/companies/{company}/activateActivate a tax ID of the account
POST/v1/companies/{company}/recurring-invoices/{recurring_invoice}/activateActivate recurring invoice
POST/v1/companies/{company}/invoices/{invoice}/annulAnnul an invoice
POST/v1/companies/{company}/invoices/{invoice}/assign-real-numberAssign a real invoice number
POST/v1/companies/{company}/invoices/bulk-createBulk create invoices
POST/v1/accounts/{account}/employee-seats/cancelCancel the employee seat add-on
POST/v1/companies/{company}/recurring-invoices/{recurring_invoice}/cancelCancel recurring invoice
POST/v1/companies/{company}/employee-seat-offer-redemptions/{id}/cancelCancel an employee-seat offer redemption
POST/v1/companies/{company}/gestoria-seat-offer-redemptions/{id}/cancelCancel a managed-company-seat offer redemption
POST/v1/accounts/{account}/employee-seats/change-quantitySync the employee seat quantity
POST/v1/companies/{company}/employee-batches/{id}/confirmConfirm an employee batch
POST/v1/companies/{company}/employee-seat-offer-redemptions/{id}/confirmConfirm an employee-seat offer redemption
POST/v1/companies/{company}/gestoria-seat-offer-redemptions/{id}/confirmConfirm a managed-company-seat offer redemption
POST/v1/companies/{company}/delivery-notes/{delivery_note}/convertConvert delivery note to invoice
POST/v1/companies/{company}/proformas/{proforma}/convertConvert proforma to invoice
POST/v1/companies/{company}/quotes/{quote}/convertConvert quote to invoice
POST/v1/accounts/{account}/webhooksCreate an account webhook endpoint
POST/v1/companies/{company}/invoices/{invoice}/correctiveGenerate corrective invoice
POST/v1/companies/{company}/employeesCreate an employee
POST/v1/companies/{company}/invoicesCreate an invoice
GET/v1/companies/{company}/invoicesList all invoices
POST/v1/companies/{company}/pdf-template-previewsCreate a PDF template preview
POST/v1/companies/{company}/purchase-invoicesCreate an expense
POST/v1/companies/{company}/invoices/{invoice}/create-recurringCreate a recurring invoice from an invoice
POST/v1/companies/{company}/recurring-invoicesCreate a recurring invoice
GET/v1/companies/{company}/recurring-invoicesList all recurring invoices
POST/v1/companies/{company}/transport-documentsCreate a transport document
POST/v1/accounts/{account}/companies/{company}/deactivateDeactivate a tax ID of the account
PATCH/v1/accounts/{account}/webhooks/{webhook}Update an account webhook endpoint
DEL/v1/accounts/{account}/companies/{company}Archive a tax ID of the account
PATCH/v1/companies/{company}/delivery-notes/{delivery_note}Update a delivery note
GET/v1/companies/{company}/invoices/{invoice}Retrieve an invoice
PATCH/v1/companies/{company}/invoices/{invoice}Update an invoice
PATCH/v1/companies/{company}/proformas/{proforma}Update a proforma
PATCH/v1/companies/{company}/purchase-invoices/{purchase_invoice}Update an expense
PATCH/v1/companies/{company}/quotes/{quote}Update a quote
GET/v1/companies/{company}/recurring-invoices/{recurring_invoice}Retrieve a recurring invoice
PATCH/v1/companies/{company}/recurring-invoices/{recurring_invoice}Update a recurring invoice
PATCH/v1/companies/{company}/transport-documents/{transport_document}Update a draft transport document
POST/v1/companies/{company}/invoices/{invoice}/duplicateDuplicate an invoice
POST/v1/companies/{company}/invoices/find-by-external-idFind an invoice by external ID
POST/v1/companies/{company}/invoices/find-by-numberFind an invoice by number
POST/v1/companies/{company}/recurring-invoices/find-by-external-idFind a recurring invoice by external ID
PATCH/v1/companies/{company}/delivery-notes/{delivery_note}/public-linkUpdate a delivery note public link
GET/v1/accounts/{account}/employee-seatsRetrieve employee seat billing status
GET/v1/accounts/{account}/employee-seats/previewPreview the employee seat charge
PATCH/v1/companies/{company}/invoices/{invoice}/public-linkUpdate invoice public link
PATCH/v1/companies/{company}/proformas/{proforma}/public-linkUpdate proforma public link
PATCH/v1/companies/{company}/quotes/{quote}/public-linkUpdate quote public link
GET/v1/accounts/{account}/companies/seat-charge-previewPreview the seat charge of adding a company
POST/v1/companies/{company}/invoices/{invoice}/issueIssue an invoice
GET/v1/accounts/{account}/webhooks/{webhook}/deliveriesList account webhook deliveries
POST/v1/accounts/{account}/companiesRegister a tax ID in the account
POST/v1/companies/{company}/employee-batchesPrepare an employee batch
GET/v1/companies/{company}/eventsList all events
GET/v1/companies/{company}/invoices/{invoice}/correctivesList corrective invoices
GET/v1/companies/{company}/employee-seat-offer-redemptionsList an employee-seat offer redemption
POST/v1/companies/{company}/employee-seat-offer-redemptionsPrepare an employee-seat offer redemption
GET/v1/companies/{company}/gestoria-seat-offer-redemptionsList a managed-company-seat offer redemption
POST/v1/companies/{company}/gestoria-seat-offer-redemptionsPrepare a managed-company-seat offer redemption
GET/v1/companies/{company}/webhook-endpoints/{webhook_endpoint}/deliveriesList webhook deliveries
POST/v1/companies/{company}/invoices/{invoice}/mark-paidMark invoice as paid
POST/v1/companies/{company}/invoices/{invoice}/mark-sentMark an invoice as sent
POST/v1/companies/{company}/transport-documents/{transport_document}/modifyModify an issued transport document
POST/v1/companies/{company}/recurring-invoices/{recurring_invoice}/pausePause recurring invoice
POST/v1/companies/{company}/products/{product}/configurations/impact-previewPreview the impact of restricting a catalog
POST/v1/companies/{company}/employees/{employee}/reactivateReactivate an employee
POST/v1/companies/{company}/employee-batches/{id}/quoteRefresh the quote for an employee batch
POST/v1/companies/{company}/employee-seat-offer-redemptions/{id}/quoteRefresh the quote for an employee-seat offer redemption
POST/v1/companies/{company}/gestoria-seat-offer-redemptions/{id}/quoteRefresh the quote for a managed-company-seat offer redemption
PATCH/v1/companies/{company}/invoices/{invoice}/rescheduleReschedule an invoice
POST/v1/companies/{company}/price-lists/resolve-manyResolve many catalog prices
POST/v1/companies/{company}/recurring-invoices/{recurring_invoice}/resumeResume recurring invoice
POST/v1/companies/{company}/invoices/{invoice}/scheduleSchedule an invoice
POST/v1/accounts/{account}/webhooks/{webhook}/testSend a test event to an account webhook endpoint
POST/v1/companies/{company}/invoices/{invoice}/sendSend invoice by email
GET/v1/accounts/{account}/webhooks/{webhook}/deliveries/{delivery}Retrieve an account webhook delivery
GET/v1/companies/{company}/events/{event}Retrieve an event
GET/v1/companies/{company}/employee-seat-offer-redemptions/{id}Retrieve an employee-seat offer redemption
GET/v1/companies/{company}/gestoria-seat-offer-redemptions/{id}Retrieve a managed-company-seat offer redemption
GET/v1/companies/{company}/webhook-endpoints/{webhook_endpoint}/deliveries/{delivery}Retrieve webhook delivery
POST/v1/companies/{company}/recurring-invoices/{recurring_invoice}/skipSkip the next recurring invoice generation
POST/v1/accounts/{account}/employee-seats/subscribeSubscribe to the employee seat add-on
POST/v1/companies/{company}/invoices/substitute-simplifiedSubstitute simplified invoices with full invoice
POST/v1/companies/{company}/invoices/{invoice}/unscheduleUnschedule an invoice
POST/v1/companies/{company}/invoices/{invoice}/unsendUnsend an invoice
POST/v1/accounts/{account}/companies/{company}/verify-creationVerify the creation of a tax ID
POST/v1/companies/{company}/invoices/{invoice}/voidVoid an invoice
POST/v1/companies/{company}/seriesCreate a series
GET/v1/companies/{company}/seriesList all series
POST/v1/companies/{company}/series/find-by-codeFind a series by code
GET/v1/companies/{company}/series/defaultGet the default series for a document type
GET/v1/companies/{company}/series/activeList active series by document type
GET/v1/companies/{company}/series/{series}Retrieve a series
PATCH/v1/companies/{company}/series/{series}Update a series
GET/v1/companies/{company}/billingRetrieve account billing details

On this page

Need a hand?Contact support