Sari la conținut
Pagini APIExports and handover packs

Documentație API

Această documentație este disponibilă doar în limba engleză.

Exports and handover packs

Three routes, all of them answering with a ZIP file rather than JSON. Two are data portability: everything Syllevo holds, in a form another system can read. The third is the month-end handover pack, the one click that replaces an accountant's monthly gather-and-rename.

Routes

Method Path Needs Answers
GET /v1/exports/organization Admin application/zip
GET /v1/exports/profiles/{id} View application/zip
GET /v1/profiles/{profileId}/handover-pack View application/zip

How these responses behave

All three are built as they are sent, which changes three things a client normally relies on.

  • No Content-Length. The size is unknowable before the last byte is compressed, and inventing one would be a lie your HTTP library would catch. The response is chunked, and a browser shows an indeterminate download.
  • The file name is in Content-Disposition. Read it from there rather than making one up.
  • A failure can only happen before the first byte. Everything that can refuse, permissions included, runs while the response is still empty. Once bytes are flowing the status line is already 200, so treat a truncated archive as a failed download and ask again.

There is no job to create and no job to poll. One request, one file, however large. A firm with three hundred clients gets one ZIP.

Exports are never gated

An export answers 200 with a full archive for every organization in every subscription state: on any package, during grace, after a refund, and at cancellation. Portability is not something a subscription buys.

It lasts as long as the organization does. After a subscription ends, that is 90 days: then the organization is deleted, with its documents. GET /v1/billing/closure has the date. See Billing.

What a package changes is one file inside the ZIP. invoices-saga.csv, the ledger handoff, comes with the 10-client package and up. When an organization is not entitled to it, the file is left out, manifest.json says so in plain language, and the rest of the archive is unaffected. The export still runs to completion. It is never a status code and never a refusal.

The generic invoices.csv always ships. Every invoice in the Saga file is also in invoices.json and invoices.csv, so nothing is withheld, only the convenience layout.

GET /v1/exports/organization

Everything the organization holds. Admin and above.

File name: syllevo-export-organization-{organizationId}-{yyyy-MM-dd}.zip.

Inside:

Entry What it holds
README.txt What this archive is, in plain language
manifest.json What the export covers, counts, and any original that could not be fetched
profiles.json The client companies covered
profiles/{id}/ One folder per client
invoices.csv Every purchase invoice, one row each
sales-invoices.csv Every imported sales invoice, one row each
invoices-saga.csv The same purchases in an accounting package's layout. Entitlement only
originals/ The original files, named by content hash

Each profiles/{id}/ folder holds suppliers.json, documents.json, invoices.json, sales-invoices.json, reminders.json, and contacts.json.

Purchases and sales are in separate files, so a customer never lands in a supplier column. sales-invoices.json and sales-invoices.csv carry the customer's name, tax id, and country where invoices.json carries the supplier. A sale's original files are in originals/ and listed in documents.json like any other. manifest.json counts sales in counts.salesInvoices and gives the CSV's version in salesInvoicesCsvFormatVersion. manifestFormatVersion is 3.

The Saga file and the handover pack stay purchases only. They are the purchase ledger handoff.

Credit notes are negative in every file, the Saga file included. invoices.json and sales-invoices.json carry documentTypeCode, correctedInvoiceNumber, and correctedInvoiceIssueDate on each invoice. invoices.csv and sales-invoices.csv add the same three as their last columns, document_type_code, corrected_invoice_number, and corrected_invoice_issue_date, which is why invoicesCsvFormatVersion and salesInvoicesCsvFormatVersion are 2. The earlier columns did not move. The Saga file's columns did not change.

Read manifest.json first. It is written last, it carries the true counts, and it names any original the export could not fetch from storage. A missing original is never a crash and never a silent gap: the archive says what it could not get.

Originals are deduplicated by content. Two clients who received the same file share one copy in originals/, so there are often fewer files there than rows in documents.json. Follow the originalPath field on each document to find its file. An empty originalPath means the file could not be fetched, and the manifest says why.

GET /v1/exports/profiles/{id}

The same archive, narrowed to one client company. View on that client.

File name: syllevo-export-profile-{profileId}-{yyyy-MM-dd}.zip.

Same layout, same manifest rules, same Saga-file behavior. Use this one when a client leaves the firm: the export is the deliverable, and it is complete without anybody's permission but the caller's.

GET /v1/profiles/{profileId}/handover-pack

One client's month, or several months, in the shape an accountant actually files. View on the client.

Parameter Type Means
month string One month as "2026-08". Omitted means the month running now
months string, repeatable Several months: ?months=2026-07&months=2026-09
source DocumentSourceKind 0 e-Factura arrivals only, 1 everything else. Omitted means all

Sending month and months together answers 400. At most twelve months, none repeated.

File name: syllevo-handover-{profileId}-2026-08.zip for one month, and syllevo-handover-{profileId}-2026-07_2026-09.zip for several, naming the first and the last. The months in between are not spelled out in the name; manifest.json lists every month the pack actually holds.

Inside a one-month pack:

Entry What it holds
manifest.json What the pack covers, counts, and anything that could not be fetched
summary.pdf One page a person reads: the month's invoices as a table, with totals
documents/ Every document evidencing an invoice issued in the month
unmatched/ Documents that arrived in the month with no invoice to belong to
invoices-saga.csv The month in the ledger's layout. Entitlement only, same rule as exports

A pack covering several months puts each one in a folder named after it, 2026-07/documents/..., and adds a root manifest.json listing the months. A one-month pack has no month folder, on purpose: the folder exists to tell two months apart, and every pack an accountant has already filed keeps the shape it had.

Documents are renamed on the way in, which is the point of the pack. A matched document is 2026-08_Supplier_InvoiceNumber.pdf, and a second document evidencing the same invoice gets a counter, ..._F123_2.pdf. An unmatched one is named by arrival date plus the name it had when it arrived, because that is all that is known about it. Names are sanitized so the archive extracts cleanly on Windows as well as anywhere else, and the extension comes from the actual content type rather than from whatever the original name claimed.

unmatched/ is in the pack rather than left out. Nothing missing at month-end includes the files nobody has read yet.

An empty month answers 200, with a pack that says nothing was received. It is not a 404. An accountant asking for a quiet month should get the evidence that it was quiet.

GET /v1/profiles/22222222-2222-4222-8222-222222222222/handover-pack?month=2026-08 HTTP/1.1
Host: api.syllevo.com
X-Api-Key: syl_live_examplekeynotreal000000000000
HTTP/1.1 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename=syllevo-handover-22222222-2222-4222-8222-222222222222-2026-08.zip

Rate limits

None of these three carry a named rate limit policy. They are governed by the global limiter's organization partition, 1200 requests a minute for the whole organization. See Conventions.

That is a generous ceiling for a large file, so the practical limit is bandwidth rather than the limiter. Do not run exports in a loop across a portfolio in parallel; run them in sequence.