Skip to content
This is a new version of the Kivra Developer Docs. Report issues or share feedback at avsandare.support@kivra.se. The previous version can be found here.

Integration guide

The Partner API is driven by events. Kivra tells you when a company activates an integration with you, when that company receives content, and when it deactivates the integration, and you respond to each with a few API calls. This guide follows that lifecycle in order. Read Webhooks first for how to verify and acknowledge the deliveries themselves.

1. A company activates an integration with you

Section titled “1. A company activates an integration with you”

A user with the right to act for a company opens the company’s settings in Kivra, picks you from the list of available partners, and activates the integration. Kivra then sends you an integration.created event:

integration.created
{
"data": {
"company_key": "1560774336a57b73569d594df5abad7fd2575c1070",
"vat_number": "SE556000475501"
},
"data_version": 1,
"event_created_at": 1788177600,
"event_type": "integration.created",
"id": "event_9c1d2e3f4a5b4c6d8e9f0a1b2c3d4e5f"
}

The vat_number lets you match the company to a customer in your system, and company_key is what every request about the company is made under. Later events about the company carry the key too.

When a company that has an integration with you receives content, Kivra sends a content.created event:

content.created
{
"data": {
"company_key": "1560774336a57b73569d594df5abad7fd2575c1070",
"content_key": "1756718042a9813e08f783496382b0bff743ec34ae",
"vat_number": "SE556000475501"
},
"data_version": 1,
"event_created_at": 1788254042,
"event_type": "content.created",
"id": "event_3f62fc97907a4212af028c30f1ea1927"
}

The event carries only keys. Use them to fetch the content with GET /v3/partner/company/{companyKey}/content/{contentKey}, which returns its metadata:

Terminal window
curl -X GET \
"https://sender.sandbox-api.kivra.com/v3/partner/company/$COMPANY_KEY/content/$CONTENT_KEY" \
-H "Authorization: Bearer $KIVRA_ACCESS_TOKEN"
{
"created_at": "2026-09-01T00:00:00Z",
"interpreted_fields": [],
"key": "1756718042a9813e08f783496382b0bff743ec34ae",
"labels": {
"governmental": false,
"handled": false,
"interpreted": false,
"reminder": false,
"trashed": false,
"viewed": false
},
"origin": "kivra",
"parts": [
{
"content_type": "application/pdf",
"name": "faktura-12345.pdf",
"sha256": "f6c21611a855ce116943c15c49e963957775fb67595b54435a956610eefd231f",
"size": 48213,
"url": "https://sender.sandbox-api.kivra.com/v3/partner/company/1560774336a57b73569d594df5abad7fd2575c1070/content/1756718042a9813e08f783496382b0bff743ec34ae?part=1"
}
],
"payment_options": [
{
"account": "5050-1055",
"amount": 150000,
"currency": "SEK",
"description": "Total",
"due_at": "2026-09-30T00:00:00Z",
"interpreted": false,
"reference": "123456789",
"reference_type": "OCR",
"type": "bankgiro",
"vat_amount": null
}
],
"received_at": "2026-09-01T09:14:02Z",
"receiver_name": "Cornelias Café AB",
"receiver_vat_number": "SE556000475501",
"references": null,
"sender_contact_info": null,
"sender_icon_url": "https://sandbox-static.kivra.com/img/tenant/1341573157b3a1c55f220f4007b2e44789d2d04015/icon.png",
"sender_name": "Lenas Konditori AB",
"sender_vat_numbers": [
"SE556123456701"
],
"subject": "Faktura 12345",
"transaction_at": "2026-09-01T00:00:00Z",
"type": "invoice"
}

The API reference describes every field in the response.

A content has one or more parts, listed in parts with a content_type, size, sha256, and a ready-made url. The simplest way to download a file is to request that URL with your bearer token. It is the same endpoint with part=N, where N is the 1-based position in parts:

Terminal window
curl -X GET \
"https://sender.sandbox-api.kivra.com/v3/partner/company/$COMPANY_KEY/content/$CONTENT_KEY?part=1" \
-H "Authorization: Bearer $KIVRA_ACCESS_TOKEN" \
-o faktura-12345.pdf

The response body is the file, and Content-Type is the part’s content_type. The part’s sha256 and size let you verify the download.

Not every document is a PDF. Kivra also lets senders deliver a letter as plain text or HTML, which arrives as a part with content_type text/plain or text/html and is downloaded the same way.

The handled and viewed labels are the same ones the company’s users see and change in Kivra, and PATCH /v3/partner/company/{companyKey}/content/{contentKey} lets your system change them too. Use that to keep Kivra and your system in step: when your system has processed the content, for example booked or paid an invoice, mark it as handled, and the company’s users see it as handled, so nobody pays it twice:

mark-handled.json
{
"labels": {
"handled": true
}
}
Terminal window
curl -X PATCH \
"https://sender.sandbox-api.kivra.com/v3/partner/company/$COMPANY_KEY/content/$CONTENT_KEY" \
-H "Authorization: Bearer $KIVRA_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @mark-handled.json

The same request can set viewed, which the company’s users see as read. Your system can also offer these as actions to its own users, such as a “Mark as read in Kivra” or “Mark as handled in Kivra” button, so they do not need to open Kivra to tidy up the inbox. Both labels can be set back to false.

A company can deactivate the integration at any time from its settings in Kivra. When it does, Kivra sends an integration.deleted event:

integration.deleted
{
"data": {
"company_key": "1560774336a57b73569d594df5abad7fd2575c1070",
"vat_number": "SE556000475501"
},
"data_version": 1,
"event_created_at": 1790841600,
"event_type": "integration.deleted",
"id": "event_7a8b9c0d1e2f4a3b9c8d7e6f5a4b3c2d"
}

You can no longer read anything under that company key, so stop making requests for it. The data you have already stored is yours to handle according to your agreement with the company.

The flow above is all a typical integration needs. For anything beyond it, the API reference describes a few more operations, such as listing the companies that have an integration with you.