How to integrate with sevdesk: Two bookkeeping versions in one tenant
The sevdesk token is simple, the pagination is ordinary and there are no webhooks to configure. What costs you a week is sevdesk-Update 2.0, the bookkeeping change sevdesk shipped in 2024: the same tenant returns one shape for older records and another for newer ones, and which tax rule you may write depends on a setting only that client knows.


The token never expires, and it dies with the user
Getting in is the easy part. Every sevdesk administrator has one token, a hexadecimal string of 32 characters, and it goes into the Authorization header on every call. There is no OAuth dance, no refresh cycle and no expiry to schedule around.
The catch is what the token is attached to. Sevdesk puts it plainly: “The api tokens have an infinite lifetime and, in other words, exist as long as the sevdesk user exists.” The next line is a warning in capitals, that the user should never be deleted. Remove that person from the account and the integration stops, with 401 and no notice.
GET /api/v1/Invoice?limit=50&offset=0&countAll=true HTTP/1.1Host: my.sevdesk.deAuthorization: b7794de0085f5cd00560f160f290af38Accept: application/jsonUser-Agent: Acme Billing by Acme GmbH
The token is the header value on its own, with no scheme in front of it. Sevdesk also asks for a meaningful User-Agent, in its words so it “can offer better support in case of queries from customers”.
Token format, header and lifetime from sevdesk’s authentication section, checked 11 August 2026. The token in the sample is the one sevdesk prints in its own documentation, so it is an illustration rather than a working credential.
Sevdesk lets the token be replaced. A generate new control sits beside it in your customer’s account and is confirmed with their password. The part to plan for is what happens next: the replacement exists only in their account, sevdesk does not notify you, and the old token stops working the moment the new one is created.
So give your customers a way to hand you a new token from inside your own product, before the first one is ever replaced. Without it, every rotation becomes a support conversation with a broken integration behind it.
One more line is worth reading twice, because it decides your onboarding copy. Sevdesk warns that a token cannot be shown again after it is created: “it is advisable to save the api token as we will NOT be able to retrieve it afterwards”. Whoever collects it from the customer only gets one attempt.
One tenant can return two bookkeeping versions
This is the part the older write-ups miss, and it is the one that costs a week. In 2024 sevdesk changed its bookkeeping engine in a release it calls sevdesk-Update 2.0, and the change did not migrate the past. Records created under the old system keep returning the old shape while new ones return the new one, from the same account, on the same endpoint.
Concretely: orders, invoices, vouchers and credit notes created under system 1.0 still come back with a taxType such as default. The same objects created since the update come back with a numbered taxRule instead. Your parser meets both, and nothing in the payload says which is which.
Still returned for every record that existed before the update.
Returned for everything created since, with a numbered rule instead of a name.
Neither payload tells you which world you are in. The bookkeeping system version is its own call, and it is the one that decides which tax rules a write may use.
GET /api/v1/Tools/bookkeepingSystemVersion HTTP/1.1Host: my.sevdesk.deAuthorization: <your customer's api token>Accept: application/json
One call per connected tenant, cached for the session. It decides which tax vocabulary a write may use, and it is the only place the answer exists.
The update, the field change and the version endpoint from sevdesk’s sevdesk-Update 2.0 notes, checked 11 August 2026. Sevdesk describes the old system as available to some customers until the end of 2024, so new connections land on the new one while their history does not.
Sevdesk offers a bridge rather than a cliff. Where you still send taxType with the values default, eu or ss, those are mapped onto the new rules for a transition period. The recommendation is to move anyway, because the new set has options the old one never had.
What is gone without a bridge is taxType: custom together with a custom taxSet. Sevdesk removed it for a reason it states directly, a high likelihood of non compliant accounting, and the same pass removed custom accounting types as well.
A normalised data model is the obvious answer to a system with two vocabularies, and it is what the common data model does for this and for the 30+ systems next to it.
Which tax rule you may use depends on the client
Reading tolerates both worlds. Writing does not, because the new model ties three things together: the rule, the rate that rule permits and the account behind it. Get the combination wrong and the write comes back 422 rather than being quietly accepted.
The shape of the constraint is easy to underestimate. Of the ten revenue rules for a standard taxpayer, exactly two allow the rates a German invoice usually carries: the ordinary one and intra community supplies. Five permit a single value, and that value is zero. The three One Stop Shop rules depend on the destination country.
| Tax rule | Allowed rates | Replaces |
|---|---|---|
| 1 · Umsatzsteuerpflichtige Umsätze | 0.0 · 7.0 · 19.0 | taxType: default |
| 2 · Ausfuhren | 0.0 | No predecessor |
| 3 · Innergemeinschaftliche Lieferungen | 0.0 · 7.0 · 19.0 | taxType: eu |
| 4 · Steuerfreie Umsätze §4 UStG | 0.0 | No predecessor |
| 5 · Reverse Charge §13b UStG (field 60) | 0.0 | No predecessor |
| 21 · Reverse Charge §18b UStG (field 21) | 0.0 | No predecessor |
| 17 · Nicht im Inland steuerbar | 0.0 | taxType: noteu |
| 18–20 · One Stop Shop | depends on country | No predecessor |
Rules, permitted rates and the deprecated properties from sevdesk’s tax rules table, checked 11 August 2026. The table above is the revenue half for a standard taxpayer. Sevdesk publishes three more, for expenses and for small business owners, and a small business client has exactly one revenue rule available.
{"invoiceType": "RE","taxRule": 1,"invoicePos": [{ "quantity": 1, "price": 1000.0, "taxRate": 19.0 }]}
With taxRule: 2 the same position would have to carry 0.0, and 19.0 would be rejected. The pairing is the validation, not the number on its own.
Which accounts, rates and rules fit together is not a constant. It depends on the client’s own settings, small business status among them, and sevdesk exposes a Receipt Guidance endpoint for exactly that question. Reading it once per tenant is cheaper than discovering the answer through 422 responses, and it is the only version of this list that stays correct.
Two more rules changed shape rather than value, and both bite at the end of a flow. A voucher can no longer be created as paid, only as DRAFT or UNPAID, with a separate call to book the amount afterwards. And enshrined stopped being a property you set: it has its own endpoint now, once for vouchers and once for bank transactions.
Advance and partial invoices carry their own restriction, and it is narrow. They can only be created under the ordinary revenue rule, or under the small business rule for a small business client. The One Stop Shop rules exclude them entirely, along with e-invoices and custom revenue accounts.
Pagination hides the total, and the count is a string
Reading is conventional, with two details that catch people. Sevdesk pages with limit and offset, the limit sits between 1 and 1000, and there are no cursors. The total number of records is not included unless you ask for it with countAll=true, which defaults to false.
When it does arrive, it arrives as a string. The response reads {"total": "157", "objects": [...]} with the number in quotation marks, so a strictly typed parser that expects an integer in that field will fail on it rather than convert it. Declare it as a string and convert it yourself, and the surprise disappears.
Worth noting against the maximum: sevdesk’s own guidance is to “keep limit values reasonable (between 10-100) to avoid performance issues”. The ceiling is 1000, the recommendation is a tenth of it, and the offset model slows down as you walk deeper into a large set.
One parameter repays learning early. embed pulls nested resources out in full instead of as an id and a name, and it takes several names separated by commas. An invoice that would otherwise cost you a second call per contact can arrive complete, which matters more here than on systems with generous limits, because the cost of the extra round trip is entirely yours.
Pagination parameters, the response format and the quoted guidance from sevdesk’s API requests section, checked 11 August 2026.
How that reads once it is normalised across systems, including the ones that page with cursors instead, is the unified pagination and filtering page.
Sending no version header pins you to the oldest
Sevdesk versions individual resources rather than the API as a whole, through an X-Version header on the request. Leave it out and you get default, and sevdesk defines default as the value that should “always reference the oldest version”.
That is the reverse of the habit most platforms teach. Elsewhere, sending nothing keeps you on the current shape; here it freezes you on the oldest one a resource has, quietly and for as long as you never look. Set the header deliberately, per resource, and write the value down somewhere your team will find it.
The reference adds one trap underneath: a resource can exist under default and not under 1.0, so a version number is not automatically safer than the default. And every response carries a Deprecation header, either true or a timestamp. That header is the earliest warning you get that a resource is going away, and nothing else will tell you.
Resource versioning, the definition of default and the deprecation header from sevdesk’s API requests section, checked 11 August 2026.
Nothing calls you, and nothing throttles you either
Sevdesk sends no events. Not a thin set, not a beta: the word webhook does not appear anywhere in its reference, and no object in our own coverage data carries a native event. Whatever you learn about a customer’s books, you learn by asking.
The second half is the one that changes the design. Sevdesk publishes no rate limit either. There is no documented ceiling, no quota and no 429 in its status code table. So the platform neither tells you when something happened nor tells you how often you may ask.
- Events sevdesk sends you
- None
- No webhooks, no callbacks, no subscriptions. The word does not occur in the reference.
- Rate limit sevdesk publishes
- None
- No documented ceiling and no 429 in the status code table. Its own advice is to keep limit between 10 and 100.
Both blanks point the same way. With no event to react to and no ceiling to respect, the polling interval is a product decision rather than a constraint you discover in production.
Counted across sevdesk’s complete API reference on 11 August 2026: zero occurrences of webhook or callback, zero of rate limit, quota or 429. The event coverage figure is counted from our own generated coverage data, where 8 of the 30+ connected systems carry a native event and sevdesk is not one of them.
Practically, the sync design is yours to choose and yours to defend. Poll the objects that change often at a rhythm that matches how quickly your product must know, keep the rest slow, and remember that every cycle costs a call whether or not anything moved.
What the same problem looks like when one event model is put over systems that have events and systems that do not is on the unified webhooks page.
A 500 can mean your request was malformed
Since every call is yours to make, every failure is yours to interpret, and one line in sevdesk’s status code table should change your retry logic. Sevdesk writes that a 500 normally means something went wrong on its side, “however, sometimes this error will appear if we missed to catch an error which is normally a 400 status code”.
A 500 is therefore not reliable evidence that the problem is temporary. A blind exponential backoff will retry some malformed requests forever, growing its wait each time, against a payload that was never going to be accepted. Log the request body with the failure, and stop retrying a 500 that comes back identical.
The status code table and the quotation from sevdesk’s API requests section, checked 11 August 2026.
Going live needs no approval, the listing needs ten users
After DATEV this reads like a different industry. Sevdesk asks for nothing before you build and nothing before you go live. In its own words, anyone can build an integration against its documented interface and “eine Freigabe oder Zustimmung durch sevdesk ist nicht notwendig”, no release and no consent required.
The partner programme is a separate track, and it starts once the integration is real. You publish it yourself and run it with ten users in production, which is where sevdesk expects you to find and fix the rough edges together with them.
Only then does an application form appear, and with it the one review in the whole process: sevdesk checks the integration against accounting requirements. A short onboarding follows to coordinate both sides, and the partnership launches with visibility in the sevdesk ecosystem.
All five steps and both quotations from sevdesk’s technology partner page, checked 11 August 2026, in German. Our own documentation describes the same route and is worth reading alongside it, with one nuance it leaves out: there is no approval to go live, and there is a review to become a partner.
For a test account there is one route and it costs nothing. Sevdesk recommends creating a trial rather than developing against a live account, and notes that a trial sits in the highest tariff, so every sevdesk function can be tested against it.
The trial recommendation and the tariff from the “Your First Request” section of sevdesk’s API reference, checked 11 August 2026: “A trial account will be in the highest tariff (materials management), so every sevdesk function can be tested”.
What Maesn covers, and what stays with you
The connection itself is short work here, and that is exactly why the rest deserves the attention. What we take off the list:
- The two vocabularies collapse into one. Whether a record predates the 2024 update or not, it reaches your code in the same shape as an invoice from any other system, so the version split stops being a branch in your parser.
- Pagination is normalised. The count you have to request, the string total and the offset walk are handled behind one interface that pages the same way for every system.
- The key never has to travel by email. Your customer enters it in a hosted step or in your own interface through the headless route, and the token is stored per tenant. What the connection looks like object by object is on the sevdesk API page.
What stays with you, and one of these is a decision rather than a task:
- The polling interval. We do not turn sevdesk into an event source, because it is not one. How fresh your product needs to be, and what that costs in calls, is a product decision we can inform and not replace.
- The tax rule your write carries. Receipt Guidance tells you which rule and rate combinations sevdesk will accept for a given client. It cannot tell you which of those is the right one for the document in front of you, because that is an accounting judgement about your customer’s business rather than a mapping we could make for you.
- The partner application, and the person behind the token. Reaching ten production users and filing the partner form is yours to do. Keeping the sevdesk user whose account issued the token in existence is your customer’s, and if they delete that person the connection stops. Neither is something we can do through an API, so both belong in your onboarding rather than in your integration.
Frequently asked questions
What authentication does the sevdesk interface use?
Can a sevdesk token be rotated?
Does sevdesk support webhooks?
How do I know which sevdesk bookkeeping version a client uses?
Why does creating a sevdesk invoice return 422?
Do I need approval from sevdesk before going live?

QuickBooks Online Webhooks: Events, Retries and Recovery
QuickBooks Online webhooks cover 29 entity types and expect HTTP 200 in three seconds. Why Intuit still asks you to poll change data capture.
Lennart Svensson · 25 Aug 2026
Lexware Office Pagination: The 406 and One Page Size
Lexware Office validates the page size and rejects a bad one with 406, the same code it uses for an unsupported media type. What that means for your read loop.
Lennart Svensson · 20 Aug 2026
How to Integrate with DATEV Rechnungswesen: One Connection
One connection carries reading and writing in DATEV Rechnungswesen, on a two-year token. Which objects travel in which direction is the real decision.
Lennart Svensson · 17 Aug 2026Build once on the Unified API.
Sevdesk has two bookkeeping versions, DATEV has two approval meetings and Xero meters what you read. Build against one interface and each of those becomes a row in a table rather than a project.