Making API Requests

Everything about making API requests

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 60 requests per second per client on production server. 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, where resourceType 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 and page 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 event
  • uuid is the unique identifier of the webhook
  • payload 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
  }
}