Websockets
Real-time updates

Minimal events – says what happened, but does not include all data.
When you get an event, you may need to call the API to retrieve the updated entity and see what has changed.
Can go back in time two weeks if you had a malfunction in your system and missed updates. This is done by submitting an offset for the topic you are listening to.

Eliminate the need for polling

Our hope is that in the long run you will be able to avoid polling our API completely and instead only call us in connection with you receiving events about updates.
Have not added everything in this mode, get in touch if you miss events.

A single connection for all customers

You connect to the web socket and then add all your integration keys in one and the same connection. It is important for our scalability that you do not have one connection per customer.

Uses Apache Kafka under the hood.

A topic for each domain, e.g. Invoices and customers
At-least-once-delivery; may come duplicates
All events have a unique ID called “offset” within their topic. Order is guaranteed.

Documentation
Overview

The API consists of a single duplex websocket stream containing different topics, e.g. "invoices" and "supplier-invoices". Each topic has an ordered list of events. Each event has a unique offset within the topic. You can listen to multiple topics and multiple tenants to get notified about changes.

Example event

{
   "topic":"invoices", // The topic of the event
   "offset": "xDy7J", // The offset of this message in the topic
   "type":"invoicepayment-bookkeep-v1", // A payment of an invoice was bookkept
   "tenantId":29302, // Identifies the tenant
   "entityId":"3817", // Identifies the affected entity (payment in this event)
   "timestamp":"2017-12-28T14:59:16.500+01:00" // When the event was created
}

Events are json serialized and contain the tenantId affected and the topic and type of the event. Event types are versioned to allow for breaking changes to be migrated in a controlled manner. Non-breaking changes (adding new fields) will be done without increasing the version.

Upon reconnecting after downtime from stream (due to disconnect etc) you can supply offsets for each topic when adding them, to get events replayed up to 14 days back. Each event received has an offset. If an offset provided is older than 14 days, the offset will be set to the earliest possible offset instead.

Events are minimal in payload and clients are encouraged to lookup the entity to find more info.

Down below you will find examples of all the possible commands to send, and also all topics you can subscribe to.

Commands

Adds new tenants to your stream.

{
   "command": "add-tenants-v1",
   "includeChildTenants": true/false,
   "clientSecret": "6565df",
   "accessTokens": [
      "Bearer ouhohohhho897"
   ]
}

The response contains only the tenants from the request, not all the currently subscribed tenants.

{
   "response": "add-tenants-v1",
   "result": "ok",
   "tenantIds": {
      "Bearer ouhohohhho897":34231
   }
}

OR 

{
   "response": "add-tenants-v1",
   "result": "error",
   "invalidTokens": [
      "lijldifdf856587"
   ]
}

TopicEventAdditional payload
articlesarticle-created-v1
articlesarticle-updated-v1
articlesarticle-deleted-v1
bureau-activitiesactivity-created-v1
bureau-activitiesactivity-updated-v1
bureau-assignmentsassignment-created-v1
bureau-assignmentsassignment-updated-v1
bureau-assignmentsassignment-deleted-v1
cost-centers cost-center-created-v1
cost-centers cost-center-updated-v1
cost-centers cost-center-deleted-v1
currenciescurrency-created-v1
currenciescurrency-updated-v1
currenciescurrency-deleted-v1
customerscustomer-created-v1
customerscustomer-updated-v2
customerscustomer-deleted-v1
financial-yearsfinancial-year-created-v1
financial-yearsfinancial-year-updated-v1
financial-yearsfinancial-year-deleted-v1
financial-yearsaccount-created-v1year, id
financial-yearsaccount-updated-v1year, id
financial-yearsaccount-deleted-v1year, id
invoicesinvoice-created-v1
invoicesinvoice-updated-v1
invoicesinvoice-cancelled-v1
invoicesinvoice-bookkeep-v1
invoicesinvoicepayment-bookkeep-v1 invoiceId, fullyPaid
invoicesinvoicepayment-deleted-v1 invoiceId
invoicesreminder-sent-v1
messagessend-push-notification-queued-v1
offersoffer-created-v1
offersoffer-updated-v1
offersoffer-canceled-v1
ordersorder-created-v1
ordersorder-updated-v1
ordersorder-cancelled-v1
projectsproject-created-v1
projectsproject-updated-v1
projectsproject-deleted-v1
supplierssupplier-created-v1
supplierssupplier-updated-v1
supplierssupplier-deleted-v1
supplier-invoicessupplier-invoice-created-v1
supplier-invoicessupplier-invoice-updated-v1
supplier-invoicessupplier-invoice-cancelled-v1
supplier-invoicessupplier-invoice-bookkeep-v1
termsofdeliveriestermofdelivery-created-v1
termsofdeliveriestermofdelivery-updated-v1
termsofdeliveriestermofdelivery-deleted-v1
termsofpaymentstermsofpayments-created-v1
termsofpaymentstermsofpayments-updated-v1
termsofpaymentstermsofpayments-deleted-v1
vouchersvouchers-created-v1year, series, id
vouchersvouchers-updated-v1year, series, id
vouchersvouchers-deleted-v1year, series, id
warehouse-stockbalanceswarehouse-stockbalance-changed-v1
waysofdeliverieswaysofdeliveries-created-v1
waysofdeliverieswaysofdeliveries-updated-v1
waysofdeliverieswaysofdeliveries-deleted-v1
Documentation

See our comprehensive documentation regarding the Fortnox API.

Subscribe to our blog

By contacting Fortnox, your personal information will be processed in accordance with Fortnox's Privacy Notice

Join us

Approximately half a million customers are waiting for your integration at our Integrations page.