Making requests against Procountor API
This page details the request and response formats and generic conventions used when accessing Procountor API. The following rules apply to all API endpoints unless otherwise explicitly stated in the API reference.
Request limits
Use of Procountor API is limited to a maximum of 20 requests per second per client on both test and production servers. Exceeding the limit may result in suspending the service for the API client in question. This limit is subject to change.
ID fields
Most resources in the API have a unique identifier (ID). These identifiers are unique within a given company in Procountor but not globally. This means that multiple companies can have invoices, ledger receipts, and other resources with identical identifiers. The things which are unique throughout all Procountor environments are company ID + resource ID tuples.
The ID fields follow the below rules:
- the primary ID field for a resource is named
id
- name of an ID field referencing another resource follows the pattern
resourceTypeId
, whereresourceType
is the type of the referred resource - an empty reference ID has a value of
null
Formats and encoding
Value | Format | Example |
---|---|---|
Date | ISO 8601 | 2017-01-30 |
Datetime | ISO 8601 | 2017-01-30T15:20:00 |
Currency code | ISO 4217 | SEK |
Decimal value | Separated by dot. Scale depends on the field. | 19.2022 |
Any | Encoding: UTF-8 Character set: Windows-1252 |
Not allowed: Ŕ, ೠ, еߙϲ․ |
Values as URL or POST parameters | URL encoded | abc+äö -> abc%2B%C3%A4%C3%B6 |
Request structure
Request types
The Procountor API supports the following RESTful methods. Not all the endpoints support each of the methods listed below. Please consult the API reference for the list of available methods for each endpoint.
GET | Fetch a resource or a collection of resources. |
---|---|
POST | Create a new resource in a collection. |
PUT |
Overwrite a resource in a collection. This method overwrites all the fields of a resource. Execute an action on the resource, e.g. mark an invoice paid. |
PATCH | Update a resource in a collection. This method updates only the specified fields of a resource. |
DELETE | Remove a resource from a collection. |
Headers
All API requests must be authorized using an access token as a bearer token in the authorization header. To get an access token please follow the API authentication guide.
GET https://api.procountor.com/api/sessioninfo HTTP/1.1
Authorization: Bearer <access token>
For API requests including a request body the content type used for the request body must be application/json
.
POST https://api.procountor.com/api/invoices HTTP/1.1
Authorization: Bearer <access token>
Content-Type: application/json
If the request is a file transfer, such as sending an attachment, the correct content type is multipart/form-data
.
POST https://api.procountor.com/api/attachments HTTP/1.1
Authorization: Bearer <access token>
Content-Type: multipart/form-data
Path and query parameters
Path parameters are mandatory and used to access specific resources or subresources. These parameters follow the restrictions set to ID fields and must be alphanumeric.
GET https://api.procountor.com/api/products/123 HTTP/1.1
Authorization: Bearer <access token>
Query parameters are used to limit the contents of requested collections, or control the output in some manner. Most of the query parameters are optional, but some endpoints also require mandatory query parameters. The query parameters must be percent-encoded.
GET https://api.procountor.com/api/businesspartners?name=Yhti%C3%B6 HTTP/1.1
Authorization: Bearer <access token>
Request body
When a request requires a body that body must be a valid JSON document unless stated otherwise. The fields in the JSON document must follow the formats and encoding quidelines below. The syntax and validation rules of these documents is detailed in the API reference. Please read through the reference carefully and note the range and type of valid values and their relations.
Required fields
Some request body fields are required. Value for such fields must be provided by the user or the request will be denied. For example you cannot create a business partner without a name or type.
POST https://api.procountor.com/api/businesspartners HTTP/1.1
Authorization: Bearer <access token>
Content-Type: application/json
{
"name": "Company",
"type": "SUPPLIER"
}
Optional fields
Many of the request body fields are optional. Such fields can be left empty, in which case the resource given in the request is considered not to have the corresponding property. Validations for such a field are only ran if the field has contents. For example invoice rows do not have to contain productId
but if they do that ID must be found from the product registry.
If an optional field is left out when overwriting a resource using PUT
request the value for that field will be removed from the resource in question.
If an optional field is left out when updating a resource with PATCH
request the existing value for the field will not be changed. To remove a value from an optional field with PATCH
request that field must be present and empty (null
) in the request body.
Read only fields
Some request body fields are marked as read only. The value for such fields is automatically generated or assigned by Procountor and can not be defined by the user. If such a field is present in the request body its value must match the existing value in the system.
Response structure
Headers
The responses sent by Procountor API are generally JSON documents and as such have content type set as application/json
.
HTTP/1.1 200 OK
Content-Type: application/json
In case of fetching documents like attachments the content type is multipart/mixed
.
HTTP/1.1 200 OK
Content-Type: multipart/mixed
Response body
The response body contains a JSON document with all the required fields for an resource. The optional fields are present if they have set values. When creating a resource with a POST
request, or updating one with PUT
, the response body will contain the created resource including the values generated for read only fields.
Paging
Most GET endpoints which return collections feature a paging mechanism. There are two optional ways to control the paging:
- using
previousId
to indicate the last resource you have already received - using
size
andpage
to specify the page size and number you want to receive next
With both methods the size
parameter can be used to control the number of resources received with a single call. This parameter often defaults to 50. Note that for the paging to work the filtering and ordering of resources must remain constant between consecutive requests. Please consult the API reference to see which paging mechanisms, if any, are available with what endpoints.
Errors
In case of a failure the API returns HTTP 4xx
error status with an error JSON detailing the error. Common errors include expired authorization and errors with validation. The validation error codes have their own reference page, and the authentication errors, as well as some other common problem cases, are discussed on the troubleshooting page.
HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate: Bearer realm="Procountor API"
{
"errors": [
{
"status": 401,
"message": "Unauthorized"
}
]
}
Webhooks
In addition to regular API endpoints the Procountor API supports also webhooks for push notifications. Currently it is possible to receive webhook notifications for events triggered using the API and requiring two-factor authentication. List of the supported events can be found from the webhooks reference.
Subscribing
In order to subscribe to events you first need to POST
a subscription message to the /api/webhooks
endpoint. The subscription message must include the consuming URL on your server, authentication details, and a list of events you want to subscribe to.
POST https://api.procountor.com/api/webhooks HTTP/1.1
Authorization: Bearer <access token>
Content-Type: application/json
{
"url": "https://service.example.com/procountor/payment_hook",
"authenticationType": "HMAC",
"authenticationMeta": {
"sharedSecret": "T0p_S3kr!t",
"hashFunction": "SHA512"
},
"subscriptions": [
"PAYMENT_UPDATED",
"PAYMENT_DELETED"
]
}
In this request the url
field must contain the URL for your webhook consuming service, and subscriptions
is a list of events you want to receive to this URL. You can register multiple event types to a single webhook but only one webhook for each event type.
The authenticationType
field contains the authentication method used for verifying the event messages. The webhooks support only HMAC
authentication. The authenticationMeta
contains the authentication details, i.e. the webhook specific secret key in sharedSecret
field, and used hash function, for which SHA512
is the only supported value, in hashFunction
field. More about authentication below.
The response for succesful subscription is:
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": 200,
"uuid": "80ef0711-98a2-3a2f-b813-82c59853315e"
}
Where uuid
is the unique identifier for the created webhook. This value is required for both managing the subscription, and for matching received event messages to specific subscriptions.
Authentication
Webhooks are authenticated using HMAC mechanism with SHA-512 hash algorithm. In practice this means that the messages received when an event is triggered contain HMAC signature for the message in X-Accountor-Signature
header. This signature is calculated using the HMAC SHA-512 algorithm and the shared secret given when subscribing to a webhook.
Receiving events
The event messages have the following format:
{
"eventType": "<EVENT_TYPE>",
"webhookUuid": "<UUID>",
"payload": {
"transactionIdentifier": "<transactionId>",
"<primaryId>": "<id>",
"message": "<message>"
},
"meta": {
"version": "20.08",
"timestamp": 1234567890
}
}
In the above message:
eventType
is the type of the triggered eventuuid
is the unique identifier of the webhookpayload
contains the event payload, including<primaryId>
, which is the id of the triggering resource. The name of this field depends on the event type and can be found from the webhooks reference.message
, which contains an event related message, and- optional
transactionIdentifier
, which matches the transaction ID for two-factor authentication, if applicable
meta
has the API version and event timestamp.
An example of a full webhook message matching the subscription above could go as follows:
POST /procountor/payment_hook HTTP/1.1
Host: service.example.com
Content-Type: application/json
X-Accountor-Signature: f1ea0ff9cf85c17f775e5f362cab62121ee3388f0c6aecf40c742d8417407d373e423281408dc1cf047a198c7a35fa14774541891c28d137b1d19f6cb5058353
{
"eventType": "PAYMENT_UPDATED",
"webhookUuid": "80ef0711-98a2-3a2f-b813-82c59853315e",
"payload": {
"transactionIdentifier": "a12b34c56d78e90f",
"paymentId": "12345",
"message": "Payment has been marked paid"
},
"meta": {
"version": "20.08",
"timestamp": 1607962479000
}
}