NAV Navbar
Logo
Shell HTTP JavaScript Node.JS Ruby Python Java Go
  • Kivra API v1
  • Terminology
  • Conventions
  • Limits
  • Interacting with the API
  • Resource Types
  • Tenants integration
  • Partners integration
  • Signatures (BETA, only available in sandbox)
  • Errors
  • Authentication
  • Partner API
  • Tenant API
  • Tenant Agreement API
  • Schemas
  • Kivra API v1

    API Endpoint

    Production environment

    Staging environment

    Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

    This document is intended for developers and others who are interested in integrating with Kivra to send digital mail. Questions can be sent to dev@kivra.com. If anything is missing or seems incorrect, please check the GitHub issues for existing known issues or create a new issue.

    Introduction

    The Kivra API is organized around REST. Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors.

    Integration in its simplest form consists of two steps:

    1. The first step is to synchronize the Recipient-databases either as a whole or one by one and see which Recipients the tenant can send contents to
    2. The second step is to send the contents itself.

    There are also optional steps that explain additional services Kivra provides. Currently these additional integrations exist:

    Inactive Content

    For tenants wishing to send content to Recipients who are at the time not existing in Kivra’s database. Kivra will then store the content for the agreed period of time and deliver it once/if the target Recipient registers with Kivra within this period of time.

    The service

    Kivra is a secure digital mailbox tied to your social security number or VAT-number to which you receive documents from companies, organizations and government agencies that are connected to Kivra. With Kivra you can receive, manage and archive your content wherever you are and on every platform as long as you have an internet connection.

    Over one billion window envelopes are sent every year in Sweden alone, so by choosing to use Kivra you contribute to a reduced carbon footprint!

    Kivra acts as a digital postman between Sender and Recipients which is also reflected in the allocation of responsibilities. Concretely, this means that the Sender is responsible for the design and content whereas Recipients are responsible for reading and processing the received content.

    Changelog

    We will list any changes to the current version of the API here.

    Date Details of changes 2 2
    2016-10-14 Release of Kivra API Version 1
    2018-04-20 Clarify Environments and API Endpoints
    2018-04-27 Document optional Content-fields and response-headers
    2018-08-20 Added description of partner endpoint (BETA).
    2018-08-20 Correction in Company scheme
    2019-05-10 Removed deprecated token bearer. Bearer should be used instead

    Terminology

    User

    An end user who is a user of Kivra and receives Content from tenants. A user is a physical person. A user can become dormant or deactivate themselves and be put under a grace period. Both these states is to aid the Tenant in making sure that only active Users are available for receiving Content. See below for more information on Dormant and Grace period.

    Company

    A Company is a judicial person that can receive content from tenants. Users that are signatories to the company have access to the company’s mailbox and archive. Other Users that are not signatories may also be given access to a company’s mailbox and archive. A Company can become dormant or deactivated by users that are signatories to the company. Both these states is to aid the Tenant in making sure that only active Companies are available for receiving Content. See below for more information on Dormant and Grace period.

    Non-user

    A non-user is an individual who is not a customer of Kivra but could be addressed by tenants in specific flows like the retain functionality or signatures.

    Recipient

    A Company, a User or a non-user in the context of being a receiver. Throughout this document Recipient is used to interchangeably mean a User or Company being a receiver.

    Tenant / Integrator

    Tenant is a sender that is integrated with Kivra. They need not be integrated directly, but can go through an integrator. The integrator acts as intermediary for the tenant at integration and can handle multiple tenants.

    Partner

    Partner is a third-party company (typically an ERP company) that may be granted access to access and process a company's mailbox, on behalf of the company.

    Content

    The information sent by Tenants to Recipients, i.e. Documents, Invoices, etc.

    Dormant Recipient

    Recipient who can’t be reached by email and sms-notifications are put in a "dormant"-state. During this dormant state the Recipient won’t show up in any of user or company files but the Tenant can still send Content which the Recipient will receive. When a Recipient log-in again they are awaken from dormant state and will start appearing in user files again.

    Grace period

    Kivra employs a 45 day grace period when a Recipient deactivates. During this grace period the Recipient won’t show up in any of user or company files and the Tenant can still send Content which the Recipient will receive.

    User object

    is a data object that contains all the available information about a user

    Company object

    is a data object that contains all the available information about a company

    Tenant object

    is a data object that contains all the available information about a sender.

    Content object

    is a data object that contains information about the document and the document itself

    Tenant key

    Is a unique key that identifies a Tenant. The tenant key is not related to the VAT identifier and as such can be used to address a specific Tenant when a Sender might wish to setup multiple Tenants for one VAT identifier.

    Metadata

    is data about data or information about data. Originally, the concept of meta-information, ie information about information. Normally metadata or metadata to describe the content and / or structure for a given data collection from any perspective. Kivra uses metadata to determine whom a consignment is to and other information that may be relevant for a shipment. as such payment information.

    Json

    Json or JavaScript Object Notation is a structured approach to data management. Similar to XML but much simpler and easier to read. JSON is the default serialization format within the Kivra system. JSON have a limited set of types and close attention needs to be paid to the correct JSON-type for metadata when sending Content to Kivra.

    Conventions

    Date & Time

    KIVRA encodes and decodes all dates and times as ISO 8601 values. The format looks like YYYY-MM-DDThh:mm:ss.sTZD, example 1970-01-01T23:25:10.0330000+01:00 where:

    UTC

    If the time is in UTC, add a Z directly after the time without a space. Z is the zone designator for the zero UTC offset. 09:30 UTC is therefore represented as 09:30Z or 0930Z. 14:45:15 UTC would be 14:45:15Z or 144515Z. UTC time is also known as 'Zulu' time, since 'Zulu' is the NATO phonetic alphabet word for Z.

    The offset from UTC is given in the format ±[hh]:[mm], ±[hh][mm], or ±[hh]. So if the time being described is one hour ahead of UTC (such as the time in Stockholm during the winter), the zone designator would be +01:00, +0100, or simply +01. This is appended to the time in the same way that Z was above. The offset from UTC changes with daylight saving time, e.g. a time offset in Chicago, would be -06:00 for the winter (Central Standard Time) and -05:00 for the summer (Central Daylight Time).

    Media types

    The Iana Media type, e.g. "application/pdf"

    UTF-8 encoding

    All data sent to Kivra needs to be UTF-8 encoded.

    Currency

    All places where currency is specified ISO4217 should be used.

    Country code

    Where applicable KIVRA uses a country code to determine certain formats. The country code should always be supplied using the ISO 3166-1 alpha-2 two-letter code.

    Email address

    Email addresses needs to be specified using E.123

    Phone numbers (mobile, land line)

    All phone numbers needs to be specified using E.123

    Identifying users

    Kivra uses the social security number/personal-number as key when accepting content. The format must adhere to the format YYYYMMDDnnnn that is including century-digits, i.e. 191212121212.

    VAT identifier

    In many countries, companies (or even individuals) are registered with authorities responsible for collecting taxes derived from the business transactions performed by the companies. That registration commonly yields a registration number, which uniquely identifies that company within the domain of the authority. Some legislation has a concept of VAT grouping, in which case the structure of the VAT identifier may reflect the grouping by e.g. suffixing the number.

    The full identifier starts with an ISO 3166-1 alpha-2 country code (except for Greece which uses the non-standard country code EL) and then has between 2 and 12 characters. The identifiers are composed of numeric digits in most countries, but in some countries they may contain letters. For instance, Kivra’s VAT Id would be: SE556840226601.

    Limits

    Kivra handles millions of documents. We put limits to protect the system from receiving more data than it can handle, and to ensure an equitable distribution of system resources. There’s also various practical reasons for this, such as reducing Head-of-line blocking and providing a optimal experience for the enduser.

    Our policies are as follows and are subject to change.

    Content File-size

    1 MB per Content per Recipient. This is the total JSON-object. For example, if you send two PDF’s embedded in a JSON-Content to a User the total for the JSON have to have a size less than 1 MB.

    Rate limit

    20 contents to the same recipient per minute. You can send many more contents per minute as long as they are to different receivers, but only up to 20 to the same recipient.

    Interacting with the API

    All API access is performed over HTTPS through [api, sandbox].kivra.com and data is sent and received as JSON. For trying out the API without touching live data we’ve set up a sandbox, reachable through sandbox.kivra.com. In order to ensure data privacy the following choices have been made, to name some that directly impact API workflows: Unencrypted HTTP is not supported, you will be redirected to the resource you tried to reach, with http replaced by https, if you attempt to use plain HTTP. Resources you have no right to see will either give you a describing status code or a 404. 404 statuses are returned if the case is such that you don’t even have the right to know, according to the system's current state, if an object exists.

    API Endpoints

    Kivra uses different endpoints for production and testing described below. We also provide the current IP addresses that could serve API requests, the current DNS-record will provide an up-to-date list with active endpoints. This is not meant to be a complete list of Kivra-maintained IP addresses. Please make sure to always access the Kivra API using the correct domain-name and environment instead of relying on IP addresses.

    Kivra maintains a infrastructure, which grows dynamically to accommodate increasing demand. As a result, Kivra API servers use a range of IP addresses, and the addresses often change.

    Please note that we do not recommend managing firewall restrictions by IP address, as the IPs associated with these domains are not static.

    Production environment

    The API endpoint for the production environment can be found at

    https://api.kivra.com

    IP adresses that may host the API endpoint:

    Sandbox environment

    The API for the sandbox environment can be found at

    https://sandbox.kivra.com

    IP adresses that may host the Sandbox endpoint:

    We usually deploy the latest production environment to our Sandbox, but may occasionally update it with newer builds, which may not be as reliable or well tested.

    URL Components

    When constructing resource identifiers (URIs) it is best to consider them as being built with up to four discrete units.

    Endpoint

    https://TYPE.kivra.com/VERSION

    Tenant resource

    /tenant/TENANTKEY

    Parameters

    /?QUERYSTRING

    Unit Fields

    The units have parameterized fields, which allow you to change their respective meanings, those fields are briefly described below.

    TYPE

    sandbox for development and test or api for production purposes.

    VERSION

    Current and only API version is v1.

    KEY

    The identifier of an object in a collection, its ID, if you will.

    QUERYSTRING

    A set of key-value pairs, used for filtering and setting options on collections.

    HTTP Verbs

    Where possible, the KIVRA API strives to use appropriate HTTP verbs for each action. The terms verb and method are used interchangingly.

    Idempotency

    The API supports idempotency for safely retrying requests without accidentally performing the same operation twice. For example, if a request that is idempotent fails due to a network connection error, you can safely retry the request.

    GET and DELETE requests are idempotent by definition, meaning that the same backend work will occur no matter how many times the same request is issued. You shouldn't send an idempotency key with these verbs because it will have no effect.

    In short, this means that making a request with an idempotent verb only changes the state of the data the first time the request is made.

    Methods

    Read more about HTTP/1.1 Method Definitions.

    Method Details
    GET Used to read a resource, be it a collection or an object. That is, it can be performed repeatedly without changing the state of the resource
    POST Used for creating resources, or performing custom or batch type actions
    PUT Used for updating resources or collections, but can also be used to create a resource when the key has been predetermined. Note that PUT apply to the entire resource and not just parts of it. So, when doing a PUT operation, the entire resource is replaced
    DELETE Used for deleting resources. Delete is atomic and acts on the whole resource, that is it can not be used to delete a part or alter the state of a resource. Use PUT for that

    Resource Types

    There are two main types of resources – objects and collections of objects, they are individually outlined in the following sections. It can generally be said that if a URL ends with a unique identifier (also known as a key), it is an object or a sub-object. Resources ending with collection names are collection resources.

    Object Resources

    Objects are mostly real-world things, such as a user, tenant to name a few, but they can also be abstract things, like a sendrequest.

    An example: /v1/tenant/13443459078e31ba8630e2e9842906c7baf38b131e

    Allowed Methods

    GET Read the representation of an object as it is accessible and viewable by you.

    PUT Update the object. If the object doesn’t already exist, it is created.

    PATCH Update the object with the specified attributes. If the object doesn’t already exist, it is created.

    DELETE Irreversably delete the designated resource from the entire system. This operation will in most cases be illegal for regular API consumers.

    Collection Resources

    Collections are conceptually lists of objects, that can be queried. Queries without any parameters will cause a listing of the keys that are used to identify the objects within the collection; adding parameters will either filter which keys show up or decorate the keys with the object they identify (in part or entirely).

    When a collection resource is queried it will only return the list of keys that identify the objects it contains. If you want to see the actual objects you have to append the query parameter include=body to the URI, more on this below.

    An example: /v1/tenant

    Allowed Methods

    GET List objects under the Collection, either all or using filters to search.

    POST Create a new object under the Collection.

    Filters and Flags

    In order to facilitate filtering/searching amongst the API objects, we provide the possibility to pass certain query string parameters that indicate which objects to include in the response and how they should be treated.

    Filters

    When searching for an object, it is suggested that you list the appropriate collection and add query parameters for the features of the object(s) you are trying to find in the URI. For example, when looking for if a user exists and is addressable for this Tenant, the resulting URL would be as follows /tenant/TKEY/user/?ssn=SSN

    Flags

    As mentioned, collections only list the keys of their member objects, which might inconvenience you by forcing you to make individual GET requests for each key in the list. In order to not waste bandwidth or time from setup and teardown of connections we supply the include flag. The include parameter currently accepts one of two values, body and fields, which indicate that you want the entire object or that you want a specific subset of the available fields, respectively.

    Note: When the include parameter is set to fields it is assumed that you will also pass a fields parameter with a comma-separated list of names, declaring which fields you want to view.

    Tenants integration

    Tenants integration allows tenants and integrators to send content to recipents via Kivra.

    Tenants and integrator will use the tenant endpoint to integrate with Kivra.

    Opt-out

    Kivra uses a method called opt-out to make the service as easy as possible for Recipients and Senders. Opt-out means that when a Recipient register with Kivra they’ll automatically receive documents from all Tenants connected to Kivra. Recipients do not need to enable individual Tenants to start receiving Content.

    Meaning of Opt-out for:

    Tenant

    Can start sending Content to all Recipients in Kivra When Tenant signs up new customers they can match that customers SSN or VAT-number to the user- or companies_accept-file respectively and start sending Content directly. A Recipient can choose to disable a Tenant. In that case, that user or company will no longer show up in the Tenant’s user- or companies_accept-file respectively and a 45-day grace period will take effect. During this grace period the Tenant can still post Content.

    Recipients

    Recipients will automatically start receiving Content from new Tenants Recipients can choose to disable a Tenant. In that case, that Recipient will no longer show up in the Tenant’s user- or companies_accept-file respectively and a 45-day grace period will take effect. During this grace period the Tenant can still post Content.

    Step 1: Synchronize Recipients

    The first thing in every integration is to synchronize which Recipients can receive Content from the Tenant. Trying to send Content to Recipients not found when synchronizing will be automatically denied unless that Recipient is in a 45 days’ grace period with that Tenant.

    This means that for each Tenant the Recipient-request is unique and therefore integrators integrating many Tenants need to keep track of the different Recipients for each of the separate Tenants.

    Synchronization of Recipients is done via the user and usermatch resources.

    Step 2: Send Content

    Metadata is data that Kivra needs to send the Content to the right Recipient. It may also determine how a Recipient can interact with the Content.

    Sending of Content is done via the content resource.

    Typical integration flows

    The Kivra API is typically integrated in different data flows, resulting in many different scenarios. In this paragraph we will describe few of these typical scenarios and provide some tips on how to use the API in that context.

    Daily document sending

    In this scenario the sender needs to send a large amount of documents each day, some of which is sent via Kivra, the rest via ordinary post. There is therefore need for knowing very early in the process whether a document can be sent via Kivra or needs to be printed and sent by ordinary post.

    The sender uses the API to synchronize the recipient database, typically during the night, and use the recipient database to select which documents to be sent via Kivra and which need to be printed and sent via ordinary post.

    Even if the recipient database have been synchronized, it is still important to check the result of the API operation when sending content, as some recipient might have become unavailable in the time between the synchronization of the recipient database and the sending of the document. In this case the API will answer with an error code (typically 40105). The documents that could not be sent via API will need to be sent via ordinary post, typically as part of tomorrow's batch.

    Payslips and retain functionality

    Payslips are typically small batches of documents sent once a month that can be handled using a simpler flow, not including the matching step but using the retain functionality instead.

    In this approach the sender sends all documents without checking if the user is a Kivra user or not, relying on the retain functionality instead. Content sent to non-Kivra users will be retained for a period of time (typically 390 days for payslips), meaning that it is kept by Kivra but not delivered. If the user creates a Kivra account before the retention period expires, the user will get all retained content. If the user does not create a Kivra account before the retention period expires, the content will be removed from Kivra.

    Payments and invoices

    Kivra allows to send both payable invoices (that might be paid via Kivra applications) or payment notifications that cannot be paid via Kivra, as for instance notification of autogiro payments.

    payable is the field in the metadata controlling whether the document should be payable via Kivra applications or not. As Kivra uses the information provided in the metadata to actually perform the payment, it is very important that metadata in the payment section is correct.

    Partners integration

    Partners integration allows a company recipient to open up its mailbox to a third party (a partner) to allow it to access and process the mailbox content. This is typically used by companies to allow bookkeeping and administrative third parties to access and process invoices and documents.

    Company recipients need to explicitly authorize a partner to access their content via a setting in their Kivra Company mailbox, and they can revoke access at any time. Both granting and revoking of access are performed via the Kivra app.

    Partners will use the partner endpoint to integrate with Kivra.

    Signatures (BETA, only available in sandbox)

    Signatures integration allows tenants and integrators to send content to be signed via Kivra's signature service. Content to be signed is sent to a list of receivers (signers or delegates, see below) who may login to signatures.kivra.com, identify themselves and sign the document via BankId. Upon signature by all parties, the agreement is completed and a new content is created (the covenant file, see below) including the original content plus a signing log listing all signers and information about the signature. Covenant files can be verified cryptographically to make sure that the information included (both original content and signing log) is correct and has not been altered after creation.

    Kivra's signature service is not directly connected to Kivra's mailbox, and parties in an agreement do not need to be users of Kivra to use the service. However signers that are users of Kivra (or become Kivra users during the signing process) will have the benefit that the covenant file will be automatically transferred to their mailbox once the agreement is signed.

    Signers, Delegates and Parties

    Each individual signing an agreement is categorized as either signeror delegate:

    Agreement states

    During its lifetime, an agreement can go through various states. The current state can be accessed by getting the agreement via the signature API:

    State active

    This is the inital state of the agreement after a successful create. During user actions on the agreement the state remains as active. The states that an active agreement can transition to are referred to as terminal states, meaning it's the end of the agreement lifecycle.

    If an agreement do not transition to a terminal state within 30 days from its creation, it will expire and it will be removed from all our services.

    The terminal states in which an agreement can transition to, are described here below.

    State completed

    Agreements automatically transitions to the state completed at the time when the last of all parties sign the agreement. When an agreement has been completed, it is forever under the terminal state completed and can never transition back to an active state or be acted upon by any party. In other words, no one can change a completed agreement.

    When an agreement becomes completed, a covenant file is created (see below). The covenant file will be availabe to the tenant via the signature API, and to the signers and delegates via the graphical interface.

    No one can change a signed agreement and the agreement along with all data and files relating to the agreement will be completely removed from all our services after 30 days from the date it became completed.

    State revoked

    This state can be triggered by a tenant who owns the agreement. If the agreement is active, the tenant can choose to revoke the agreement at any time. When an agreement has been revoked, it is forever under the terminal state revoked and can never transition back to an active state or be acted upon by any party. No one can sign a revoked agreement and the agreement along with all data and files relating to the agreement will be completely removed from all our services within 30 days after the date it was created.

    Agreement verification and covenant file

    When the agreement transitions to the completed state, a few more things happen. An additional PDF file, a signed version of the original agreement, is created. This file is called the covenant file. The covenant file includes the original agreement and some additional pages including Bank ID data for the signatures and additional information about the signing events. The covenant file is accessible for 30 days to the tenant and all parties, after that it is removed from all services, together with the initial descriptive data for the original agreement. However, we construct a new data structure that we store persistently and that will be used for verification: a 256bit string value constructed through an internal algorithm that we refer to as verification value.

    The verification value is used solely for verification purposes. This means that if you have access to the signed document, you can use this for verification through our services where we run the obtained file through our internal algorithm to produce the value string for that exact file.

    Notifications

    After creating the agreement, the tenant is responsible to inform the parties that there is a document waiting to be signed at signatures.kivra.com. After the users access the Kivra signature service and agree to its terms of service, Kivra will take care of notify the parties about events concerning the agreement lifecycle using the contact information provided by the tenant.

    Signature flow

    1. The tenant posts an agreement providing the PDF document to be signed and the list of parties, and gets back an agreement id. Parties are specified by their role, a SSN number, an email and a mobile phone. The agreement is made available by Kivra to the parties.
    2. The tenant uses the document ID to check the agreement status. The agreement can also be revoked by the tenant, as long as it has not reached the completed state.
    3. Once the document has become completed, the tenant can download the covenant file via the API and save it, while parties have different options based on whether they are users of Kivra or not: for Kivra user the covenant file will be automatically transferred to the Kivra mailbox; for non Kivra user, parties have 30 days to either become a Kivra user and get the covenant file in the Kivra mailbox, or download the covenant file from the signature service for personal storage.
    4. The agreement is removed from all our services 30 days after creation in case the agreement does not reach the completed state. The agreement and covenant file are removed from all our services 30 days after the agreement reached the completed state. Once the agreement and covenant file have been removed, there will be no option for recovering them, only the verification option will be available. So it is important that both tenant and signers make sure that they have saved and safely stored the covenant file.

    Errors

    Kivra uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, invalid data, etc.). Codes in the 5xx range indicate an error with Kivra's servers (these are rare).

    Error handling

    The integrator needs proper handling of common errors. Errors can happen at any stage and Kivra will report back to let the integrator take appropriate action.

    Recipient-file synchronization:

    Common errors that can occur and need to be handled gracefully.

    These errors should be handled gracefully such that the last working download of a Recipient-file is used until the problem has been solved and a new Recipient-file can be downloaded and used.

    Content Delivery:

    Common errors that can occur and need to be handled gracefully.

    Error Messages

    When the KIVRA API returns error messages, it does so in a extended JSON format.

    Example error response

    { "code"          : 40400
    , "short_message" : "Resource not found"
    , "long_message"  : "There's no resource at the given URI."
    }
    

    An error has four properties:

    Property Description
    code The Kivra error code
    short_message A short description of the error
    long_message A longer and more verbose error message

    Error codes

    In addition to descriptive error text, error messages contain machine-parseable codes. While the text for an error message may change, the codes will stay the same. The following table describes the codes which may appear when working with the API:

    Code Short Message Long Message
    40000 Invalid Token Could not authenticate with OAuth2 using the supplied token
    40001 Invalid Request The request was invalid
    40002 Redirect URI Mismatch The redirect_uri does not match the registered redirect_uri
    40003 Email adress in use The email adress supplied is already in use
    40004 Already registered This user is already registered
    40005 Error in phonenumber The request can't be processed due to phonenumber not meeting the required format
    40006 Error in password The request can't be processed due to password not meeting the required format
    40007 Error in email The request can't be processed due to email not meeting the required format
    40008 Unprocessable Entity The JSON payload was malformed. The client should not resend the same payload without first correcting the erroneous JSON payload.
    40009 Error in SSN The request can't be processed due to SSN not meeting the required format.
    40010 No action supplied or invalid The action parameter was not supplied or invalid.
    40011 Failed Extended Validation The request can't be processed due to SSN and/or mobile failed extended validation.
    40100 Unauthorized Supplied credentials was invalid
    40101 Access Denied The resource owner or authorization server denied the request
    40102 Unauthorized Client The client is not authorized to request an authorization code using this method.
    40103 Invalid Grant The provided authorization grant (e.g. authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
    40104 Invalid Client Client authentication failed (e.g. unknown client, no client authentication included, or unsupported authentication method).
    40105 Invalid Sendrequest No sendrequest exists between sender and receiver, or sendrequest is not accepted.
    40106 Email in use This email adress is already in use and can not be used.
    40108 Registration Code or Sendrequest Invalid The Registration Code is invalid or no Sendrequest exists or has been expired.
    40300 Forbidden Access was denied to the given resource, authenticating will make no difference
    40400 Not found The resource was not found at the given URI at this time
    40500 Method Not Allowed The method specified in is not allowed for the resource at the requested URI
    40601 Invalid Accept Header The Accept Header contains a non valid or unknown Content-Type
    42900 Too Many Requests Too many requests within this timespan have been made. Please try again later

    Authentication

    Create the RFC 2045 base64 encoding to be used for tenant registration, replace client_id and client_secret with real values and make sure there are no trailing newlines (echo -n) and that the string is encoded literally (use single quotes and no escaping)

    $ echo -n 'client_id:client_secret' | base64
    Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=
    

    Then perform the authentication which will respond with an access token.

    REQUEST: Authentication

    curl -i -X POST https://api.kivra.com/v1/auth \
       -d "grant_type=client_credentials" \
       -H "Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ="
    

    RESPONSE: Authentication

    HTTP/1.1 200 OK
    Server: nginx
    Date: Thu, 02 Oct 2014 12:43:25 GMT
    Content-Type: application/json
    Content-Length: 124
    Connection: keep-alive
    Vary: Accept-Encoding
    Strict-Transport-Security: max-age=31536000;
    
    {
      "state":"",
      "access_token":"H6Zq08rF5fjQttd6fTKepWb3FQNptcip",
      "expires_in":28800,
      "scope":"kivra.v1.tenant.{tenant-key}.*",
      "token_type":"bearer"
    }
    

    A new access_token can be requested any time. If a request to the API is issued with a non valid access_token a http-response with the HTTP-header 401 is returned such as HTTP/1.1 401 Unauthorized. With the use of a valid access_token request to the API can be done as the example below.

    Example request with access_token

    curl -i -X GET -H "Authorization: Bearer <access_token>" <api-url-to-object>
    

    Authorization with limited access scope

    In some particular configuration, for instance when a centralized service wants to provide a satellite service with possibility to only send content to Kivra for a specific tenant, but not allowing any other operation, the centralized service may request an access token for a specific tenant with a limited scope. This access token can be safely provided to the satellite service.

    To retrieve this access token, the client performs a new authorization with some extra parameters specifying the limited scope.

    curl -X POST \
      https://api.kivra.com/v1/auth \
      -d grant_type=client_credentials \
      -d scope=post:kivra.v1.tenant.{tenant-key}.content \
      -H "Authorization: Basic {base64-auth}"
    

    The answer will look like the following:

    {
        "state": "",
        "access_token": "DMWmtGWe9YpXep6FTgVEwWttxLR6D53z",
        "expires_in": 28800,
        "scope": "post:kivra.v1.tenant.{tenant-key}.content",
        "token_type": "bearer"
    }
    

    Scope

    Scopes are specified as one or a commaseparated list of methods with a path appended and separated by :.

    Method is a lower case string of one or more of the allowed methods, valid examples:

    Example Details
    post:path Allows POST for the given path
    get,put:path Allows GET and PUT for the given path

    Path is a lower case string starting with the keyword kivra and the path appended and interspersed with . instead of the path-separator / such as: kivra.v1.example. There is also the possibility to use wildcards:

    Wildcard Details
    * Marks a scope as valid for any keyword on current-level
    ** Marks a scope as valid for any keyword on current-level and recursively

    - Flow: clientCredentials

    - Token URL = https://api.kivra.com/v1/auth

    Partner API

    Endpoints for partner access

    Find Company

    Code samples

    # You can also use wget
    curl -X GET https://api.kivra.com/v1/partner/company?vat_number=SE556840226601 \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    GET https://api.kivra.com/v1/partner/company?vat_number=SE556840226601 HTTP/1.1
    Host: api.kivra.com
    
    Accept: application/json
    
    
    var headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/partner/company',
      method: 'get',
      data: '?vat_number=SE556840226601',
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/partner/company?vat_number=SE556840226601',
    {
      method: 'GET',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.get 'https://api.kivra.com/v1/partner/company',
      params: {
      'vat_number' => 'string'
    }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.get('https://api.kivra.com/v1/partner/company', params={
      'vat_number': 'SE556840226601'
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/partner/company?vat_number=SE556840226601");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("GET", "https://api.kivra.com/v1/partner/company", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    GET /partner/company

    Lookup a specific company

    This resource allows a partner to look if a specific company has granted access to its mailbox.

    Parameters

    Parameter In Description
    vat_numberrequiredstring query Perform a search to see if a specific Company is available for access

    Example responses

    200 Response

    {
      "key": "15236156848eefa1dc75364af2be38c98eb3aae223"
    }
    

    Responses

    Status Meaning Description Schema
    200 OK Company key for the company with the matching VAT number CompanyKey

    Get company inbox

    Code samples

    # You can also use wget
    curl -X GET https://api.kivra.com/v1/partner/company/{companyKey}/content \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    GET https://api.kivra.com/v1/partner/company/{companyKey}/content HTTP/1.1
    Host: api.kivra.com
    
    Accept: application/json
    
    
    var headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/partner/company/{companyKey}/content',
      method: 'get',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/partner/company/{companyKey}/content',
    {
      method: 'GET',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.get 'https://api.kivra.com/v1/partner/company/{companyKey}/content',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.get('https://api.kivra.com/v1/partner/company/{companyKey}/content', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/partner/company/{companyKey}/content");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("GET", "https://api.kivra.com/v1/partner/company/{companyKey}/content", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    GET /partner/company/{companyKey}/content

    Get the company inbox

    This resource allows to access a high level description for each content in the company inbox, to allow for a first sorting and filtering of the content.

    Parameters

    Parameter In Description
    companyKeyrequiredstring path The unique key for the company object being retrieved

    Example responses

    200 Response

    [
      {
        "key": "15294092505b9cfab3f79d233f8eca6fbc5385fa61",
        "sender": "1341573157b3a133f220f4217b2e32989d2efa015",
        "sender_name": "Kivra",
        "created_at": "2018-06-19T11:54:10Z",
        "subject": "Invoice 4512 from Local Bank",
        "status": "read"
      }
    ]
    

    Responses

    Status Meaning Description Schema
    200 OK High level description of content items in the company inbox Inline

    Response Schema

    Status Code 200

    Name Description
    anonymous[CompanyInbox] No description
    » keystring Content's unique key
    » senderstring Unique key for the tenant that posted the content
    » sender_namestring Name of the tenant that posted the content
    » created_atstring Date and time when the content was delivered to the recipient
    » subjectstring Subject of the content, as set by the sender
    » statusstring Whether the content has been read (opened) or not

    Enumerated Values

    Property Value
    status read
    status unread

    Get content metadata

    Code samples

    # You can also use wget
    curl -X GET https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey} \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    GET https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey} HTTP/1.1
    Host: api.kivra.com
    
    Accept: application/json
    
    
    var headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}',
      method: 'get',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}',
    {
      method: 'GET',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.get 'https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.get('https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("GET", "https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    GET /partner/company/{companyKey}/content/{contentKey}

    Get metadata for a content.

    This resource allows to get complete metadata information for a particular content.

    Parameters

    Parameter In Description
    companyKeyrequiredstring path The unique key for the company object being retrieved
    contentKeyrequiredstring path The unique key for a specific content

    Example responses

    200 Response

    {
      "sender": "1341573157b3a133f220f4217b2e32989d2efa015",
      "sender_name": "Kivra",
      "created_at": "2018-06-19T11:54:10Z",
      "subject": "Invoice 4512 from Local Bank",
      "receiver_name": "Digital Hero AB",
      "payment": {
        "payable": true,
        "status": "unpaid",
        "currency": "SEK",
        "due_date": "2017-01-01",
        "total_owed": "123.50",
        "type": "SE_OCR",
        "method": "1",
        "account": "12345",
        "reference": "123OCRNUMBER456",
        "variable_amount": false,
        "min_amount": "50.00"
      },
      "parts": [
        {
          "content_type": "application/pdf",
          "checksum": "9209c7eebdd283a4c4bd7555e73e6064",
          "sha256": "287f2fe67a8a76a10169aa6a885d21e1f83416c4831294ea5c4b0a38bda5c78d",
          "size": 163414,
          "body": "<!doctype html>\n<html class=\"....",
          "key": "15118724482475bf32615b4a2aaa604fd66377010e"
        }
      ]
    }
    

    Responses

    Status Meaning Description Schema
    200 OK Complete metadata for the specific content CompanyContent

    Get raw file

    Code samples

    # You can also use wget
    curl -X GET https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/file/{fileKey}/raw \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    GET https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/file/{fileKey}/raw HTTP/1.1
    Host: api.kivra.com
    
    Accept: application/json
    
    
    var headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/file/{fileKey}/raw',
      method: 'get',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/file/{fileKey}/raw',
    {
      method: 'GET',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.get 'https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/file/{fileKey}/raw',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.get('https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/file/{fileKey}/raw', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/file/{fileKey}/raw");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("GET", "https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/file/{fileKey}/raw", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    GET /partner/company/{companyKey}/content/{contentKey}/file/{fileKey}/raw

    Get raw file in binary format

    This resource allows to get the raw file in binary format.

    Parameters

    Parameter In Description
    companyKeyrequiredstring path The unique key for the company object being retrieved
    contentKeyrequiredstring path The unique key for a specific content
    fileKeyrequiredstring path The unique key for a specific file

    Example responses

    200 Response

    "string"
    

    Responses

    Status Meaning Description Schema
    200 OK The content type will be the same as the file, so for a typical pdf it will be application/pdf string

    Set status for content

    Code samples

    # You can also use wget
    curl -X POST https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/{status} \
      -H 'Authorization: Bearer {access-token}'
    
    
    POST https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/{status} HTTP/1.1
    Host: api.kivra.com
    
    
    var headers = {
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/{status}',
      method: 'post',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/{status}',
    {
      method: 'POST',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.post 'https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/{status}',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.post('https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/{status}', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/{status}");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("POST");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("POST", "https://api.kivra.com/v1/partner/company/{companyKey}/content/{contentKey}/{status}", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    POST /partner/company/{companyKey}/content/{contentKey}/{status}

    Set status for content

    This resource allows to set the status for a specific content. It is used by the partner to set whether the content should be marked as viewed or paid.

    Parameters

    Parameter In Description
    companyKeyrequiredstring path The unique key for the company object being retrieved
    contentKeyrequiredstring path The unique key for a specific content
    statusrequiredstring path The specific state to be set for this content, can be paid, unpaid, view or unview

    Responses

    Status Meaning Description Schema
    204 No Content empty response confirming that the operation was successful None

    Tenant API

    Endpoints for tenant management and content

    Create Tenant

    Code samples

    # You can also use wget
    curl -X POST https://api.kivra.com/v1/tenant \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    POST https://api.kivra.com/v1/tenant HTTP/1.1
    Host: api.kivra.com
    Content-Type: application/json
    Accept: application/json
    
    
    var headers = {
      'Content-Type':'application/json',
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant',
      method: 'post',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    const inputBody = '{
      "name": "Kivra",
      "company_id": [
        {
          "name": "Kivra AB",
          "orgnr": "SE556840226601"
        }
      ]
    }';
    const headers = {
      'Content-Type':'application/json',
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant',
    {
      method: 'POST',
      body: inputBody,
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Content-Type' => 'application/json',
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.post 'https://api.kivra.com/v1/tenant',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.post('https://api.kivra.com/v1/tenant', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("POST");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Content-Type": []string{"application/json"},
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("POST", "https://api.kivra.com/v1/tenant", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    POST /tenant

    Create Tenant

    Creation of tenants via API allows clients to create new tenants in an efficient manner. The created tenant is automatically added to the client scope. The client needs to re-authenticate to have the new scope in effect.

    Body parameter

    {
      "name": "Kivra",
      "company_id": [
        {
          "name": "Kivra AB",
          "orgnr": "SE556840226601"
        }
      ]
    }
    

    Parameters

    Parameter In Description
    bodyTenant body No description

    Example responses

    201 Response

    {
      "name": "Kivra",
      "company_id": [
        {
          "name": "Kivra AB",
          "orgnr": "SE556840226601"
        }
      ],
      "edit_security_level": 25,
      "groups": [],
      "visibility": "visible"
    }
    

    Responses

    Status Meaning Description Schema
    201 Created Tenant Created succesfully Tenant

    Response Headers

    Status Header Description
    201 kivra-objkeystring(hexadecimal value) Object Key
    201 locationstring(url) URL to created Object

    List Users

    Code samples

    # You can also use wget
    curl -X GET https://api.kivra.com/v1/tenant/{tenantKey}/user \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    GET https://api.kivra.com/v1/tenant/{tenantKey}/user HTTP/1.1
    Host: api.kivra.com
    
    Accept: application/json
    
    
    var headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant/{tenantKey}/user',
      method: 'get',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant/{tenantKey}/user',
    {
      method: 'GET',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.get 'https://api.kivra.com/v1/tenant/{tenantKey}/user',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.get('https://api.kivra.com/v1/tenant/{tenantKey}/user', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant/{tenantKey}/user");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("GET", "https://api.kivra.com/v1/tenant/{tenantKey}/user", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    GET /tenant/{tenantKey}/user

    List available recipient users for a tenant

    This resource is used to list all or search for users that eligible for receiving Content from the specific Tenant. The response is a JSON list of Objects containing the User’s key and SSN.

    Parameters

    Parameter In Description
    tenantKeyrequiredstring(hexadecimal) path The unique Key for a Tenant
    ssnstring query Perform a search to see if a specific User is available

    Example responses

    200 Response

    [
      {
        "key": "15236156848eefa1dc75364af2be38c98eb3aae223",
        "ssn": "191212121212"
      }
    ]
    

    Responses

    Status Meaning Description Schema
    200 OK List of available users Inline

    Response Schema

    Status Code 200

    List of available users, can be empty

    Name Description
    anonymous[User] List of available users, can be empty
    » keystring User's unique Key
    » ssnstring User's unique SSN in the form YYYYMMDDnnnn

    Match Users

    Code samples

    # You can also use wget
    curl -X POST https://api.kivra.com/v1/tenant/{tenantKey}/usermatch \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    POST https://api.kivra.com/v1/tenant/{tenantKey}/usermatch HTTP/1.1
    Host: api.kivra.com
    Content-Type: application/json
    Accept: application/json
    
    
    var headers = {
      'Content-Type':'application/json',
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant/{tenantKey}/usermatch',
      method: 'post',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    const inputBody = '{
      "ssns": [
        "191212121212",
        "197701032380",
        "198112172385"
      ]
    }';
    const headers = {
      'Content-Type':'application/json',
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant/{tenantKey}/usermatch',
    {
      method: 'POST',
      body: inputBody,
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Content-Type' => 'application/json',
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.post 'https://api.kivra.com/v1/tenant/{tenantKey}/usermatch',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.post('https://api.kivra.com/v1/tenant/{tenantKey}/usermatch', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant/{tenantKey}/usermatch");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("POST");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Content-Type": []string{"application/json"},
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("POST", "https://api.kivra.com/v1/tenant/{tenantKey}/usermatch", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    POST /tenant/{tenantKey}/usermatch

    Match a list of recipient users for a specific tenant

    This resource is used to match a list of users to check that they are eligible for receiving Content from the specific Tenant. The request contains a list of SSNs to be matched, and the response is a filtered list containing only the SSNs that are eligible to receive content from the tenant.

    Body parameter

    {
      "ssns": [
        "191212121212",
        "197701032380",
        "198112172385"
      ]
    }
    

    Parameters

    Parameter In Description
    tenantKeyrequiredstring(hexadecimal) path The unique Key for a Tenant
    bodyrequiredUserMatch body List of SSNs to be matched

    Example responses

    200 Response

    {}
    

    Responses

    Status Meaning Description Schema
    200 OK Filtered list of SSNs UserMatch

    List Companies

    Code samples

    # You can also use wget
    curl -X GET https://api.kivra.com/v1/tenant/{tenantKey}/company \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    GET https://api.kivra.com/v1/tenant/{tenantKey}/company HTTP/1.1
    Host: api.kivra.com
    
    Accept: application/json
    
    
    var headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant/{tenantKey}/company',
      method: 'get',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant/{tenantKey}/company',
    {
      method: 'GET',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.get 'https://api.kivra.com/v1/tenant/{tenantKey}/company',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.get('https://api.kivra.com/v1/tenant/{tenantKey}/company', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant/{tenantKey}/company");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("GET", "https://api.kivra.com/v1/tenant/{tenantKey}/company", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    GET /tenant/{tenantKey}/company

    List available recipient companies for a tenant

    This resource is used to list all or search for companies that eligible for receiving Content from the specific Tenant. The response is a JSON list of Objects containing the Companies key and Vat Number.

    Parameters

    Parameter In Description
    tenantKeyrequiredstring(hexadecimal) path The unique Key for a Tenant
    vat_numberstring query Perform a search to see if a specific Company is available

    Example responses

    200 Response

    [
      {
        "key": "15236156848eefa1dc75364af2be38c98eb3aae223",
        "vatnr": "SE556840226601"
      }
    ]
    

    Responses

    Status Meaning Description Schema
    200 OK List of available companies Inline

    Response Schema

    Status Code 200

    List of available companies, can be empty

    Name Description
    anonymous[Company] List of available companies, can be empty
    » keystring Company's unique Key
    » vatnrstring Company's unique Vat Number

    Send content

    Code samples

    # You can also use wget
    curl -X POST https://api.kivra.com/v1/tenant/{tenantKey}/content \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    POST https://api.kivra.com/v1/tenant/{tenantKey}/content HTTP/1.1
    Host: api.kivra.com
    Content-Type: application/json
    Accept: application/json
    
    
    var headers = {
      'Content-Type':'application/json',
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant/{tenantKey}/content',
      method: 'post',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    const inputBody = '{
      "ssn": "191212121212",
      "subject": "Sample Invoice",
      "generated_at": "2016-12-12",
      "files": [
        {
          "name": "filename.pdf",
          "data": "REVBREJFRUY=",
          "content_type": "application/pdf"
        }
      ]
    }';
    const headers = {
      'Content-Type':'application/json',
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant/{tenantKey}/content',
    {
      method: 'POST',
      body: inputBody,
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Content-Type' => 'application/json',
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.post 'https://api.kivra.com/v1/tenant/{tenantKey}/content',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.post('https://api.kivra.com/v1/tenant/{tenantKey}/content', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant/{tenantKey}/content");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("POST");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Content-Type": []string{"application/json"},
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("POST", "https://api.kivra.com/v1/tenant/{tenantKey}/content", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    POST /tenant/{tenantKey}/content

    Send content to a recipient (user or company)

    Metadata is data that Kivra needs to send the Content to the right User. It may also determine how a User can interact with the Content.

    Minimum Metadata

    As a minimum a valid ssn or vat_number is required.

    Inactive Content

    An inactive Content is a Content that is sent to a Recipient who is not yet a user of Kivra. Once that Recipient register with Kivra, the Content will be delivered to that Recipient’s Kivra account. Inactive Content has a time limit for how long they can be Inactive before being deleted, ie removed unless the Recipient activates their account within a given period of time.

    Sending inactive Content uses all the same attributes as a normal Content with the difference for some additional metadata-attributes. By enabling the retain metadata attribute and setting it to true will enable possible retention of a Content. Kivra’s logic is to first look if the Recipient exist. If it does Kivra will deliver the Content as usual, if the Recipient doesn’t exist Kivra will retain the Content for the default amount of time (30 days). This makes it easy for an Integrator to issue a "retain or deliver"-logic for all it’s Contents.

    If an integrator want to retain a Content for a another time-period than Kivra’s default if can be done via the retention_time additional metadata.

    Body parameter

    {
      "ssn": "191212121212",
      "subject": "Sample Invoice",
      "generated_at": "2016-12-12",
      "files": [
        {
          "name": "filename.pdf",
          "data": "REVBREJFRUY=",
          "content_type": "application/pdf"
        }
      ]
    }
    

    Parameters

    Parameter In Description
    tenantKeyrequiredstring(hexadecimal) path The unique Key for a Tenant
    bodyContent body No description

    Example responses

    201 Response

    {
      "subject": "Sample Invoice",
      "generated_at": "2016-12-12"
    }
    

    Responses

    Status Meaning Description Schema
    201 Created Content Created succesfully Content

    Response Headers

    Status Header Description
    201 kivra-objkeystring(hexadecimal value) Object Key
    201 kivra-retainedboolean Boolean denoting if a Content was Retained, Note: this header is only returned when a Content is retained
    201 locationstring(url) URL to created Object

    Tenant Agreement API

    Endpoints for agreements management (BETA)

    Post Agreement

    Code samples

    # You can also use wget
    curl -X POST https://api.kivra.com/v1/tenant/{tenantKey}/agreement \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    POST https://api.kivra.com/v1/tenant/{tenantKey}/agreement HTTP/1.1
    Host: api.kivra.com
    Content-Type: application/json
    Accept: application/json
    
    
    var headers = {
      'Content-Type':'application/json',
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement',
      method: 'post',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    const inputBody = '{
      "subject": "Employment agreement",
      "type": "agreement",
      "vat_number": "SE556913262701",
      "original": {
        "name": "agreement1025.pdf",
        "content_type": "application/pdf",
        "data": "REVBREJFRUY="
      },
      "parties": [
        {
          "ssn": "197701032380",
          "name": "Jan-Erik Karlsson",
          "email": "je.karlsson@email.nu",
          "phone": "+46705050505",
          "role": "signer"
        },
        {
          "ssn": "198112172385",
          "name": "Gustav Larsson",
          "email": "gustav123@mymail.com",
          "phone": "+46705212121",
          "role": "delegate"
        }
      ]
    }';
    const headers = {
      'Content-Type':'application/json',
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant/{tenantKey}/agreement',
    {
      method: 'POST',
      body: inputBody,
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Content-Type' => 'application/json',
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.post 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.post('https://api.kivra.com/v1/tenant/{tenantKey}/agreement', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant/{tenantKey}/agreement");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("POST");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Content-Type": []string{"application/json"},
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("POST", "https://api.kivra.com/v1/tenant/{tenantKey}/agreement", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    POST /tenant/{tenantKey}/agreement

    Post an agreement to be signed

    This resource is used to post an agreement to be signed by the recipients listed in the metadata. An Agreement ID will be returned.

    Body parameter

    {
      "subject": "Employment agreement",
      "type": "agreement",
      "vat_number": "SE556913262701",
      "original": {
        "name": "agreement1025.pdf",
        "content_type": "application/pdf",
        "data": "REVBREJFRUY="
      },
      "parties": [
        {
          "ssn": "197701032380",
          "name": "Jan-Erik Karlsson",
          "email": "je.karlsson@email.nu",
          "phone": "+46705050505",
          "role": "signer"
        },
        {
          "ssn": "198112172385",
          "name": "Gustav Larsson",
          "email": "gustav123@mymail.com",
          "phone": "+46705212121",
          "role": "delegate"
        }
      ]
    }
    

    Parameters

    Parameter In Description
    tenantKeyrequiredstring(hexadecimal) path The unique Key for a Tenant
    bodyAgreement body No description

    Example responses

    200 Response

    "15544700816b7d63c83d6e476493879b5043ec9d7b"
    

    Responses

    Status Meaning Description Schema
    200 OK Agreement created succesfully string

    List agreements

    Code samples

    # You can also use wget
    curl -X GET https://api.kivra.com/v1/tenant/{tenantKey}/agreement \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    GET https://api.kivra.com/v1/tenant/{tenantKey}/agreement HTTP/1.1
    Host: api.kivra.com
    
    Accept: application/json
    
    
    var headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement',
      method: 'get',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant/{tenantKey}/agreement',
    {
      method: 'GET',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.get 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.get('https://api.kivra.com/v1/tenant/{tenantKey}/agreement', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant/{tenantKey}/agreement");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("GET", "https://api.kivra.com/v1/tenant/{tenantKey}/agreement", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    GET /tenant/{tenantKey}/agreement

    List all agreements for a tenant, with their current status

    List all agreements created by a tenant, with their current status.

    Parameters

    Parameter In Description
    tenantKeyrequiredstring(hexadecimal) path The unique Key for a Tenant

    Example responses

    200 Response

    [
      {
        "key": "1527232009ba54f8186d8c43e2a3c8092b57ca2739",
        "state": "active"
      },
      {
        "key": "155265136911763308f2514ff3aa6dacc8211a2107",
        "state": "revoked"
      },
      {
        "key": "15100645203cff9f19d92443848c8a2f1cbf257510",
        "state": "completed"
      }
    ]
    

    Responses

    Status Meaning Description Schema
    200 OK List of agreements and their status Inline

    Response Schema

    Status Code 200

    list

    Name Description
    anonymous[AgreementStateShort] list
    » keystring unique agreement id
    » statestring current state for the agreement

    Get agreement

    Code samples

    # You can also use wget
    curl -X GET https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey} \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer {access-token}'
    
    
    GET https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey} HTTP/1.1
    Host: api.kivra.com
    
    Accept: application/json
    
    
    var headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}',
      method: 'get',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Accept':'application/json',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}',
    {
      method: 'GET',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Accept' => 'application/json',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.get 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.get('https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Accept": []string{"application/json"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("GET", "https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    GET /tenant/{tenantKey}/agreement/{agreementKey}

    Agreement object with current status and updated metadata

    Get an agreement with current status and updated metadata

    Parameters

    Parameter In Description
    tenantKeyrequiredstring(hexadecimal) path The unique Key for a Tenant
    agreementKeyrequiredstring(hexadecimal) path The unique Key for an Agreement

    Example responses

    200 Response

    [
      {
        "created_at": "2019-04-09T13:42:26Z",
        "signatures": [
          {
            "ssn": "197701032380",
            "real_name": "Jan-Erik Karlsson",
            "created_at": "2019-04-12T08:23:29Z",
            "order_ref": "d4ace777-6b91-4172-903e-39371ede89f1"
          },
          {
            "ssn": "198112172385",
            "real_name": "Gustav Johan Larsson",
            "created_at": "2019-04-11T18:53:03Z",
            "order_ref": "f5bce777-0b42-4222-1f3e-ab523ede7a5f"
          }
        ],
        "state": "completed",
        "expires_at": "2019-05-09T13:42:26Z",
        "trashed_at": "2019-05-12T08:23:29Z",
        "parties": [
          {
            "ssn": "197701032380",
            "name": "Jan-Erik Karlsson",
            "email": "je.karlsson.hem@email.nu",
            "phone": "+46705050505",
            "role": "signer"
          },
          {
            "ssn": "198112172385",
            "name": "Gustav Larsson",
            "email": "gustav123@mymail.com",
            "phone": "+46705212121",
            "role": "delegate"
          }
        ],
        "subject": "Employment agreement"
      }
    ]
    

    Responses

    Status Meaning Description Schema
    200 OK Agreement object with current status and updated metadata Inline

    Response Schema

    Status Code 200

    list

    Name Description
    anonymous[AgreementStateDetailed] list
    » created_atstring The time when the agreement was created
    » signatures[AgreementSignature] List of signatures
    »» ssnstring Signer's unique SSN, format: YYYYMMDDnnnn
    »» real_namestring The real name of the signer, as provided by Mobile BankID service
    »» created_atstring The time when the signature was created
    »» order_refstring The unique ID of the signature
    » statestring The current state of the agreement
    » expires_atstring The expiration time for the agreement, if the agreement is not completed before this date, it will no longer be available for signature
    » trashed_atstring The time when the signed agreement will no longer be available for download or via the API. This field is relevant only when state is "completed"
    » parties[AgreementParties] list of signers and delegates that are requested to sign the agreement
    »» ssnstring User's unique SSN, format: YYYYMMDDnnnn
    »» namestring Name of the user
    »» emailstring email to be used to contact the user
    »» phonestring mobile phone to be used to contact the user (via SMS)
    »» rolestring the role of the user in this signature flow
    » subjectstring Name of the agreement

    Enumerated Values

    Property Value
    state active
    state completed
    state revoked
    role signer
    role delegate

    Revoke agreement

    Code samples

    # You can also use wget
    curl -X POST https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/revoke \
      -H 'Authorization: Bearer {access-token}'
    
    
    POST https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/revoke HTTP/1.1
    Host: api.kivra.com
    
    
    var headers = {
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/revoke',
      method: 'post',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/revoke',
    {
      method: 'POST',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.post 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/revoke',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.post('https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/revoke', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/revoke");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("POST");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("POST", "https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/revoke", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    POST /tenant/{tenantKey}/agreement/{agreementKey}/revoke

    Revoke an agreement

    Revoke an agreement. An agreement once revoked can no longer be accessed or signed by any of the parties. An agreement can only be rekoved if in state active, and after revoke will be put in state revoked. A revoked agreement can never become active again.

    Parameters

    Parameter In Description
    tenantKeyrequiredstring(hexadecimal) path The unique Key for a Tenant
    agreementKeyrequiredstring(hexadecimal) path The unique Key for an Agreement

    Responses

    Status Meaning Description Schema
    204 No Content empty response confirming that the revoke operation was successful None

    Get covenant agreement

    Code samples

    # You can also use wget
    curl -X GET https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/covenant \
      -H 'Accept: application/octet-stream' \
      -H 'Authorization: Bearer {access-token}'
    
    
    GET https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/covenant HTTP/1.1
    Host: api.kivra.com
    
    Accept: application/octet-stream
    
    
    var headers = {
      'Accept':'application/octet-stream',
      'Authorization':'Bearer {access-token}'
    
    };
    
    $.ajax({
      url: 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/covenant',
      method: 'get',
    
      headers: headers,
      success: function(data) {
        console.log(JSON.stringify(data));
      }
    })
    
    
    const request = require('node-fetch');
    
    const headers = {
      'Accept':'application/octet-stream',
      'Authorization':'Bearer {access-token}'
    
    };
    
    fetch('https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/covenant',
    {
      method: 'GET',
    
      headers: headers
    })
    .then(function(res) {
        return res.json();
    }).then(function(body) {
        console.log(body);
    });
    
    
    require 'rest-client'
    require 'json'
    
    headers = {
      'Accept' => 'application/octet-stream',
      'Authorization' => 'Bearer {access-token}'
    }
    
    result = RestClient.get 'https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/covenant',
      params: {
      }, headers: headers
    
    p JSON.parse(result)
    
    
    import requests
    headers = {
      'Accept': 'application/octet-stream',
      'Authorization': 'Bearer {access-token}'
    }
    
    r = requests.get('https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/covenant', params={
    
    }, headers = headers)
    
    print r.json()
    
    
    URL obj = new URL("https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/covenant");
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    System.out.println(response.toString());
    
    
    package main
    
    import (
           "bytes"
           "net/http"
    )
    
    func main() {
    
        headers := map[string][]string{
            "Accept": []string{"application/octet-stream"},
            "Authorization": []string{"Bearer {access-token}"},
    
        }
    
        data := bytes.NewBuffer([]byte{jsonReq})
        req, err := http.NewRequest("GET", "https://api.kivra.com/v1/tenant/{tenantKey}/agreement/{agreementKey}/covenant", data)
        req.Header = headers
    
        client := &http.Client{}
        resp, err := client.Do(req)
        // ...
    }
    
    

    GET /tenant/{tenantKey}/agreement/{agreementKey}/covenant

    Get the covenant file (signed agreement)

    Get the covenant file (the signed version of the agreement).

    Parameters

    Parameter In Description
    tenantKeyrequiredstring(hexadecimal) path The unique Key for a Tenant
    agreementKeyrequiredstring(hexadecimal) path The unique Key for an Agreement

    Example responses

    200 Response

    Responses

    Status Meaning Description Schema
    200 OK The covenant file as a PDF file with base64 encoding Inline

    Response Schema

    Status Code 200

    Name Description
    » datastring(base64) The covenant file as a PDF file with base64 encoding

    Schemas

    Content

    {
      "ssn": "191212121212",
      "vat_number": "SE556840226601",
      "subject": "Sample Invoice",
      "generated_at": "2016-12-12",
      "retain": true,
      "retention_time": "30",
      "tenant_info": "string",
      "files": [
        {
          "name": "filename.pdf",
          "data": "REVBREJFRUY=",
          "content_type": "application/pdf"
        }
      ],
      "context": {
        "invoice": {
          "payment": {
            "payable": true,
            "status": "unpaid",
            "currency": "SEK",
            "due_date": "2017-01-01",
            "total_owed": "123.50",
            "type": "SE_OCR",
            "method": "1",
            "account": "12345",
            "reference": "123OCRNUMBER456",
            "variable_amount": false,
            "min_amount": "50.00"
          },
          "invoice_reference": "Invoice Nr #123"
        }
      }
    }
    

    Properties

    Name Description
    ssnrequiredstring User's unique SSN, format: YYYYMMDDnnnn
    vat_numberrequiredstring A valid VAT-identifier, Swedish format: SE[xxxxxxxxxx]01
    subjectstring This Subject/Title will be visibile in the Recipients Inbox.
    generated_atstring(ISO8601) Optional attribute which denotes when a specific Content was generated at the tenant/integrator’s site. The attribute will be used for sorting in the Kivra user interface, which makes it possible for a tenant or integrator to control the sorting.
    retainboolean Boolean denoting if Kivra should try and retain this Content if it can’t be delivered. Default false
    retention_timestring How long to retain a Content. Supported values: "30" and "390"
    tenant_infostring An arbitrary string defined by the tenant, used to group content for administrative tasks
    files[File] Array of file Objects
    contextobject Optionally specify additional information
    » invoiceobject Optionally specify invoice information
    »» paymentPayment No description
    »» invoice_referencestring Tenant’s own Invoice Reference

    Enumerated Values

    Property Value
    retention_time 30
    retention_time 390

    Payment

    {
      "payable": true,
      "status": "unpaid",
      "currency": "SEK",
      "due_date": "2017-01-01",
      "total_owed": "123.50",
      "type": "SE_OCR",
      "method": "1",
      "account": "12345",
      "reference": "123OCRNUMBER456",
      "variable_amount": false,
      "min_amount": "50.00"
    }
    

    Properties

    Optionally specify payment information

    Name Description
    payablerequiredboolean Toggles whether this content should be payable through Kivra’s payment platform
    statusstring Toggles whether this content is paid or unpaid: if already paid the user can’t pay it again through Kivra
    currencyrequiredstring(ISO4217) Currency used in specifying total_owed
    due_daterequiredstring(ISO8601) Date when this Invoice is due
    total_owedrequiredstring(float) The total amount owed according to the invoice. If payable equals true this must be a non negative number that’s greater than "0"
    typerequiredstring Type of format for the reference
    methodrequiredstring 1 = BG and 2 = PG
    accountrequiredstring Tenant’s account number
    referencerequiredstring The reference number used for paying
    variable_amountboolean Toggles whether the user may choose to pay only a portion of the total_owed amount or whether the user must always pay the complete total_owed amount
    min_amountstring(float) The minimum amount that can be paid when variable_amount equals true. Note that this is a soft limit, so whenever variable_amount is true the user will be able to choose freely the amount to be paid, but it may be warned if the amount paid is inferior to min_amount

    Enumerated Values

    Property Value
    status paid
    status unpaid
    type SE_OCR
    type TENANT_REF
    method 1
    method 2

    Company

    {
      "key": "15236156848eefa1dc75364af2be38c98eb3aae223",
      "vatnr": "SE556840226601"
    }
    

    Properties

    Name Description
    keystring Company's unique Key
    vatnrstring Company's unique Vat Number

    User

    {
      "key": "15236156848eefa1dc75364af2be38c98eb3aae223",
      "ssn": "191212121212"
    }
    

    Properties

    Name Description
    keystring User's unique Key
    ssnstring User's unique SSN in the form YYYYMMDDnnnn

    UserMatch

    {
      "ssns": [
        "191212121212",
        "197701032380",
        "198112172385"
      ]
    }
    

    Properties

    usermatchRequest

    Name Description
    ssnsrequired[string] list of SSNs to be matched

    Tenant

    {
      "name": "Kivra",
      "company_id": [
        {
          "name": "Kivra AB",
          "orgnr": "SE556840226601"
        }
      ],
      "edit_security_level": 25,
      "groups": [],
      "visibility": "visible"
    }
    

    Properties

    Name Description
    namerequiredstring Name of the Tenant, this name shows up in the Users Inbox
    company_idrequired[CompanyId] No description
    edit_security_levelinteger Security level needed for an enduser to opt_out from this Tenant
    groups[string] List of groups this Tenant belongs to
    visibilitystring Determines if this Tenant is visible for the enduser

    Enumerated Values

    Property Value
    visibility visible
    visibility hidden

    Agreement

    {
      "subject": "Employment agreement",
      "type": "agreement",
      "vat_number": "SE556913262701",
      "original": {
        "name": "agreement1025.pdf",
        "content_type": "application/pdf",
        "data": "REVBREJFRUY="
      },
      "parties": [
        {
          "ssn": "197701032380",
          "name": "Jan-Erik Karlsson",
          "email": "je.karlsson@email.nu",
          "phone": "+46705050505",
          "role": "signer"
        },
        {
          "ssn": "198112172385",
          "name": "Gustav Larsson",
          "email": "gustav123@mymail.com",
          "phone": "+46705212121",
          "role": "delegate"
        }
      ]
    }
    

    Properties

    Name Description
    subjectrequiredstring Name of the agreement
    typerequiredstring the type of content, for agreements always use 'agreement'
    vat_numberrequiredstring The VAT number for the company sending the contract, it will appear on the signature log
    originalrequiredobject No description
    » namestring Name of the document file
    » content_typestring The Iana Media type corresponding to the file, e.g. "application/pdf"
    » datastring(Base64-encoded data) Base64-encoded data for the agreement PDF
    partiesrequired[AgreementParties] list of signers and delegates that are requested to sign the agreement

    AgreementParties

    {
      "ssn": "197701032380",
      "name": "Jan-Erik Karlsson",
      "email": "je.karlsson.hem@email.nu",
      "phone": "+46705050505",
      "role": "signer"
    }
    

    Properties

    Name Description
    ssnstring User's unique SSN, format: YYYYMMDDnnnn
    namestring Name of the user
    emailstring email to be used to contact the user
    phonestring mobile phone to be used to contact the user (via SMS)
    rolestring the role of the user in this signature flow

    Enumerated Values

    Property Value
    role signer
    role delegate

    AgreementStateShort

    {
      "key": "1544707148d73a3e84a216427724637fc207cba2ab",
      "state": "active"
    }
    

    Properties

    Name Description
    keystring unique agreement id
    statestring current state for the agreement

    AgreementStateDetailed

    {
      "created_at": "2019-04-09T13:42:26Z",
      "signatures": [
        {
          "ssn": "197701032380",
          "real_name": "Jan-Erik Karlsson",
          "created_at": "2019-04-12T08:23:29Z",
          "order_ref": "d4ace777-6b91-4172-903e-39371ede89f1"
        },
        {
          "ssn": "198112172385",
          "real_name": "Gustav Johan Larsson",
          "created_at": "2019-04-11T18:53:03Z",
          "order_ref": "f5bce777-0b42-4222-1f3e-ab523ede7a5f"
        }
      ],
      "state": "completed",
      "expires_at": "2019-05-09T13:42:26Z",
      "trashed_at": "2019-05-12T08:23:29Z",
      "parties": [
        {
          "ssn": "197701032380",
          "name": "Jan-Erik Karlsson",
          "email": "je.karlsson.hem@email.nu",
          "phone": "+46705050505",
          "role": "signer"
        },
        {
          "ssn": "198112172385",
          "name": "Gustav Larsson",
          "email": "gustav123@mymail.com",
          "phone": "+46705212121",
          "role": "delegate"
        }
      ],
      "subject": "Employment agreement"
    }
    

    Properties

    Name Description
    created_atstring The time when the agreement was created
    signatures[AgreementSignature] List of signatures
    statestring The current state of the agreement
    expires_atstring The expiration time for the agreement, if the agreement is not completed before this date, it will no longer be available for signature
    trashed_atstring The time when the signed agreement will no longer be available for download or via the API. This field is relevant only when state is "completed"
    parties[AgreementParties] list of signers and delegates that are requested to sign the agreement
    subjectstring Name of the agreement

    Enumerated Values

    Property Value
    state active
    state completed
    state revoked

    AgreementSignature

    {
      "ssn": "191212121212",
      "real_name": "Jan-Erik Karlsson",
      "created_at": "2019-04-12T08:23:29Z",
      "order_ref": "d4ace777-6b91-4172-903e-39371ede89f1"
    }
    

    Properties

    Name Description
    ssnstring Signer's unique SSN, format: YYYYMMDDnnnn
    real_namestring The real name of the signer, as provided by Mobile BankID service
    created_atstring The time when the signature was created
    order_refstring The unique ID of the signature

    CompanyId

    {
      "name": "Kivra AB",
      "orgnr": "SE556840226601"
    }
    

    Properties

    Name Description
    namerequiredstring Legal name of Company
    orgnrrequiredstring Vat number of Company

    File

    {
      "name": "filename.pdf",
      "data": "REVBREJFRUY=",
      "content_type": "application/pdf"
    }
    

    Properties

    Name Description
    namerequiredstring Arbritrary file-name that is shown alongside the File in the Kivra GUI
    datarequiredstring(Base64-encoded data) Base64-encoded data
    content_typerequiredstring The Iana Media type corresponding to the file, e.g. "application/pdf"

    CompanyKey

    {
      "key": "15236156848eefa1dc75364af2be38c98eb3aae223"
    }
    

    Properties

    Name Description
    keystring Company's unique Key

    CompanyInbox

    {
      "key": "15294092505b9cfab3f79d233f8eca6fbc5385fa61",
      "sender": "1341573157b3a133f220f4217b2e32989d2efa015",
      "sender_name": "Kivra",
      "created_at": "2018-06-19T11:54:10Z",
      "subject": "Invoice 4512 from Local Bank",
      "status": "read"
    }
    

    Properties

    Name Description
    keystring Content's unique key
    senderstring Unique key for the tenant that posted the content
    sender_namestring Name of the tenant that posted the content
    created_atstring Date and time when the content was delivered to the recipient
    subjectstring Subject of the content, as set by the sender
    statusstring Whether the content has been read (opened) or not

    Enumerated Values

    Property Value
    status read
    status unread

    CompanyContent

    {
      "sender": "1341573157b3a133f220f4217b2e32989d2efa015",
      "sender_name": "Kivra",
      "created_at": "2018-06-19T11:54:10Z",
      "subject": "Invoice 4512 from Local Bank",
      "receiver_name": "Digital Hero AB",
      "payment": {
        "payable": true,
        "status": "unpaid",
        "currency": "SEK",
        "due_date": "2017-01-01",
        "total_owed": "123.50",
        "type": "SE_OCR",
        "method": "1",
        "account": "12345",
        "reference": "123OCRNUMBER456",
        "variable_amount": false,
        "min_amount": "50.00"
      },
      "parts": [
        {
          "content_type": "application/pdf",
          "checksum": "9209c7eebdd283a4c4bd7555e73e6064",
          "sha256": "287f2fe67a8a76a10169aa6a885d21e1f83416c4831294ea5c4b0a38bda5c78d",
          "size": 163414,
          "body": "<!doctype html>\n<html class=\"....",
          "key": "15118724482475bf32615b4a2aaa604fd66377010e"
        }
      ]
    }
    

    Properties

    Name Description
    senderstring Unique key for the tenant that posted the content
    sender_namestring Name of the tenant that posted the content
    created_atstring Date and time when the content was delivered to the recipient
    subjectstring Subject of the content, as set by the sender
    receiver_namestring Name of the company that received the content
    paymentPayment No description
    parts[Parts] files composing the content

    Parts

    {
      "content_type": "application/pdf",
      "checksum": "9209c7eebdd283a4c4bd7555e73e6064",
      "sha256": "287f2fe67a8a76a10169aa6a885d21e1f83416c4831294ea5c4b0a38bda5c78d",
      "size": 163414,
      "body": "<!doctype html>\n<html class=\"....",
      "key": "15118724482475bf32615b4a2aaa604fd66377010e"
    }
    

    Properties

    Name Description
    content_typestring The Iana Media type corresponding to the file, e.g. "application/pdf"
    checksumstring The cheksum of the document calculated with md5
    sha256string hash of the document calculated with SHA-256
    sizeinteger size of the document in bytes
    bodystring body of the content (present only if content_type is "text/html" or "text/plain")
    keystring The unique key for the content file (present for all content that is not "text/html" or "text/plain")