Blog— Anton Ignashev

Symfonia WebAPI: a developer's guide — sessions, licences, the buffer and the errors you'll hit on day one

Symfonia WebAPI: a developer's guide — sessions, licences, the buffer and the errors you'll hit on day one

Why Symfonia Gets Its Own Guide

I've written developer guides for enova365 WebAPI, the Comarch Optima API and Sfera in Subiekt nexo, plus a comparison of all three. Symfonia was missing, and it's the one people ask about least until a project lands on their desk. Then they find out the public material is thin, the help-centre articles are behind a login, and the WebAPI behaves less like a web service than like a remote-controlled copy of Handel.

That last point explains almost everything below. Every technical claim here comes from Symfonia's own 2026 WebAPI documentation on pomoc.symfonia.pl. I cross-checked the endpoint paths against an open-source client, symf-webapi-rs, generated from the WebAPI interfaces for version 26.20. It's a third-party project, not Symfonia's, and routes do move between versions, so treat the Swagger UI on your own installation as the final word.

What the WebAPI Actually Is

Symfonia's documentation says it directly: WebAPI is a Windows service that runs Handel in the background and exposes it over HTTP(S) in the REST style, with JSON messages. It doesn't talk to the database on its own. It starts Handel's COM objects (or, on the FK side, the FK integration object) and drives them.

Six consequences follow, and the vendor states every one of them:

Constraint What the documentation says What it means for you
Scope of one instance one company, one Handel user a second company means a second service, in its own directory, with its own licence
Handel and FK cannot run in the same instance integrating both programs means two services
Concurrent sessions 10 by default, more on request unclosed sessions count until they expire
Licence check read only at service start after any licence change, restart the service
Licence model annual subscription, priced by integration scope Main is required before any module
Parallelism extra licences run more Handel COM instances throughput is bought, not tuned

Read the module list before you quote a project. On the Handel side (WAH): Main, Kontrahenci, Towary, Stany magazynowe, Zamówienia obce, Zamówienia własne, Dokumenty sprzedaży, Dokumenty zakupu, Dokumenty magazynowe, Płatności, Rezerwacje, custom modules, and Komplet. On the FK side (WAF): Main, Kontrahenci, Pracownicy, Słowniki, Rozrachunki, Wymiary, Dokumenty, Plan kont.

What about price? Symfonia doesn't publish a WebAPI figure in the documentation. Licences are annual and priced by scope. The only numbers I could find are integrator bundles: a shop connector plus a one-year WebAPI licence for Symfonia ERP Handel at 2 400 zł net a year from one vendor and 3 228 zł a year from another. That's a ceiling for the simplest case, and it includes someone else's software. Ask your Symfonia partner for the module list priced against your scope, not for "the API".

Sessions: Two Tokens, Three Kinds of 401

Authentication runs in two steps. In the configurator, each Symfonia user that WebAPI may run as gets an application token. You open a session with a GET to the session endpoint, a deviceName query parameter and this header:

GET /api/Sessions/OpenNewSession?deviceName=erp-sync HTTP/1.1
Host: symfonia-srv:9000
Authorization: Application 3f2a...-guid

The response body is the session token. Every later call carries it:

GET /api/Contractors/Page?page=1&size=100&orderBy=Asc HTTP/1.1
Authorization: Session 9c41...-guid

One honest caveat about the path. The vendor FAQ writes the call as /api/OpenNewSession, while the generated client and its controller layout use /api/Sessions/OpenNewSession (with /api/Sessions/CloseSession and /api/Sessions/SessionInformation next to it). Open Swagger on your instance and check before you hard-code either. SwaggerUI is a checkbox in the configurator, and since the 2026 release it covers every endpoint.

Session length is set per client in the configurator, and each authorised call renews it. The FAQ warns about both ends: too short and you reopen sessions constantly, too long and dead sessions sit on your 10 slots.

Here's the first real trap. According to the HTTP codes page, 401 covers an invalid application token, an invalid session token, an expired session and an exceeded session limit. Your client can't tell from the status alone whether to reopen a session or stop. The pattern I use: on 401, reopen once and retry; if the reopen itself returns 401, stop and alert, because you've either lost the token or run out of sessions.

And close sessions explicitly on shutdown. A sync job that crashes in a loop and opens a new session each time can lock everyone else out in ten iterations.

The Codes You'll Actually See

Code Meaning per Symfonia What to do
200 / 201 / 204 processed; body may carry the created object read the ID and number from the body
400 validation error or an internal Handel method failed; body has a message and ModelState log ModelState, don't retry blindly
401 bad token, expired session, or session limit exceeded reopen once, then alert
404 the ID doesn't exist in the database treat as data, not as an outage
409 the object is being edited by another Handel user back off and retry later
500 unhandled exception in WebAPI; body has the StackTrace collect logs and report to the vendor

The 409 deserves a note. It means someone has the contractor or document open in Handel right now. In a busy office that's not rare, so your sync has to queue the change and try again instead of failing the run.

Writing Documents: the Buffer Is the Default

Sales documents go through SalesIssue. POST /api/SalesIssue/New takes the document in the body and an issue parameter. The documentation is explicit: if you don't pass issue, the document goes to the buffer, not into the books. There's a separate PUT /api/SalesIssue/InBuffer to issue a buffered document by ID or number, and corrections go through /api/SalesIssue/NewCorrection with the same rule.

I'd keep that default. A document written by an integration should land where a person can look at it, the same principle I argued for with enova365 service accounts. The FK side works the same way: the WAF Dokumenty module adds simple, purchase, sales or custom documents to the FK buffer, and /api/FKDocuments/Buffer reads what's waiting there.

The most common failure when writing is an error like [ImportZO]: [Metoda zwróciła błąd [0].], also seen with ImportMG, ImportSP, ImportZK and ImportZW. The troubleshooting page lists the causes, and none of them is your JSON. The WebAPI user lacks permissions, has no access to some departments, warehouses or cash registers, or has no default department, warehouse or cash register set. The fix is to log into Handel once as that user, set the defaults, and try issuing the same document by hand. If Handel shows a dialog during login (an AmBasic report, an OnTimer error, an FK integration message), WebAPI won't start at all.

Reading Changes: IncrementalSync and the Unticked Box

For syncing, there's paging (/api/Contractors/Page?page=&size=&orderBy=) and there's GET /api/Contractors/IncrementalSync?dateFrom=, with equivalents for other objects. Incremental sync is what you want for a shop or a CRM: pull only what changed since the last run.

The catch is on the configurator's Synchronizacja tab. Change logging is enabled per record type, and by default only stock levels are on. Products, contractors, foreign orders, sales documents and price lists have to be switched on. If nobody does it, IncrementalSync returns an empty list and your integration looks healthy while missing every new customer. Check that tab on day one and write it into the handover document.

Two more things from the troubleshooting page I'd keep handy. After a new fiscal year is created in FK, WebAPI can fail with "Nie odnaleziono roku dla daty" until the service is restarted. And GET /api/Ping returns the loaded modules and running Handel instances, which is the fastest way to see whether a 404 on a whole controller is really a missing module licence. /api/Alive just returns the server date.

KSeF in the 2026 Release

Version 26.0.1.0 added an IKsefController: POST /api/Ksef/AddSendToKsefEvent queues a document for sending through Symfonia Cloud Connector, and ChangeKsefStatusAsync changes the KSeF status in the Handel database. The same release added attachment endpoints for sales and purchase documents. If you're building a KSeF flow for an accounting office on top of Symfonia, check the WebAPI version first. Anything before 2026 doesn't have these routes.

What I'd Build First

A read-only sync with sessions handled properly: open, renew, close on shutdown, one reopen on 401. Paging for the initial load, IncrementalSync with the right boxes ticked for everything after. Then writes into the buffer only, with a person issuing. Throughput comes last, and on Symfonia it's a licence question (more COM instances), not a code question.

The FK side is where the interesting automation is: settlements, the buffer and dimensions are exactly what an agent needs to propose postings that an accountant approves, the same split I described in the Symfonia MT940 post.

Scoping a Symfonia integration and not sure which modules you actually need? Get in touch. An hour with your configurator and your document flow settles the licence list faster than any quote.

Let’s talk about your project

Free 30-minute consultation. We’ll figure out if and how I can help.

Book a Free 30-Minute Call

Select a date

November 2026
Mon
Tue
Wed
Thu
Fri
Sat
Sun
← Back to Blog

Related Posts

What Subiekt nexo and Subiekt GT cost in 2026: licence prices, the Abonament, and the 30 days that raise the renewal by half
Blog

What Subiekt nexo and Subiekt GT cost in 2026: licence prices, the Abonament, and the 30 days that raise the renewal by half

Subiekt nexo for 3 workstations is 1 275 zł net, Subiekt GT 1 045 zł, nexo PRO 2 575 zł. Those are perpetual licences, and then there's the yearly Abonament: 349 zł for nexo if you renew within 30 days of expiry, 539 zł if later. Plus Sfera (the API), the accounting-office client licences, and a comparison with Optima and enova365.

Read more→
What Comarch ERP Optima costs in 2026: the subscription list, Basic vs Pro, and three costs it leaves out
Blog

What Comarch ERP Optima costs in 2026: the subscription list, Basic vs Pro, and three costs it leaves out

Optima's price list is public: Podstawowy 59 zł a month, Logistyka Basic 75 zł, Księga Handlowa 175 zł. The catch is the word Pro: it's a top-up on Basic, not a separate tier, so full accounting in Finanse costs 250 zł, not 200. Plus the Podstawowy limits, how HR counts employees for accounting offices, and two worked examples.

Read more→
December pay paid in January 2027: a 2026 or a 2027 cost? The 8 January payday and ZUS by 15 or 22 February
Blog

December pay paid in January 2027: a 2026 or a 2027 cost? The 8 January payday and ZUS by 15 or 22 February

December payroll paid in January is a 2026 cost, but only if the pay leaves on the date in the client's pay rules and the ZUS contributions reach ZUS on time. 10 January 2027 is a Sunday, so the statutory deadline ends on Friday 8 January. The same pay lands in the employee's 2027 PIT-11. Here's what an office checks in December and in February.

Read more→