Skip to content

Releases: factuarea/factuarea-node

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 20:15
9c24f3b

Minor Changes

  • #19 141b8c6 Thanks @Chelu97! - Regenerate the SDK from the account model contract and expose it from the
    client. This adds to the pending company-axis changeset: both ship together in
    the next minor. Nothing here is published by this change.

    Breaking, in the same single window (axis-and-payload-breaking-window).
    The account-model announcement will be at account-model.

    The claim voucher becomes the NIF transfer. Each of the three retired voucher
    methods is listed next to the transfer method that replaces it:

    Retired Replaced by
    account.claimTokens.create account.nifTransfers.create
    account.claimTokens.list account.nifTransfers.list
    account.claimTokens.accept account.nifTransfers.accept

    account.nifTransfers.revoke is NEW: the voucher had no revoke method to replace.

    The only voucher left is managedAccounts.claimTokens.create, which reissues the
    voucher of a managed account (an addition of the contract, not a leftover).

    New client resources. factuarea.companies (the account's NIF portfolio, with
    stats) and factuarea.managedAccounts (list, create, show, imports,
    accessLevel, plan, management and claimTokens) are now properties of the
    client, next to account. account gains nifTransfers, webhooks (with
    deliveries), requestLogs and provisioningUsage(). The bulk import
    (managedAccounts.imports.create and .preview) takes a FormData and is sent as
    multipart/form-data; the SDK adds no JSON content type.

    The account argument is positional. Account-scoped methods take the account
    id as their first argument, before any other id and before the body. TypeScript
    callers get a compile error, but plain JavaScript callers would shift every
    argument by one place WITHOUT an error: review each call to account.*,
    companies.* and managedAccounts.* when upgrading.

    Webhook verification is unchanged: factuarea.webhooks.verify accepts an account
    envelope and returns it with account, account_relationship and company_id
    intact.

    Six taxes methods are removed, with no replacement (breaking): the contract
    no longer declares them. TaxesResource keeps only list and show; calling any
    of taxes.create, taxes.update, taxes.delete, taxes.setDefault,
    taxes.setDefaultForDocument or taxes.toggle is now a compile error in
    TypeScript and a TypeError in plain JavaScript.

    Two verbs change with the document (breaking, same signatures):
    contacts.restore goes from PATCH to POST (no other contacts method
    changes), and recurringInvoices.update goes from PUT to PATCH.

    Also new on the account axis, besides what is listed above:
    account.members.show; account.members.grants.{list,show,update,delete};
    account.invitations.show; account.apiKeys.updateNifScope (the API-key method
    for the NIF scope); and companies.stats.

    Final axis contract, with the surfaces that landed on flat URLs in 0.8.0 and
    0.9.0.
    The 613-operation contract is regenerated: tasks, projects,
    taskLabels, taskTimers, purchaseScans, purchaseScanEmails, notifications,
    agenda, users, verifactu.representation, contacts.imports and
    series.update now take the company id as their first argument and hang off
    /v1/companies/{company}/…. The scanner paths are purchase-scans (hyphen).

    Every partial update is a PATCH (breaking, same signatures): besides
    recurringInvoices.update, the update methods of contacts, products,
    invoices, quotes, proformas, deliveryNotes, purchaseInvoices, series,
    tasks, projects, webhookEndpoints, employees, workSchedules, absence
    types and policies, and purchaseScans.review, among others, stop using PUT.
    Money amounts in responses are decimal strings ("4.13"), not numbers.

    While the SDK is in 0.x a breaking change stays a minor; 1.0.0 remains
    reserved for the API's GA (docs/VERSIONING.md).

  • #19 03f0e9b Thanks @Chelu97! - Regenerate the SDK from the company-axis contract: every company resource now
    hangs off /v1/companies/{company}/… and the account surface off
    /v1/accounts/{account}/…. 481 operations in 396 paths, up from 469 in 387
    (+17 / −5).

    Breaking — every company-scoped method takes the company first. The company
    stops being inferred in silence from the credential and travels in the URL, where
    it is visible, logged and auditable:

    // Before
    await factuarea.invoices.list({ status: "paid" });
    
    // Now
    await factuarea.invoices.list(company, { status: "paid" });

    company is the company id — the one factuarea.account.show() returns in
    data.scope[].id — never its tax ID or its name.

    Also breaking, in the same single window:

    • factuarea.account.show() keeps its name and now answers on /v1/me,
      returning the credential's scope (data.scope[]) alongside its API key.
    • The X-Active-Profile header is retired: the contract no longer declares it,
      and the axis segment replaces it.
    • Updates use PATCH (contacts.restore, contacts.updateCustomerProfile,
      contacts.updateSupplierProfile, contacts.updateBankAccounts…), and amounts
      travel as decimal strings.
    • The five API-key operations move from the company to the account axis:
      companies.apiKeys.* → account.apiKeys.* on /v1/accounts/{account}/api-keys.

    Added: the account axis (members and their module access, invitations, claim
    tokens, owner transfer, usage), companies.issuingReadiness and
    recurringInvoices.bulkStatus.

    Removed: the ContactRoleV1Request type export. The role of contacts.assignContactRole travels in the path (/contacts/{contact}/roles/{role}), so the operation no longer has a body.

    While the SDK is in 0.x a breaking change stays a minor; 1.0.0 remains
    reserved for the API's GA (docs/VERSIONING.md).

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 14 Oct 18:34
20f3a51

Minor Changes

  • #29 b88375b Thanks @Chelu97! - Regenerate the SDK from an updated public OpenAPI spec
    (+41 operations, -0 operations).

    Auto-generated by the Spec Sync workflow. While the SDK is in
    0.x, a removed or renamed operation stays a minor and
    1.0.0 remains reserved for the API's GA (docs/VERSIONING.md).
    Name the replacement of every removed operation here before merging.

  • #29 b88375b Thanks @Chelu97! - Add transportDocuments for the transport control document (DeCA): list,
    statuses, retrieve, create, update and delete drafts, issue, modify, close,
    reopen, cancel, supersede, send, the evidence, and the PDF, QR and proof of
    issuance downloads. Export TransportDocument, its parts and the request type
    of each step, and add the issue-transport-document example.

    qr now returns a BinaryResponse: the resource generator treats every
    image/* response as binary, so a PNG QR code keeps its bytes.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 04 Oct 23:21
0064ceb

Minor Changes

  • #25 8fab024 Thanks @Chelu97! - Add series.update(series, body?, config?) (PUT /v1/series/{series}, scope series:write) and re-pin spec/openapi.json from the current public contract (571 operations: 1 added, none removed). src/generated/ and src/resources/ are regenerated.

    New in the client:

    • series.update edits a series with a partial body: name, code, counter_reset (never, annual or monthly), number_format, initial_number, invoice_kind and the deprecated year_reset. document_type is not editable. It answers the updated Series. The new type UpdateSeriesRequest is exported from @factuarea/sdk.
    • Each fiscal guard of the numbering arrives as ValidationError with code business_rule_violation and a subcode: series_code_immutable_with_documents, series_format_immutable_with_documents, series_locked_by_verifactu, series_initial_number_creates_gap, series_invoice_kind_locked and series_default_kind_change. Invalid values answer parameter_invalid_value.
    • Changing only counter_reset also emits the webhook series.updated. PATCH and DELETE on a series keep answering 405 series_immutable, now with Allow: GET, PUT; archive a series instead of deleting it.
    • invoices.activities publishes more event_type values with an exact metadata contract: the result of each AEAT submission (verifactu.record_accepted, verifactu.record_rejected, verifactu.transmission_failed, verifactu.transmission_blocked), invoice.email_failed, invoice.public_link_viewed and the payment events payment.payment_created, payment.payment_reversed and payment.payment_updated, whose provider is the gateway (stripe, gocardless, monei, woocommerce or shopify) or null for a manual payment.
    • VeriFactuRecord gains the required aeat_warning_requires_subsanation (boolean | null). Code that builds VeriFactuRecord objects by hand, such as test fixtures typed as VeriFactuRecord, must add it.
  • #25 dab5844 Thanks @Chelu97! - Add unattended checkout (self-service kiosks and vending machines) and the VERI*FACTU remission controls, and re-pin spec/openapi.json from the current public contract (570 operations: 6 added, none removed). src/generated/ and src/resources/ are regenerated.

    New in the client:

    • invoices.create issues a paid simplified invoice in one idempotent call. The request accepts type (F1 or F2), prices_include_tax, payment (method, paid_at, reference), operation_on and the options register_verifactu and wait_for_pdf; client_id is optional, so an F2 without it is an anonymous ticket. The response is the new InvoiceWithCheckoutBlocks type: the invoice plus verifactu (status registered or failed, error_code, aeat_status, huella, qr_url, qr_png_base64, legend, csv), pdf (status, signed url, expires_at) and public_url.
    • A late retry with the same external_id answers 200 with Idempotent-Replayed: true and the invoice already issued. invoices.create returns the same body for 201 and 200; call factuarea.http.request when you need the status or the header. A different type or total answers 409 idempotency_key_reused with subcode unattended_replay_mismatch, and a request still in flight answers 409 resource_locked; both arrive as ConflictError with code, subcode and param.
    • invoices.pdf and invoices.pdfLink accept format: a4 (default), ticket_80 or ticket_58. invoices.pdfLink(invoice, params?, config?) keeps the previous invoices.pdfLink(invoice, config?) call working: a second argument made only of request-option keys (headers, timeout, maxRetries, idempotencyKey) is still read as the options, and any other object is the query.
    • invoices.annul accepts revert_collections, which reverts every live payment (reason issued_in_error) and annuls the invoice atomically. invoices.canAnnul also returns requires_collection_reversal and active_collections_amount.
    • invoices.corrective lines accept unit, regime_key, exemption_reason and exemption_reason_text; an omitted value is inherited from the original line. The conversion of a quote, a proforma or a delivery note can return warnings and warning_codes (zero_rate_line_without_exemption).
    • Invoice gains operation_on.
    • Series carry a purpose: Series.invoice_kind is complete, simplified, corrective or simplified_corrective, and null for a series that is not of invoices. series.create accepts invoice_kind. series.list, series.default and series.active accept an invoice_kind filter, and series.active also takes document_type; series.active(params?, config?) keeps the series.active(config?) call working with the same rule as invoices.pdfLink.
    • series_id is optional and nullable in invoices.create. invoices.update accepts type (F1 or F2). invoices.corrective accepts correction_nature (I or S) and series_id. invoices.duplicate and series.active document a 422 response.
    • contacts.imports.show retrieves a contact import (BusinessContactImport), and contacts.imports.errors downloads its errors as CSV and returns a BinaryResponse. BusinessContactImportPreview gains import_uuid, added_count, skipped_count, failed_count, unprocessed_count, status and failure_reason, so code that builds that type by hand must add them; its rows gain an optional result.
    • The types BusinessContactImport, CreateCorrectiveInvoiceRequest, CreateSeriesRequest and UpdateInvoiceRequest are exported from @factuarea/sdk.
    • verifactu.records.retryBlocked reactivates every blocked record at once. VeriFactuRecord gains aeat_error_code, is_blocked, block_reason and can_subsanar, and verifactu.records.subsanar now returns the id of the new record. VeriFactuStats gains pending_incident_count, blocked_incident_count and oldest_pending_at.
    • verifactu.representation (show, register, revoke) manages the representation that enables remission by a third party. VeriFactuConfig gains remission_mode and the active_representation_* fields, and verifactu.settings accepts remission_mode.
    • FactuareaError.lineIndex carries error.line_index, the zero-based position of the document line a domain rule rejected, the N of lines.N.tax_rate. It is null for any other error.
    • The types CreateInvoiceRequest, InvoiceWithCheckoutBlocks, AnnulInvoiceV1Request, CanAnnulInvoice, CompanyRepresentation, RegisterCompanyRepresentationV1Request, RemissionMode, RepresentationKind, VeriFactuConfig, VeriFactuRecord and VeriFactuStats are exported from @factuarea/sdk.

    Breaking changes (the SDK is in 0.x, so they land in a minor):

    • A sale line with no tax_rate, no referenced tax and no product with a tax no longer receives an implicit 21 %. It takes the company's default VAT for the document, or the request is rejected with 422 missing_required_param, param lines.N.tax_rate and line_index N.
    • Operations that issue an invoice (invoices.create when it issues, issue, corrective, substituteSimplified, and send and markSent when they issue) can answer 422 verifactu_not_eligible when a field does not fit the AEAT billing record: a customer name over 120 characters, a Spanish tax ID that is not 9 characters, an invoice number with characters the AEAT does not accept, or more than 12 tax breakdowns. error.param says which (client_id, series_id, original_invoice_id, simplified_invoice_uuids, company_name, lines, total or type). No number is consumed and the invoice stays as it was, so correct the data and repeat. In bulkCreate and bulkStatus the rejection appears per element in failures.
    • Issuing and annulling (annul, void) answer 422 verifactu_not_eligible with subcode signing_certificate_unavailable for a company that has enabled VeriFactu in NO VERIFACTU mode and has no usable certificate, until one is uploaded. error.param is certificate, representation or system_certificate. Companies with VeriFactu disabled and companies in VERIFACTU mode are not affected.
    • verifactu.records.retry no longer answers max_retries_exceeded: a record is retried without a cap while the incident lasts.
    • Invoice gains the required operation_on (string | null). Code that builds Invoice objects by hand, such as test fixtures typed as Invoice, must add it.
    • The payment reversal reason gains issued_in_error in InvoicePaymentDetail.reversal_reason and in the payment.reversed event, so an exhaustive switch over it needs a new case. It cannot be requested for a single payment with paymentsRevert.

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 30 Sep 22:18
0b7fb1e

Minor Changes

  • #22 cd19edd Thanks @Chelu97! - Add the tasks and projects resources and re-pin spec/openapi.json from the current public contract (457 paths / 564 operations: 81 added, none removed). src/generated/ and src/resources/ are regenerated.

    New resources on the client (80 operations). Every write sends an Idempotency-Key, lists return a Page with cursor auto-pagination, and errors use the typed hierarchy.

    • factuarea.projects (22): list, create, show, update, delete, archive, unarchive, findByKey; columns (list, create, update, delete, reorder); customFields (list, create, update, delete); tasks (export, import); timeSummary.show; timeInvoices (preview, create). columns.delete takes move_to_column_id in its query to relocate the column's tasks.
    • factuarea.tasks (45): search, create, show, update, delete, duplicate, findByKey, linked, status, move, reposition, assign, unassign, bulkStatus, bulkUpdate, bulkDelete; comments (list, create, update, delete); relations (list, create, delete); labels (assign, unassign); customFields.set; externalLinks (list, create, delete); entityLinks (list, create, delete); attachments (list, show, create, download, delete); uploadLinks.create; timeEntries (list, show, create, update, delete); timer.start; activities.list. create accepts entity_link to link the task to a document or contact in the same call, and custom_fields is a map from field id to a string, number, boolean, string array or null.
    • factuarea.taskLabels (5): list, create, show, update, delete.
    • factuarea.taskTimers (2): current ({ data: null } when nothing is running) and stop.
    • factuarea.users (2): me, list.
    • factuarea.notifications (3): list, read, markAllRead.
    • factuarea.agenda (1): list, a combined agenda of due tasks, document due dates, tax deadlines, absences and holidays.

    The request and response types of these resources (Project, ProjectColumn, Task, TaskComment, TaskLabel, TaskTimeEntry, TaskAttachment, AgendaItem, CreateTaskV1Request, UpdateTaskV1Request, LogTaskTimeV1Request and the rest) are exported from @factuarea/sdk.

    Also carried by the re-pin, measured against the previous pinned spec:

    • New invoices.issue (POST /invoices/{invoice}/issue).
    • Invoice gains issued_at, sent_via and is_sent, its status is now a typed union, and invoices.list accepts an is_sent filter.
    • Recurring invoices gain generation_mode (draft, issue or issue_and_send) on create, update and read.
    • 24 new webhook event types, accepted by webhookEndpoints subscriptions and test events: invoice.issued, invoice.marked_sent, invoice.unsent and 21 for tasks, comments, time entries and projects.
    • New enum values: issued in the bulk invoice status change, issued in place of sent in the invoice Excel export status filter, issue in place of draft as a scheduled invoice action, and the automation action types create_task, change_task_status, assign_task and add_task_comment.
    • API key scopes: projects:read|write|delete, tasks:read|write|delete, users:read and notifications:read|write are added; the retired clients:* and suppliers:* scopes leave the enum.

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 27 Sep 16:57
f3c4fd8

Minor Changes

  • #12 4c2ee4d Thanks @fernandoc00! - Add purchase scanner resources and extraction/review types from the backend contract. Support batch uploads, source downloads, versioned review and draft conversion, duplicate resolution, archive/restore, and inbound email history. Preserve structured batch failures and request options across pagination.

    Fix the default request-version header to the supported stable version 2026-06-01; the previous export-date pin was rejected by the backend.

  • #12 396bf15 Thanks @fernandoc00! - Re-pin spec/openapi.json from the current backend contract (399 paths / 483 operations) and regenerate src/generated/ and src/resources/.

    BREAKING: the backend retired the legacy clients/suppliers routes (replaced by contacts, which already covers the same identities and roles). ClientsResource, SuppliersResource, the factuarea.clients/factuarea.suppliers client properties and the Supplier type export are removed; the SDK stays in 0.x (breaking changes may land in a minor while pre-GA, docs/VERSIONING.md), so this is a minor, not a major, release. Use contacts for every identity, role and profile operation.

    Harden scripts/build-resources.mjs (design D4): operations without x-speakeasy-group now fail the generator with a listing of method path operationId before any output is written, instead of being silently dropped. The script also accepts --spec <path>/--out <dir> for testing against fixture specs.

    Add spec-guided Idempotency-Key support (design D6): _send/_delete in src/core/resource.ts accept an optional fifth { idempotent?: boolean } argument, and the generator sets it for non-POST mutations the spec marks as requiring the header. src/core/http-client.ts's METHODS_WITH_IDEMPOTENCY already generates the header unconditionally for every POST/PUT/PATCH/DELETE (a broader policy than D6, already shipped on this branch before this change) — that blanket behavior is kept as-is per the repo owner's instruction, so this is additive, not a narrowing.

    Method names follow backend/docs/api/sdk-method-naming.md @ 1.1.0 (up from the 1.0.0 cited by the generator before this change; the naming rule itself did not change).

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 21 Sep 11:37
b08a1f6

Minor Changes

  • #16 90f936c Thanks @Chelu97! - Regenerate the SDK from the public OpenAPI spec that publishes contacts as the
    sole identity resource (+9 operations, -28 operations; 469 in total).

    Removed: the clients and suppliers resources, retired from the public API on
    2026-09-16 (/v1/clients/* and /v1/suppliers/*), plus the Supplier type.
    Replacements, all on factuarea.contacts (filter by roles: ["customer"] or
    roles: ["supplier"] where the legacy resource implied the role):

    • clients.list|search|show|create|update|delete and suppliers.* → contacts.list|search|show|create|update|delete
    • clients.stats / suppliers.stats → contacts.stats
    • clients.activities / suppliers.activities → contacts.activities
    • clients.bulkCreate → contacts.bulkCreate; clients.bulkDelete / suppliers.bulkDelete → contacts.bulkDelete
    • clients.import / clients.importTemplate → contacts.import / contacts.importTemplate
    • clients.censusVerification → contacts.verifyCensus
    • clients.findByTaxId / suppliers.findByTaxId → contacts.findByTaxId
    • clients.findByExternalId / suppliers.findByExternalId → contacts.findByExternalId
    • suppliers.bulkStatus → contacts.bulkChangeContactRoleStatus
    • suppliers.toggleActive → contacts.changeContactRoleStatus

    Added on contacts: stats, activities, bulkCreate, bulkDelete,
    importTemplate, verifyCensus, findByTaxId, findByExternalId and
    archive.

    While the SDK is in 0.x a removed operation is a minor; 1.0.0 stays
    reserved for the API's GA (docs/VERSIONING.md).

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 15 Sep 22:17
0ee2194

Minor Changes

  • #13 ecf8c54 Thanks @fernandoc00! - Export the canonical contact and request types, make contacts the default in examples and documentation, and mark legacy client/supplier projections as compatibility resources. Cover contact role, profile, import and archive/restore operations against the public contract.

    Preserve per-request headers (including the active company profile), timeouts and abort signals across paginated requests. Encode boolean query filters as 0/1 for Laravel validation and expose import mappings as named-column objects instead of arrays.

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 12 Sep 20:13
4784b9d

Minor Changes

  • #10 271b9f7 Thanks @fernandoc00! - Add canonical contacts, contact roles and preferences, and preserve array filters in Laravel-compatible query parameters.

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 09 Sep 23:38
2f360e6

Patch Changes

  • #7 25619ea Thanks @Chelu97! - products.variants.update: stock no longer declares minimum: 0. Send the current balance to leave it untouched (it may be negative when delivered documents ran ahead of the incoming stock); any other value is a manual set and must still be >= 0 (422 otherwise). products.variants.create keeps minimum: 0.

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 09 Sep 17:24
1378437

Minor Changes

  • #5 53510b2 Thanks @Chelu97! - Regenerate the SDK from the public OpenAPI spec published with Factuarea v1.15.26
    (+57 operations, -0 operations): the automation engine (client.automations.*,
    18 operations), ecommerce stores, product options and configurations, price-list
    resolution and stock-ledger audit.

    The resource generator now nests namespaces to any depth
    (client.automations.rules.versions.list()), which the three-level
    automations.rules.versions and automations.runs.steps groups require: with
    two levels their methods collided with rules.list / runs.list.