Tabba.
IntegrationerSådan virker TabbaFeatures

© 2026 Tabba. Alle rettigheder forbeholdes.

Udviklere
Udviklere
Udviklere
Getting startedQuickstartAuthenticationAccounting platformsexternal_id and idempotencyWork registrationIssuance and auto-sendWebhooksPaginationErrors

Andre spor

AI clientsAPI reference

Accounting platforms

One API over Dinero and e-conomic: what is identical, the fields that name a platform's own choice, and what a platform can refuse.

A key is bound to one connected company, and that company keeps its books in one accounting system: Dinero or e-conomic. Which one it is, is not something your integration has to know.

Every endpoint under /api/v1 behaves the same on either: the same request bodies, the same response shapes, the same status codes and the same error codes. No field, no code and no message of the API names a platform. You write the integration once, and it keeps working for a company on the other system.

This page is where the two are named, because the few differences below are yours to act on.

What stays the same

  • Field names. platform_ref and platform_number on an invoice, a credit note and an accrual entry are the handle and the number the accounting system gave the booked document, whichever system that is.
  • Error codes. PLATFORM_API_ERROR is the 502 for an accounting system that could not be reached or did not answer. A refusal by the accounting system is data under refusal, with a reason code of Tabba's own and the platform's words beside it.
  • send_error. null on a document whose delivery succeeded, and an object with a reason and the platform's own words (platform_reason) when the document was booked and its delivery is not known to have succeeded.
  • Amounts, dates, currencies, recognition and the month-end accrual are Tabba's own arithmetic and are identical by construction.

Ids are the platform's handles

A customer's and a product's id is the handle the accounting system knows the record by: a GUID on Dinero, the customer or product number on e-conomic. Treat it as opaque text. It is not always a UUID, and a number can be given to another record once its own is deleted in the accounting system.

Address records by your own external_id and you never depend on the handle: see external_id and idempotency.

Fields that name a platform's own choice

A few fields of a customer and a product name an entry of a list the accounting system keeps, or a fact only one system holds.

FieldOn DineroOn e-conomic
vat_zone_ref (customer)not keptrequired: the VAT zone the customer is placed in
customer_group_ref (customer)not keptrequired: the customer group the customer is filed in
payment_terms_ref (customer)not keptan entry of the company's list of payment terms
layout_ref (customer)not keptthe customer's document layout
payment_mean (customer)required when send_method is einvoicenot asked for
invoice_mail_out_option_key (customer)VAT, GLN, SE or PGLN
account_ref (product)the account number as text, and may be left outthe number of the product group the revenue is filed in

Where a required value is missing, the write is answered 422 with VALIDATION_FAILED, and field_errors carries a code under the field's name:

HTTP/1.1 422 Unprocessable Entity
{
  "error": {
    "type": "invalid_request_error",
    "code": "VALIDATION_FAILED",
    "message": "The customer failed validation.",
    "field_errors": {
      "vat_zone_ref": ["VAT_ZONE_REQUIRED"],
      "customer_group_ref": ["CUSTOMER_GROUP_REQUIRED"]
    },
    "request_id": "req_…"
  }
}

To find valid values, read a customer or a product the company already has (GET /customers, GET /products): each states the references the accounting system holds for it.

Two rules keep a sync that does not model these fields from moving a record:

  • POST /customers under an external_id that is taken keeps vat_zone_ref, payment_terms_ref, layout_ref and customer_group_ref as they are when the body leaves them out.
  • POST /products under an external_id that is taken keeps account_ref when the body leaves it out and account_number is unchanged.

A product whose account_ref names no product group of the company is refused by the platform, with the reason under refusal.

What a platform can refuse

CodeStatusWhat happened
PLATFORM_REFUSED422The accounting system refused the write of a customer or a product. Nothing was written. refusal says why.
ISSUE_REFUSED422The accounting system refused to book an invoice. Nothing was booked.
CREDIT_REFUSED422The accounting system refused to book a credit note. Nothing was booked.
PLATFORM_NOT_CONFIGURED409The company's connection is missing a setting the write needs. Nothing about your request is wrong: an admin completes the setup in the workspace.
PLATFORM_UNAVAILABLE409The company has no accounting system to write to.
PLATFORM_API_ERROR502The accounting system could not be reached, or did not answer. It may or may not hold the change.

A refusal is not an outage. Do not retry a 422 with the same body: read refusal.reason and refusal.platform_reason, and correct the record. Retry a 502 with backoff. A create sent under an external_id is safe to send again unchanged within the hour: see external_id and idempotency.

E-invoices

A customer whose send_method is einvoice states how it is routed, in invoice_mail_out_option_key, and the identifier that channel reads. The channels a platform can route are in the table above. A channel the company's platform cannot route is refused when the customer is written, as VALIDATION_FAILED with MAILOUT_OPTION_UNAVAILABLE under invoice_mail_out_option_key.

The delivery channel is checked again when an invoice is issued, before anything is booked: a customer that cannot be sent to is refused with INVALID_SEND_METHOD, and one that lacks its e-invoice details with MISSING_EINVOICE_DETAILS. Both are 422, and in both the fix is on the customer.

Differences that never reach a refusal

  • A credit note on e-conomic is a booked invoice with negative amounts. Crediting works on both platforms and POST /credit-notes is identical. What differs is the document that lands in the books.
  • e-conomic sends a document as part of booking it, and keeps no readable record of a send. A document booked there therefore states send_error: null. On Dinero the send is a step of its own after the booking, and a failed one is reported in send_error.
  • A booked document cannot be sent again through the API, on either platform. Following up on a failed delivery is done in the workspace.

Authentication

Key format, scope, the company a key is bound to, rotation.

external_id and idempotency

Naming every record by your own key, and why a retried create makes nothing twice.

På denne side

What stays the sameIds are the platform's handlesFields that name a platform's own choiceWhat a platform can refuseE-invoicesDifferences that never reach a refusal

Denne side

Vis som MarkdownÅbn i Claude