· 8 years ago · May 30, 2018, 01:44 PM
1{
2 "openapi": "3.0.1",
3 "servers": [
4 {
5 "url": "https://api.kivra.com/v1",
6 "description": "Production environment"
7 },
8 {
9 "url": "https://sandbox.kivra.com/v1",
10 "description": "Staging environment"
11 }
12 ],
13 "basePath": "/v1",
14 "schemes": [
15 "https"
16 ],
17 "info": {
18 "title": "Kivra API",
19 "description": "This document is intended for developers and others who are interested in integrating with [Kivra](https://www.kivra.com) to send digital mail. Questions can be sent to [dev@kivra.com](mailto:dev@kivra.com).\n\nIf anything is missing or seems incorrect, please check the [GitHub issues](https://github.com/kivra/developer.kivra.com/issues) for existing known issues or [create a new issue](https://github.com/kivra/developer.kivra.com/issues/new).\n\n### Introduction\nThe Kivra API is organized around [REST](http://en.wikipedia.org/wiki/Representational_State_Transfer). Our API has predictable,\nresource-oriented URLs, and uses HTTP response codes to indicate API errors.\n\nIntegration in its simplest form consists of two steps:\n\n 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\n 2. The second step is to send the contents itself.\n\nThere are also optional steps that explain additional services Kivra provides. Currently these additional integrations exist:\n\n### Inactive Content\nFor 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.\n\n*Note: Usage of inactive content is only allowed in certain specific cases and its usage needs to be regulated in the business relationship between the sender party and Kivra.*\n\n\n## The service\nKivra is a secure digital mailbox tied to your social security number or\nVAT-number to which you receive documents from companies, organizations\nand government agencies that are connected to Kivra. With Kivra you can\nreceive, manage and archive your content wherever you are and on every\nplatform as long as you have an internet connection.\n\nOver one billion window envelopes are sent every year in Sweden alone, so\nby choosing to use Kivra you contribute to a reduced carbon footprint!\n\nKivra acts as a digital postman between Sender and Recipients which is\nalso reflected in the allocation of responsibilities. Concretely, this\nmeans that the Sender is responsible for the design and content whereas\nRecipients are responsible for reading and processing the received content.\n\n\n## Changelog\nWe will list any changes to the current version of the API here.\n\n| Date | Details of changes |\n| ----------- | ---------------------------------------------------------- |\n| 2016-10-14 | Release of Kivra API Version 1 |\n| 2018-04-20 | Clarify [Environments and API Endpoints](#api-endpoints) |\n| 2018-04-27 | Document optional Content-fields and response-headers |\n\n# Terminology\n### User\nAn 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.\n\n### Company\nA 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.\n\n### Recipient\nA Company or a User in the context of being a receiver. Throughout this document Recipient is used to interchangeably mean a User or Company being a receiver.\n\n### Tenant / Partner / Integrator\nTenant is a sender that is integrated with Kivra. They need not be integrated directly, but can go through a partner. This partner is acting as intermediary for the tenant at integration and can handle multiple tenants.\n\n### Content\nThe information sent by Tenants to Recipients, i.e. Documents, Invoices, etc.\n\n### Dormant Recipient\nRecipient 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.\n\n### Grace period\nKivra 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.\n\n### User object\nis a data object that contains all the available information about a user\n\n### Company object\nis a data object that contains all the available information about a company\n\n### Tenant object\nis a data object that contains all the available information about a sender.\n\n### Content object\nis a data object that contains information about the document and the document itself\n\n### Tenant key\nIs 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.\n\n### Metadata\nis 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.\n\n### Json\nJson 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.\n\n# Conventions\n## Date & Time\nKIVRA encodes and decodes all dates and times as [ISO 8601](http://www.w3.org/TR/NOTE-datetime) values. The format looks like YYYY-MM-DDThh:mm:ss.sTZD, example 1970-01-01T23:25:10.0330000+01:00 where:\n\n* YYYY, The year including century\n* MM, Month\n* DD, Day\n* T, Separator\n* hh, Zero-padded hour between 00 and 24 (where 24 is only used to notate midnight at the end of a calendar day)\n* mm, Zero-padded minutes between 00 and 59\n* ss, Zero-padded second between 00 and 60 (where 60 is only used to notate an added leap second)\n* s, one or more digits representing a decimal fraction of a second\n* TZD, Time zone designator (Z or +hh:mm or -hh:mm)\n\n## UTC\nIf 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'.\n\nThe 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).\n\n## Media types\nThe [Iana](http://www.iana.org/assignments/media-types/media-types.xhtml) Media type, e.g. \"application/pdf\"\n\n## UTF-8 encoding\nAll data sent to Kivra needs to be [UTF-8](http://en.wikipedia.org/wiki/UTF-8) encoded.\n\n## Currency\nAll places where currency is specified [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) should be used.\n\n## Country code\nWhere applicable KIVRA uses a country code to determine certain formats. The country code should always be supplied using the [ISO 3166-1](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) alpha-2 two-letter code.\n\n## Email address\nEmail addresses needs to be specified using [E.123](https://en.wikipedia.org/wiki/E.123)\n\n## Phone numbers (mobile, land line)\nAll phone numbers needs to be specified using [E.123](https://en.wikipedia.org/wiki/E.123)\n\n## Identifying users\nKivra 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\".\n\n## VAT identifier\nIn 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.\n\nThe 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.\n\n# Limits\nKivra 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.\n\nOur policies are as follows and are subject to change.\n\n## Content File-size\n1 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.\n\n# Interacting with the API\nAll API access is performed over HTTPS through [api, sandbox].kivra.com and data is sent and received as [JSON](http://www.json.org/). For trying out the API without touching live data we’ve set up a sandbox, reachable through sandbox.kivra.com.\nIn order to ensure data privacy the following choices have been made, to name some that directly impact API workflows:\nUnencrypted 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.\nResources 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.\n\n## API Endpoints\nKivra 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.\n\nKivra 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.\n\n*Please note that we do not recommend managing firewall restrictions by IP address, as the IPs associated with these domains are not static.*\n\n<aside class=\"notice\">\nAll interaction with Kivra's APIs must be done over HTTPS.\n</aside>\n\n### Production environment\nThe API endpoint for the production environment can be found at\n\n`https://api.kivra.com`\n\nIP adresses that may host the API endpoint:\n\n* 5.178.78.52\n* 5.178.78.53\n* 46.21.99.50\n* 46.21.99.51\n\n<aside class=\"notice\">\nThis is the live production environment, for testing, please use Sandbox.\n</aside>\n\n### Sandbox environment\nThe API for the sandbox environment can be found at\n\n`https://sandbox.kivra.com`\n\nIP adresses that may host the Sandbox endpoint:\n\n* 104.199.61.8\n\n<aside class=\"warning\">\nThis is not to be used with any critical or production data. We make no guarantees as to the availability of the service, or the data stored by it.\n</aside>\n\n*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.*\n\n## URL Components\nWhen constructing resource identifiers (URIs) it is best to consider them as being built with up to four discrete units.\n\n### Endpoint\n`https://TYPE.kivra.com/VERSION`\n\n### Tenant resource\n`/tenant/TENANTKEY`\n\n### Parameters\n`/?QUERYSTRING`\n\n## Unit Fields\nThe units have parameterized fields, which allow you to change their respective meanings, those fields are briefly described below.\n\n### TYPE\n`sandbox` for development and test or `api` for production purposes.\n\n### VERSION\nCurrent and only API version is `v1.`\n\n### KEY\nThe identifier of an object in a collection, its ID, if you will.\n\n### QUERYSTRING\nA set of key-value pairs, used for filtering and setting options on collections.\n\n## HTTP Verbs\nWhere possible, the KIVRA API strives to use appropriate HTTP verbs for each action. The terms verb and method are used interchangingly.\n\n### Idempotency\nThe 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.\n\n`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.\n\nIn 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.\n\n## Methods\nRead more about [HTTP/1.1 Method Definitions](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html).\n\n| Method | Details |\n| ----------- | ---------------------------------------------------------- |\n| 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 |\n| POST | Used for creating resources, or performing custom or batch type actions |\n| 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 |\n| 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 |\n\n# Resource Types\nThere are two main types of resources – objects and collections of objects, they are individually outlined in the following sections.\nIt 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.\n\n## Object Resources\nObjects are mostly real-world things, such as a user, tenant to name a few, but they can also be abstract things, like a sendrequest.\n\nAn example: */v1/tenant/13443459078e31ba8630e2e9842906c7baf38b131e*\n\n### Allowed Methods\n**GET**\nRead the representation of an object as it is accessible and viewable by you.\n\n**PUT**\nUpdate the object. If the object doesn’t already exist, it is created.\n\n**PATCH**\nUpdate the object with the specified attributes. If the object doesn’t already exist, it is created.\n\n**DELETE**\nIrreversably delete the designated resource from the entire system. This operation will in most cases be illegal for regular API consumers.\n\n## Collection Resources\nCollections 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).\n\nWhen 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.\n\nAn example: */v1/tenant*\n\n### Allowed Methods\n**GET**\nList objects under the Collection, either all or using filters to search.\n\n**POST**\nCreate a new object under the Collection.\n\n## Filters and Flags\nIn 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.\n\n### Filters\nWhen 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`\n\n### Flags\nAs 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.\n\n**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.\n\n# Integration\n## User types\nOpt-out\nKivra 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.\n\n### Meaning of Opt-out for:\n#### Tenant\nCan start sending Content to all Recipients in Kivra\nWhen 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.\nA 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.\n\n#### Recipients\nRecipients will automatically start receiving Content from new Tenants\nRecipients 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.\n\n## Step 1: Synchronize Recipients\nThe 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.\n\nThis means that for each Tenant the Recipient-request is unique and therefore partners integrating many Tenants need to keep track of the different Recipients for each of the separate Tenants.\n\nSynchronization of Recipients is done via the [User Resource](#list_users)\n\n## Step 2: Send Content\nMetadata 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.\n\nSending of Content is done via the [Tenant Content Resource](#send_content)\n\n# Errors\nKivra 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).\n\n## Error handling\nThe 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.\n\n### Recipient-file synchronization:\nCommon errors that can occur and need to be handled gracefully.\n\n* Network problem that hinders the integrator from communicating with Kivra\n* Problem on Kivra’s end that hinders the integrator from querying the state of **Recipients**\n\nThese 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.\n\n### Content Delivery:\nCommon errors that can occur and need to be handled gracefully.\n\n* Network problem that hinders the integrator from communicating with Kivra resulting in either not being able to reach Kivra or a non-successful response-code\n* Problem with the **input**-file either due to above(network problem) or other such as corrupt data or invalid metadata.\n\n## Error Messages\nWhen the KIVRA API returns error messages, it does so in a extended JSON format.\n\n> ### Example error response\n\n```bash\n{ \"code\" : 40400\n, \"short_message\" : \"Resource not found\"\n, \"long_message\" : \"There's no resource at the given URI.\"\n}\n```\n\n### An error has four properties:\n\n| Property | Description |\n| ------------- | ---------------------------------------------------------- |\n| code | The Kivra [error code](#error-codes) |\n| short_message | A short description of the error |\n| long_message | A longer and more verbose error message |\n\n## Error codes\nIn 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:\n\n| Code | Short Message | Long Message |\n| ---- | ------------- | ------------ |\n|40000 |Invalid Token |Could not authenticate with OAuth2 using the supplied token |\n|40001 |Invalid Request |The request was invalid |\n|40002 |Redirect URI Mismatch |The redirect_uri does not match the registered redirect_uri |\n|40003 |Email adress in use |The email adress supplied is already in use |\n|40004 |Already registered |This user is already registered |\n|40005 |Error in phonenumber |The request can't be processed due to phonenumber not meeting the required format |\n|40006 |Error in password |The request can't be processed due to password not meeting the required format |\n|40007 |Error in email |The request can't be processed due to email not meeting the required format |\n|40008 |Unprocessable Entity |The JSON payload was malformed. The client should not resend the same payload without first correcting the erroneous JSON payload. |\n|40009 |Error in SSN |The request can't be processed due to SSN not meeting the required format. |\n|40010 |No action supplied or invalid |The action parameter was not supplied or invalid. |\n|40011 |Failed Extended Validation |The request can't be processed due to SSN and/or mobile failed extended validation. |\n|40100 |Unauthorized |Supplied credentials was invalid |\n|40101 |Access Denied |The resource owner or authorization server denied the request |\n|40102 |Unauthorized Client |The client is not authorized to request an authorization code using this method. |\n|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. |\n|40104 |Invalid Client |Client authentication failed (e.g. unknown client, no client authentication included, or unsupported authentication method). |\n|40105 |Invalid Sendrequest |No sendrequest exists between sender and receiver, or sendrequest is not accepted. |\n|40106 |Email in use |This email adress is already in use and can not be used. |\n|40108 |Registration Code or Sendrequest Invalid |The Registration Code is invalid or no Sendrequest exists or has been expired. |\n|40300 |Forbidden |Access was denied to the given resource, authenticating will make no difference |\n|40400 |Not found |The resource was not found at the given URI at this time |\n|40500 | Method Not Allowed | The method specified in is not allowed for the resource at the requested URI |\n|40601 | Invalid Accept Header | The Accept Header contains a non valid or unknown Content-Type |\n",
20 "version": "v1"
21 },
22 "tags": [
23 {
24 "name": "Tenant",
25 "description": "Tenant endpoint"
26 }
27 ],
28 "paths": {
29 "/tenant": {
30 "post": {
31 "tags": [
32 "Tenant"
33 ],
34 "summary": "Create Tenant",
35 "operationId": "Create Tenant",
36 "description": "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.\n",
37 "security": [
38 {
39 "oAuth2Client": [
40 "post:kivra.v1.tenant.{tenantKey}"
41 ]
42 }
43 ],
44 "responses": {
45 "201": {
46 "description": "Tenant Created succesfully\n",
47 "content": {
48 "application/json": {
49 "schema": {
50 "$ref": "#/components/schemas/Tenant"
51 }
52 }
53 },
54 "headers": {
55 "kivra-objkey": {
56 "description": "Object Key",
57 "schema": {
58 "type": "string",
59 "format": "hexadecimal value"
60 }
61 },
62 "location": {
63 "description": "URL to created Object",
64 "schema": {
65 "type": "string",
66 "format": "url"
67 }
68 }
69 }
70 }
71 },
72 "requestBody": {
73 "content": {
74 "application/json": {
75 "schema": {
76 "$ref": "#/components/schemas/Tenant"
77 }
78 }
79 }
80 }
81 }
82 },
83 "/tenant/{tenantKey}/user": {
84 "get": {
85 "tags": [
86 "Tenant"
87 ],
88 "summary": "Resource to list available users for a Tenant",
89 "operationId": "List Users",
90 "description": "This resource is used to list all or search for users that eligible for receiving Content from the specific Tenant.\nThe response is a JSON list of Objects containing the User’s key and SSN.\n\n<aside class=\"notice\">\nIf a search is done and the User doesn’t exist or have Opt-ed out of receiving Content from the Tenant an empty list will be returned.\n</aside>\n",
91 "parameters": [
92 {
93 "name": "tenantKey",
94 "in": "path",
95 "description": "The unique Key for a Tenant",
96 "required": true,
97 "schema": {
98 "type": "string",
99 "format": "hexadecimal"
100 }
101 },
102 {
103 "name": "ssn",
104 "in": "query",
105 "description": "Perform a search to see if a specific User is available",
106 "required": false,
107 "schema": {
108 "description": "User's unique SSN",
109 "type": "string"
110 }
111 }
112 ],
113 "security": [
114 {
115 "oAuth2Client": [
116 "get:kivra.v1.tenant.{tenantKey}.user"
117 ]
118 }
119 ],
120 "responses": {
121 "200": {
122 "description": "List of available users\n",
123 "content": {
124 "application/json": {
125 "schema": {
126 "type": "array",
127 "description": "List of available users, can be empty",
128 "items": {
129 "$ref": "#/components/schemas/User"
130 }
131 }
132 }
133 }
134 }
135 }
136 }
137 },
138 "/tenant/{tenantKey}/company": {
139 "get": {
140 "tags": [
141 "Tenant"
142 ],
143 "summary": "Resource to list available companies for a Tenant",
144 "operationId": "List Companies",
145 "description": "This resource is used to list all or search for companies that eligible for receiving Content from the specific Tenant.\nThe response is a JSON list of Objects containing the Companies key and Vat Number.\n\n<aside class=\"notice\">\nIf a search is done and the Company doesn’t exist or have Opt-ed out of receiving Content from the Tenant an empty list will be returned.\n</aside>\n",
146 "parameters": [
147 {
148 "name": "tenantKey",
149 "in": "path",
150 "description": "The unique Key for a Tenant",
151 "required": true,
152 "schema": {
153 "type": "string",
154 "format": "hexadecimal"
155 }
156 },
157 {
158 "name": "vat_number",
159 "in": "query",
160 "description": "Perform a search to see if a specific Company is available",
161 "required": false,
162 "schema": {
163 "description": "Companies unique Vat Number",
164 "type": "string"
165 }
166 }
167 ],
168 "security": [
169 {
170 "oAuth2Client": [
171 "get:kivra.v1.tenant.{tenantKey}.company"
172 ]
173 }
174 ],
175 "responses": {
176 "200": {
177 "description": "List of available companies\n",
178 "content": {
179 "application/json": {
180 "schema": {
181 "type": "array",
182 "description": "List of available companies, can be empty",
183 "items": {
184 "$ref": "#/components/schemas/Company"
185 }
186 }
187 }
188 }
189 }
190 }
191 }
192 },
193 "/tenant/{tenantKey}/content": {
194 "post": {
195 "tags": [
196 "Tenant"
197 ],
198 "summary": "Send Content",
199 "operationId": "Send Content",
200 "description": "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.\n\n#### Minimum Metadata\nAs a minimum a valid `ssn` or `vat_number` is required.\n\n<aside class=\"notice\">\nNote: Kivra will reject Content using both `ssn` and `vat_number` in the same metadata as this is ambiguous.\n</aside>\n\n#### Inactive Content\nAn 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.\n\n<aside class=\"notice\">\nNote: Usage of inactive content is only allowed in certain specific cases and its usage needs to be regulated in the business relationship between the sender party and Kivra.\n</aside>\n\nSending inactive Content uses all the same attributes as a normal Content with the difference for some additional metadata-attributes.\nBy 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.\n\nIf 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.\n",
201 "security": [
202 {
203 "oAuth2Client": [
204 "post:kivra.v1.tenant.{tenantKey}.content"
205 ]
206 }
207 ],
208 "parameters": [
209 {
210 "name": "tenantKey",
211 "in": "path",
212 "description": "The unique Key for a Tenant",
213 "required": true,
214 "schema": {
215 "type": "string",
216 "format": "hexadecimal"
217 }
218 }
219 ],
220 "responses": {
221 "201": {
222 "description": "Content Created succesfully\n",
223 "content": {
224 "application/json": {
225 "schema": {
226 "$ref": "#/components/schemas/Content"
227 }
228 }
229 },
230 "headers": {
231 "kivra-objkey": {
232 "description": "Object Key",
233 "schema": {
234 "type": "string",
235 "format": "hexadecimal value"
236 }
237 },
238 "kivra-retained": {
239 "description": "Boolean denoting if a Content was Retained, Note: this header is **only** returned when a Content is retained\n",
240 "schema": {
241 "type": "boolean"
242 }
243 },
244 "location": {
245 "description": "URL to created Object",
246 "schema": {
247 "type": "string",
248 "format": "url"
249 }
250 }
251 }
252 }
253 },
254 "requestBody": {
255 "content": {
256 "application/json": {
257 "schema": {
258 "$ref": "#/components/schemas/Content"
259 }
260 }
261 }
262 }
263 }
264 }
265 },
266 "components": {
267 "schemas": {
268 "Content": {
269 "type": "object",
270 "required": [
271 "ssn",
272 "vat_number"
273 ],
274 "properties": {
275 "ssn": {
276 "description": "User's unique SSN, format: `YYYYMMDDnnnn`\n",
277 "type": "string",
278 "writeOnly": true,
279 "example": "191212121212"
280 },
281 "vat_number": {
282 "description": "A valid VAT-identifier, Swedish format: `SE[xxxxxxxxxx]01`\n",
283 "type": "string",
284 "readOnly": true,
285 "writeOnly": true,
286 "example": "SE556840226601"
287 },
288 "subject": {
289 "description": "This Subject/Title will be visibile in the Recipients Inbox.",
290 "type": "string",
291 "example": "Sample Invoice"
292 },
293 "generated_at": {
294 "type": "string",
295 "format": "ISO8601",
296 "example": "2016-12-12",
297 "description": "Optional attribute which denotes when a specific Content was generated at the tenant/partner’s site. Kivra will sort on this in the user interface which effectively makes it possible for a tenant or partner to control the sorting in the user interface.\n"
298 },
299 "retain": {
300 "description": "Boolean denoting if Kivra should try and retain this Content if it can’t be delivered. Default `false`\n",
301 "type": "boolean",
302 "writeOnly": true,
303 "readOnly": true,
304 "example": true
305 },
306 "retention_time": {
307 "description": "How long to retain a Content. Supported values: `\"30\"` and `\"390\"`\n",
308 "type": "string",
309 "writeOnly": true,
310 "readOnly": true,
311 "example": "30"
312 },
313 "tenant_info": {
314 "description": "An arbitrary string defined by the tenant, used to group content for administrative tasks\n",
315 "type": "string",
316 "writeOnly": true,
317 "readOnly": true
318 },
319 "files": {
320 "description": "Array of file Objects",
321 "type": "array",
322 "writeOnly": true,
323 "items": {
324 "$ref": "#/components/schemas/File"
325 }
326 },
327 "context": {
328 "type": "object",
329 "writeOnly": true,
330 "readOnly": true,
331 "description": "Optionally specify payment information",
332 "properties": {
333 "invoice": {
334 "type": "object",
335 "properties": {
336 "payment": {
337 "type": "object",
338 "required": [
339 "payable",
340 "currency",
341 "due_date",
342 "total_owed",
343 "type",
344 "method",
345 "account",
346 "reference"
347 ],
348 "properties": {
349 "payable": {
350 "type": "boolean",
351 "description": "Toggles whether this Content is to be payable through Kivra’s payment platform"
352 },
353 "status": {
354 "type": "string",
355 "description": "Toggles whether this content is paid or unpaid: if already paid the user can’t pay it again through Kivra",
356 "enum": [
357 "paid",
358 "unpaid"
359 ]
360 },
361 "currency": {
362 "type": "string",
363 "format": "ISO4217",
364 "example": "SEK",
365 "description": "Currency used in specifying total_owed"
366 },
367 "due_date": {
368 "type": "string",
369 "format": "ISO8601",
370 "example": "2017-01-01",
371 "description": "Date when this Invoice is due"
372 },
373 "total_owed": {
374 "type": "string",
375 "format": "float",
376 "example": "123.50",
377 "description": "The total amount owed according to the invoice. **If payable equals true this must be a non negative number that’s greater than \"0\"**"
378 },
379 "type": {
380 "type": "string",
381 "description": "Type of format for the reference",
382 "example": "SE_OCR",
383 "enum": [
384 "SE_OCR",
385 "TENANT_REF"
386 ]
387 },
388 "method": {
389 "type": "string",
390 "description": "1 = BG and 2 = PG",
391 "example": "1",
392 "enum": [
393 "1",
394 "2"
395 ]
396 },
397 "account": {
398 "type": "string",
399 "example": "12345",
400 "description": "Tenant’s account number"
401 },
402 "reference": {
403 "type": "string",
404 "example": "123OCRNUMBER456",
405 "description": "The reference number used for paying"
406 }
407 }
408 },
409 "invoice_reference": {
410 "type": "string",
411 "description": "Tenant’s own Invoice Reference",
412 "example": "Invoice Nr #123"
413 }
414 }
415 }
416 }
417 }
418 }
419 },
420 "Company": {
421 "type": "object",
422 "properties": {
423 "key": {
424 "description": "Company's unique Key",
425 "type": "string",
426 "example": "15236156848eefa1dc75364af2be38c98eb3aae223"
427 },
428 "vat_number": {
429 "description": "Company's unique Vat Number",
430 "type": "string",
431 "example": "SE556840226601"
432 }
433 }
434 },
435 "User": {
436 "type": "object",
437 "properties": {
438 "key": {
439 "description": "User's unique Key",
440 "type": "string",
441 "example": "15236156848eefa1dc75364af2be38c98eb3aae223"
442 },
443 "ssn": {
444 "description": "User's unique SSN in the form `YYYYMMDDnnnn`",
445 "type": "string",
446 "example": "191212121212"
447 }
448 }
449 },
450 "Tenant": {
451 "type": "object",
452 "required": [
453 "name",
454 "company_id"
455 ],
456 "properties": {
457 "name": {
458 "description": "Name of the Tenant, this name shows up in the Users Inbox",
459 "type": "string",
460 "example": "Kivra"
461 },
462 "company_id": {
463 "type": "array",
464 "items": {
465 "$ref": "#/components/schemas/CompanyId"
466 }
467 },
468 "edit_security_level": {
469 "description": "Security level needed for an enduser to `opt_out` from this Tenant",
470 "type": "integer",
471 "readOnly": true,
472 "example": 25
473 },
474 "groups": {
475 "type": "array",
476 "readOnly": true,
477 "description": "List of groups this Tenant belongs to",
478 "example": [
479
480 ]
481 },
482 "visibility": {
483 "description": "Determines if this Tenant is visible for the enduser",
484 "type": "string",
485 "readOnly": true,
486 "enum": [
487 "visible",
488 "hidden"
489 ]
490 }
491 }
492 },
493 "CompanyId": {
494 "type": "object",
495 "required": [
496 "name",
497 "orgnr"
498 ],
499 "properties": {
500 "name": {
501 "description": "Legal name of Company",
502 "type": "string",
503 "example": "Kivra AB"
504 },
505 "orgnr": {
506 "description": "Vat number of Company",
507 "type": "string",
508 "example": "SE556840226601"
509 }
510 }
511 },
512 "File": {
513 "type": "object",
514 "required": [
515 "name",
516 "data",
517 "content_type"
518 ],
519 "properties": {
520 "name": {
521 "description": "Arbritrary file-name that is shown alongside the File in the Kivra GUI",
522 "type": "string",
523 "example": "filename.pdf"
524 },
525 "data": {
526 "description": "Base64-encoded data",
527 "type": "string",
528 "format": "Base64-encoded data",
529 "example": "REVBREJFRUY="
530 },
531 "content_type": {
532 "description": "The [Iana](http://www.iana.org/assignments/media-types/media-types.xhtml) Media type corresponding to the file, e.g. \"application/pdf\"",
533 "type": "string",
534 "example": "application/pdf"
535 }
536 }
537 }
538 },
539 "securitySchemes": {
540 "oAuth2Client": {
541 "type": "oauth2",
542 "description": "Kivra supports Oauth2 with Client Credentials flow. Each client has a `client_id` and a `client_secret` and these need to be base64 encoded and sent to the API via POST to receive an access token which is used for subsequent calls.\n\n> 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)\n\n```bash\n$ echo -n 'client_id:client_secret' | base64\nY2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=\n```\n\n> Then perform the authentication which will respond with an access token.\n\n> ### REQUEST: Authentication\n\n```bash\ncurl -i -X POST https://api.kivra.com/v1/auth \\\n -d \"grant_type=client_credentials\" \\\n -H \"Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=\"\n```\n\n> ### RESPONSE: Authentication\n\n```bash\nHTTP/1.1 200 OK\nServer: nginx\nDate: Thu, 02 Oct 2014 12:43:25 GMT\nContent-Type: application/json\nContent-Length: 124\nConnection: keep-alive\nVary: Accept-Encoding\nStrict-Transport-Security: max-age=31536000;\n\n{\n \"state\":\"\",\n \"access_token\":\"H6Zq08rF5fjQttd6fTKepWb3FQNptcip\",\n \"expires_in\":28800,\n \"scope\":\"kivra.v1.tenant.{tenant-key}.*\",\n \"token_type\":\"bearer\"\n}\n```\n\n<aside class=\"notice\">\nAn access_token is valid for eight(8) hours.\n</aside>\n\nA 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.\n\n<aside class=\"warning\">\nNote: Client Credentials and Access Tokens needs to be treated securely, It is how you securely identify your application's rights and identity when accessing the Kivra API. Do not distribute Client Credentials or Access Tokens in email, distributed native applications, client-side javascript, or public code repositories.\n</aside>\n\n> ### Example request with `access_token`\n\n```bash\ncurl -i -X GET -H \"Authorization: token <access_token>\" <api-url-to-object>\n```\n## Authorization with limited access scope\n\nIn 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.\n\nTo retrieve this access token, the client performs a new authorization with some extra parameters specifying the limited scope.\n\n```shell\ncurl -X POST \\\n https://api.kivra.com/v1/auth \\\n -d grant_type=client_credentials \\\n -d scope=post:kivra.v1.tenant.{tenant-key}.content \\\n -H \"Authorization: Basic {base64-auth}\"\n```\n\n> The answer will look like the following:\n\n```json\n{\n \"state\": \"\",\n \"access_token\": \"DMWmtGWe9YpXep6FTgVEwWttxLR6D53z\",\n \"expires_in\": 28800,\n \"scope\": \"post:kivra.v1.tenant.{tenant-key}.content\",\n \"token_type\": \"bearer\"\n}\n```\n### Scope\nScopes are specified as one or a commaseparated list of methods with a path appended and separated by `:`.\n\nMethod is a lower case string of one or more of the allowed methods, valid examples:\n\n| Example | Details |\n| ----------- | ---------------------------------------------------------- |\n| `post:path` | Allows `POST` for the given path |\n| `get,put:path` | Allows `GET` and `PUT` for the given path |\n\nPath is a lower case string starting with the keyword `kivra` and the path appended and interspersed with `.` instead\nof the path-separator `/` such as: `kivra.v1.example`. There is also the possibility to use wildcards:\n\n| Wildcard | Details |\n| ----------- | -------------------------------------------------------------- |\n| `*` | Marks a scope as valid for *any* keyword on **current-level** |\n| `**` | Marks a scope as valid for *any* keyword on **current-level** and **recursively** |\n",
543 "flows": {
544 "clientCredentials": {
545 "authorizationUrl": "https://api.kivra.com/v1/auth"
546 }
547 }
548 }
549 }
550 }
551}