Factuarea API

Imports i dates

Com representa l'API els diners (EUR, dos decimals), les dates (YYYY-MM-DD), els timestamps (ISO-8601) i la zona horària Europe/Madrid emprada per al reinici de quotes.

Cada valor monetari, de data i d'hora de l'API pública segueix un petit conjunt de convencions fixes. Són les mateixes a tots els recursos, així que tan aviat com les gestiones en un lloc el teu client funciona a tot arreu.

Diners

Els imports sempre van en euros (EUR) — el camp currency és present a tots els documents i és "EUR" a v1 (ISO 4217). Encara no hi ha suport multidivisa.

Els imports porten dos decimals (precisió de cèntims). La representació canònica és un string decimal amb exactament dos decimals, a l'estil Stripe:

{ "price": "1234.56" }

Alguns recursos emeten actualment els imports com a números JSON (floats) en lloc de strings decimals — per exemple el total, el subtotal o el unit_price d'un document tornen com a 1802.9, 968, 100. Escriu el teu parser perquè accepti tant un string com un número en qualsevol camp de diners, i normalitza'l a un tipus decimal fix al teu costat (p. ex. Decimal a Python, un big-decimal o un enter d'unitats menors a JS). No guardis mai els diners com un float binari en cru.

Deixa que l'API calculi els totals

No arrodoneixis ni calculis per endavant. Envia les dades en cru de cada línia (quantity, unit_price, discount, el *_id de l'impost) i deixa que l'API derivi el subtotal, l'IVA, el recàrrec, la retenció i el total general. El servidor és l'única font de veritat per a cada total — si arrodoneixes els imports de línia pel teu compte abans d'enviar-los, les teves xifres poden divergir del que emmagatzema l'API.

El total d'un document segueix una sola fórmula a tota l'API:

total = subtotal + total_vat + total_surcharge − total_retention

Si necessites previsualitzar el desglossament abans de crear un document — per a un resum de comanda, un carretó o per conciliar les teves pròpies xifres — crida POST /v1/taxes/calculate-totals amb les línies i llegeix el subtotal, el total_vat, el total_surcharge, el total_retention i el total calculats (imports en EUR), més un desglossament per línia en el mateix ordre:

{
  "subtotal": 250,
  "total_vat": 52.5,
  "total_surcharge": 0,
  "total_retention": 15,
  "total": 287.5,
  "lines": [
    { "subtotal": 100, "vat_amount": 21, "surcharge_amount": 0, "retention_amount": 0, "total": 121 }
  ]
}

El mateix desglossament d'impostos per línia aplica a tots els documents de venda: factures, pressupostos, proformes i albarans accepten tots un retention_rate i un surcharge_rate per línia (retenció d'IRPF i recàrrec d'equivalència, 0–100), i la seva capçalera porta els total_vat, total_surcharge i total_retention agregats. La mateixa fórmula es compleix a tot arreu. Cada línia a més retorna retention_rate i surcharge_rate a la resposta, perquè puguis reconciliar el desglossament línia a línia.

El recàrrec d'equivalència segueix parells legals fixos. Quan una línia declara un surcharge_rate, ha de coincidir amb el tipus d'IVA d'aquesta línia segons el règim espanyol: 21% → 5.2%, 10% → 1.4%, 4% → 0.5%, 0% → 0%. Un parell il·legal (p. ex. tax_rate: 21 amb surcharge_rate: 1.4) es rebutja amb 422 i els parells permesos es retornen a error.allowed_values. Envia només el recàrrec que admet el tipus d'IVA de la línia.

Factures de compra — impost per línia

Una factura de compra registra el que et va cobrar un proveïdor, així que cadascuna de les seves línies accepta uns qualificadors fiscals extra que el costat de venda cobreix a la seva manera. A CreatePurchaseInvoiceRequest.lines[] pots fixar:

CampTipusSignificat
retention_ratenumber (0–100)Retenció d'IRPF aplicada a la línia.
surcharge_ratenumberRecàrrec d'equivalència, mateixos parells legals que en venda.
vat_deductiblebooleanInformatiu — marca l'IVA com a deduïble. No canvia l'import pagat.
exemption_reasonenum o nullPer què la línia està exempta o no subjecta (vegeu sota).

El total per línia segueix la mateixa forma que al costat de venda, restant la retenció i sumant el recàrrec:

total de línia = subtotal + impostos − retention_amount + surcharge_amount

El surcharge_rate d'una línia de compra segueix els mateixos parells legals IVA↔recàrrec que una línia de venda, validats al servidor: 21 → 5.2, 10 → 1.4, 4 → 0.5, 0 → 0. El parell 0 → 0 també és vàlid al costat de compra — una línia exempta o a tipus zero porta un recàrrec zero. Un parell il·legal es rebutja amb 422.

exemption_reason qualifica per què una línia queda fora de l'IVA ordinari. És un enum o null (o absent), cosa que significa que la línia hereta la qualificació de la capçalera de la factura, o no en declara cap:

ValorClasse
E1, E2, E3, E4, E5, E6Exempta (causa d'exempció de la LIVA)
N1, N2No subjecta (causa de no subjecció)
nullHeretar de la capçalera / cap declarada

Una línia de factura de compra que porta alhora un recàrrec i un motiu d'exempció:

{
  "description": "Wholesale goods",
  "quantity": 10,
  "unit_price": "50.00",
  "tax_rate": 21,
  "surcharge_rate": 5.2,
  "retention_rate": 0,
  "vat_deductible": true,
  "exemption_reason": null
}
curl -s -X POST https://api.factuarea.com/v1/purchase_invoices \
  -H "Authorization: Bearer $FACTUAREA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "supplier_id": "01931b3e-...s01",
    "received_on": "2026-03-15",
    "lines": [
      { "description": "Exempt service", "quantity": 1, "unit_price": "200.00", "tax_rate": 0, "surcharge_rate": 0, "exemption_reason": "E1" }
    ]
  }' | jq '.data | {subtotal, total_vat, total_surcharge, total_retention, total}'

Cèntims als informes fiscals. Els endpoints fiscals agregats (Modelo 303 / 347 via /v1/tax_reports/*) retornen els seus imports com a cèntims enters, no com a decimals d'EUR — p. ex. una base imposable acumulada de 25000 significa 250.00 €. Això està documentat camp a camp a la spec; tracta les xifres dels informes fiscals com a unitats menors i divideix per 100 només per mostrar-les.

Dates

Les dates de calendari (sense component horari) usen YYYY-MM-DD — la forma de data completa ISO-8601 / RFC 3339. Això cobreix camps com ara issued_on, due_on, paid_on, valid_until, delivery_date, received_on, start_on i end_on:

{
  "issued_on": "2026-03-15",
  "due_on": "2026-04-14",
  "paid_on": "2026-03-20"
}

Envia les dates en el mateix format. Una data no té hora ni zona horària — és el dia de calendari tal com queda registrat per al document.

Timestamps

Els camps d'instant temporal (metadades d'auditoria i cicle de vida com ara created_at, updated_at, signed_at, last_delivery_at) usen strings de data-hora ISO-8601 / RFC 3339 complets. La majoria s'emeten en UTC amb un sufix Z:

{ "created_at": "2026-05-15T10:34:21Z" }

Alguns timestamps porten en el seu lloc un offset Europe/Madrid explícit (+01:00 a l'hivern, +02:00 a l'estiu):

{ "created_at": "2026-04-15T10:31:05+02:00" }

Totes dues formes són ISO-8601 vàlides i denoten el mateix tipus de valor: un instant exacte. Analitza l'offset — no donis per fet que el string sempre està en UTC. Un parser ISO-8601 en condicions (Instant.parse, datetime.fromisoformat, new Date(...), Carbon::parse) gestiona Z i ±hh:mm de manera idèntica i normalitza a l'instant absolut.

Zona horària per a les quotes

La quota mensual del rate limit es reinicia el dia 1 de cada mes natural a les 00:00 Europe/Madrid (CET/CEST), no en UTC. La quota per minut és una finestra lliscant i la capçalera X-RateLimit-Reset és un UNIX timestamp (segons des de l'epoch, independent de la zona horària). Consulta Rate limits per a la semàntica completa de les finestres.

Sempre que l'API necessita una única referència de calendari civil per a un límit de negoci — períodes fiscals, el reinici de la quota mensual — aquesta referència és Europe/Madrid.

Referència ràpida

ValorFormatExemple
DinersEUR, dos decimals — string decimal (alguns camps emeten un número)"1234.56" / 1802.9
DivisaISO 4217, sempre EUR a v1"EUR"
Imports d'informes fiscalsCèntims enters (unitats menors)25000 → 250.00 €
DataYYYY-MM-DD (ISO-8601 data completa)"2026-03-15"
TimestampISO-8601 data-hora, normalment UTC Z, de vegades ±hh:mm"2026-05-15T10:34:21Z"
Calendari de quotes / fiscalHora civil Europe/Madriddia 1, 00:00 CET/CEST

En aquesta pàgina