Factuarea API

Empreses gestionades

Dona d'alta, aprovisiona i opera empreses filles sota el teu tenant mestre — el model de gestoria des de l'API v1, amb cobrament per-seat i un cicle de vida activa/desactivada.

Una empresa gestionada és un subcompte fill que crees i operes sota el teu propi tenant mestre. És el model de gestoria: una assessoria (la mestra) manté un únic joc de credencials i, mitjançant elles, dona d'alta i gestiona moltes empreses clients, cadascuna aïllada de les altres.

Aprovisiones cada empresa filla i després la manejes de dues maneres: emets una API key filla acotada a ella, o mantens la teva master key i canvies d'empresa objectiu per petició amb el header X-Active-Profile. Aquesta pàgina cobreix les empreses en si — crear-les, aprovisionar-les, el seu cicle de vida activa/desactivada, el cobrament de places i l'arxivat.

Onze endpoints sota /v1/companies gestionen les empreses.

OperacióEndpointScope
Llistar empresesGET /v1/companiescompanies:read
Crear una empresaPOST /v1/companiescompanies:write
Recuperar una empresaGET /v1/companies/{id}companies:read
Actualitzar una empresaPATCH /v1/companies/{id}companies:write
Arxivar una empresaDELETE /v1/companies/{id}companies:delete
Consultar l'estat de creacióGET /v1/companies/{id}/creation-statuscompanies:read
Verificar (reconciliar) la creacióPOST /v1/companies/{id}/verify-creationcompanies:write
Desactivar una empresaPOST /v1/companies/{id}/deactivatecompanies:write
Reactivar una empresaPOST /v1/companies/{id}/activatecompanies:write
Activar empreses en blocPOST /v1/companies/activatecompanies:write
Previsualitzar el cobrament de la plaçaGET /v1/companies/seat-charge-previewcompanies:read

{id} és l'id de l'empresa — un UUID v7 opac, no el seu tax_id. Mira els esquemes complets a la Referència de l'API.

Crea una empresa gestionada

POST /v1/companies dona d'alta una nova empresa filla sota el teu tenant mestre. name i tax_id són els únics camps obligatoris; la resta del perfil (raó social, adreça fiscal, dades de contacte) és opcional i es pot enviar en la mateixa petició. El tax_id (NIF / CIF / NIE) ha de ser únic entre les empreses que ja gestiones; un duplicat retorna 409. Requereix el scope companies:write.

curl -X POST https://api.factuarea.com/v1/companies \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "name": "Talleres García SL",
    "tax_id": "B12345678"
  }'

Resposta (201):

{
  "data": {
    "object": "company",
    "id": "01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c",
    "name": "Talleres García SL",
    "business_name": "Talleres García, Sociedad Limitada",
    "tax_id": "B12345678",
    "status": "active",
    "address": "Calle Mayor 1",
    "city": "Madrid",
    "postal_code": "28013",
    "province": "Madrid",
    "country_aeat_zone": "peninsula",
    "email": "contacto@talleresgarcia.es",
    "phone": null,
    "logo_url": null,
    "created_at": "2026-01-15T09:30:00+00:00",
    "updated_at": null
  }
}

Cos de la petició

CampObligatoriNotes
nameNom comercial (1–255 caràcters).
tax_idIdentificador fiscal espanyol (NIF / CIF / NIE). Immutable després de l'alta.
business_namenoRaó social, fins a 100 caràcters.
addressnoAdreça fiscal.
citynoCiutat de la seu fiscal.
postal_codenoCodi postal — d'ell es deriva la zona AEAT (country_aeat_zone a les respostes).
provincenoProvíncia.
countrynoPaís.
emailnoEmail de contacte.
phonenoTelèfon de contacte.

El camp status de la resposta és el cicle de vida activa/desactivada de l'empresa, un eix diferent del provisioning_status que segueix l'aprovisionament asíncron. No hi ha camp d'entrada country_aeat_zone — envies un country de text lliure, i la zona AEAT es deriva del postal_code.

A l'alta només s'aplica validació a nivell de formulari. La comprovació censal amb l'AEAT és un pas d'aprovisionament a part — donar d'alta una empresa aquí no la verifica contra el cens en la mateixa petició.

Identificador fiscal duplicat

Reutilitzar un tax_id que ja gestiones retorna 409 amb resource_already_exists, i existing_resource_id apunta a l'empresa que ja el té:

{
  "error": {
    "type": "invalid_request_error",
    "code": "resource_already_exists",
    "message": "Ya gestionas una empresa con este NIF.",
    "param": "tax_id",
    "existing_resource_id": "01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c"
  }
}

El tax_id és únic per tenant mestre, no a nivell global: dues gestories diferents poden gestionar cadascuna una empresa amb el mateix identificador fiscal.

Cicle de vida de l'aprovisionament

Donar d'alta una empresa de facturació real no és instantani. POST /v1/companies respon a l'instant, però al darrere l'empresa filla s'aprovisiona de manera asíncrona: es creen una sèrie de documents per defecte i la config fiscal mínima i — en live — es cobra a la gestoria la nova plaça. Fins que això acaba, la filla encara no és operativa. Dos endpoints exposen el cicle: un per consultar-lo i un altre per reconciliar-lo.

OperacióEndpointScope
Consultar l'estat de creacióGET /v1/companies/{id}/creation-statuscompanies:read
Verificar (reconciliar) la creacióPOST /v1/companies/{id}/verify-creationcompanies:write

Estats d'aprovisionament

provisioning_status recorre un cicle de vida petit i d'un sol sentit:

EstatSignificat
pendingLa filla es va donar d'alta; l'aprovisionament encara no ha començat.
awaiting_paymentLa gestoria no té cap mètode de pagament registrat, així que la plaça encara no es pot cobrar. payment_setup_url apunta a on el tenant mestre n'afegeix un.
provisioningLa plaça es va cobrar (o la filla està en mode de prova) i el tenant s'està configurant.
activeL'aprovisionament ha acabat. La filla és plenament operativa.
failedL'aprovisionament no s'ha pogut completar — failed_reason indica el motiu. Torna a crear l'empresa per reintentar-ho.

Amb una clau de prova (fact_test_) no hi ha cap crida a Stripe: la filla passa directament a active, de manera determinista. El camí d'awaiting_payment i el cobrament per-seat només apliquen a les claus live.

Cobrament per-seat

En live, cada empresa filla activa és una plaça que es cobra dins la subscripció ja existent del tenant mestre — una sola factura recurrent que es llegeix com a "pla + N clients". Afegir una filla afegeix una plaça i cobra el prorrateig de seguida pel que queda del període de facturació; arxivar una filla treu la plaça i abona el temps no usat a la factura següent. La filla no arriba a active fins que aquest cobrament immediat té èxit; si falla, la filla acaba en failed. Previsualitza l'import per endavant amb el preview de la plaça.

Com que la plaça viu en la mateixa subscripció del tenant mestre, la filla hereta el pla i els add-ons del mestre, i un impagament de la subscripció del mestre suspèn el compte sencer de la gestoria — les seves filles incloses. No hi ha cap factura separada per filla.

Consulta l'estat de creació

GET /v1/companies/{id}/creation-status retorna el provisioning_status actual i les marques de temps. Consulta'l després de crear una empresa fins que arribi a active (o failed). Requereix el scope companies:read.

curl https://api.factuarea.com/v1/companies/01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c/creation-status \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"

Resposta (200):

{
  "data": {
    "object": "company_creation_status",
    "id": "01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c",
    "provisioning_status": "active",
    "payment_setup_url": null,
    "failed_reason": null,
    "started_at": "2026-01-15T09:30:00+00:00",
    "completed_at": "2026-01-15T09:31:00+00:00"
  }
}

payment_setup_url és present només mentre awaiting_payment, i failed_reason només quan failed; tots dos són null en els altres casos.

Verifica la creació

POST /v1/companies/{id}/verify-creation reconcilia una filla contra la subscripció del tenant mestre i la fa avançar quan pot. No porta cos de petició i és idempotent. Requereix el scope companies:write.

curl -X POST \
  https://api.factuarea.com/v1/companies/01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c/verify-creation \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"

Crida'l un cop el tenant mestre hagi afegit un mètode de pagament, o quan vulguis treure una filla d'awaiting_payment:

  • Una filla que ja està active és una operació sense efecte — la crida es pot repetir sense risc.
  • Mentre awaiting_payment, si el mestre ja té un mètode de pagament, es cobra la plaça prorratejada i la filla passa a active.
  • Si el mestre encara no té mètode de pagament, la crida no té efecte ni error — la filla es manté en awaiting_payment.

Retorna el mateix recurs de creation-status que l'endpoint de consulta, així que pots llegir el provisioning_status resultant directament de la resposta.

El cicle de vida activa/desactivada

A part de l'aprovisionament, cada filla porta un status — el seu cicle de vida del vincle dins la gestoria. És el camp status del recurs d'empresa, i recorre tres estats:

EstatSignificat
activeLa filla està vinculada i operativa.
inactiveLa filla està desactivada — inaccessible fins que la reactives (pagant de nou la seva plaça), però amb les seves dades intactes i de manera reversible.
archivedLa filla ha estat desvinculada. És un estat terminal.

Les transicions són active ↔ inactive (desactivar / reactivar) i active → archived o inactive → archived (arxivar). archived és terminal.

Desactivar allibera la plaça; reactivar la cobra de nou. Això permet a una gestoria aparcar un client entre encàrrecs sense perdre el seu historial, i recuperar-lo més tard.

Desactiva una empresa

POST /v1/companies/{id}/deactivate passa una filla active a inactive. L'empresa queda inaccessible però conserva totes les seves dades, de manera reversible. No cobra: l'abonament prorratejat de la plaça alliberada s'aplica best-effort a la factura següent. Requereix el scope companies:write.

curl -X POST \
  https://api.factuarea.com/v1/companies/01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c/deactivate \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"

Retorna el recurs d'empresa actualitzat amb status: "inactive".

Reactiva una empresa

POST /v1/companies/{id}/activate torna una filla inactive a active. La reactivació està gatejada per un cobrament atòmic de la plaça: primer es cobra el prorrateig, i només si el cobrament té èxit la filla passa a active. Si el mestre no té mètode de pagament, o el cobrament falla, l'empresa segueix inactive. Requereix el scope companies:write.

curl -X POST \
  https://api.factuarea.com/v1/companies/01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c/activate \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"

Retorna el recurs d'empresa actualitzat amb status: "active".

Activa empreses en bloc

POST /v1/companies/activate reactiva diverses filles en una sola crida, amb un únic cobrament conjunt — una factura per a tot el lot en comptes d'una per empresa. El cos porta company_ids, una llista de valors id d'empresa filla (1–1000). Requereix el scope companies:write.

curl -X POST https://api.factuarea.com/v1/companies/activate \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z" \
  -H "Content-Type: application/json" \
  -d '{
    "company_ids": [
      "01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c",
      "01931b3e-8d5b-7a1f-9c2d-5e6f7a8b9c0d"
    ]
  }'

El cobrament és atòmic a nivell de lot — o totes o cap. La propietat (404 per a una empresa fora del teu arbre) i la precondició inactive (422) es validen per a cada empresa abans que s'executi cap cobrament. La resposta és la llista d'empreses reactivades ({ "data": [ … ] }).

Previsualitza el cobrament de la plaça

GET /v1/companies/seat-charge-preview retorna el que costaria afegir o reactivar empreses filles, sense cobrar res. Fes-lo servir per mostrar el prorrateig abans d'un POST /v1/companies o d'una activació, i per detectar per endavant el cas "sense mètode de pagament". Requereix el scope companies:read.

Té dos modes:

  • count (≥1, default 1) — previsualitza el prorrateig conjunt d'activar aquest nombre de filles en un lot.
  • company_ids — una llista de valors id de filles concretes, per a un preview conscient de la cobertura: l'import és 0 amb already_covered: true quan totes segueixen cobertes aquest període, i en cas contrari prorrateja només les no cobertes. Quan s'envia, mana sobre count.
curl "https://api.factuarea.com/v1/companies/seat-charge-preview?count=1" \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"

Resposta (200):

{
  "data": {
    "object": "seat_charge_preview",
    "amount": 1240,
    "tax_amount": 260,
    "total": 1500,
    "tax_rate": 21,
    "currency": "EUR",
    "next_invoice_date": "2026-02-01",
    "requires_payment_method": false,
    "requires_active_plan": false,
    "included_in_trial": false,
    "already_covered": false,
    "is_first_seat": false,
    "recurring_quantity": 4,
    "recurring_base_cents": 4000,
    "recurring_total_cents": 4840
  }
}

amount és la base imposable del prorrateig en unitats mínimes de la moneda (cèntims), tax_amount l'IVA, i total (amount + tax_amount) el que es cobra realment. tax_rate és el percentatge d'IVA derivat (p. ex. 21) o null si Stripe Tax no el va calcular. Els camps recurring_* projecten la quota mensual conjunta després de l'activació: nombre total de places, base sense IVA i total amb IVA (recurring_total_cents és null quan l'IVA no és calculable).

Quatre flags mútuament excloents expliquen un import 0, per ordre de prioritat:

FlagL'amount és 0 perquè…
already_coveredLes empreses que activaries ja estan incloses en la subscripció d'aquest període — reactivar-les és gratis.
requires_active_planLa gestoria no té pla vigent i ha de contractar-ne un abans de gestionar empreses.
included_in_trialLa gestoria està en el seu període de prova — l'empresa es crea gratis (les places comencen a cobrar-se quan el trial es converteix en pla de pagament).
requires_payment_methodLa gestoria té un pla de pagament però cap mètode de pagament registrat, i ha d'afegir-ne un (Billing Portal) primer.

is_first_seat és true quan l'activació crea la primera subscripció de places del mestre: el càrrec és un mes complet i avui ancora el dia de cobrament mensual del cicle conjunt.

Llista i recupera empreses

GET /v1/companies retorna les teves empreses gestionades amb paginació per cursor; GET /v1/companies/{id} en retorna una. Ambdues estan acotades al teu tenant mestre.

curl https://api.factuarea.com/v1/companies?limit=25 \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"

Una empresa gestionada per un tenant mestre diferent retorna 404, mai 403 — l'API no revela mai que existeix una empresa que no pots gestionar.

Actualitza una empresa

PATCH /v1/companies/{id} és una actualització parcial. L'únic camp editable és name — el perfil (raó social, adreça fiscal, contacte, zona AEAT) no és editable aquí, i el tax_id és immutable i es rebutja si l'inclous al cos. Una empresa ha d'estar active per editar-se. Requereix el scope companies:write.

curl -X PATCH \
  https://api.factuarea.com/v1/companies/01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Talleres García e Hijos SL" }'

Arxiva una empresa

DELETE /v1/companies/{id} arxiva l'empresa en lloc d'esborrar-la: el seu status passa a archived i deixa d'acceptar operacions. Una empresa active o inactive es pot arxivar; archived és terminal. Requereix el scope companies:delete.

curl -X DELETE \
  https://api.factuarea.com/v1/companies/01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"

L'arxivat pot quedar bloquejat: si l'empresa encara té estat que ho impedeix (per exemple documents pendents), la petició retorna 422 i l'empresa conserva el seu estat actual. Resol abans la condició que ho bloqueja i després arxiva-la.

Scopes i aïllament

Les empreses es protegeixen amb els seus propis scopes:

  • companies:read — llistar i recuperar empreses gestionades, consultar l'estat de creació i previsualitzar el cobrament de la plaça.
  • companies:write — crear, actualitzar, activar i desactivar empreses gestionades, i verificar la seva creació.
  • companies:delete — arxivar empreses gestionades.

Tota operació està acotada al teu tenant mestre. Un id d'empresa que pertany a un altre mestre retorna 404 — mai 403. Aquest aïllament entre mestres és la garantia central del model de gestoria: un mestre només veu i actua sobre les seves pròpies empreses. La mateixa garantia regeix actuar en nom d'una filla i les seves API keys.

En aquesta pàgina