# API guidelines

# Requests

The Pagero Web API is based on REST principles, where API resources are accessed through HTTPS requests, using the following HTTP verbs:

Verb Description
GET Used for retrieving resources.
POST Used to create new resources.
PUT Used to update/replace resources.
DELETE Used to delete resources.

# Base URL

The base URL for the Pagero Online API is:

https://api.pageroonline.com/

The Pagero Online Web API consists of several “sub APIs”. The name of a sub API will always come right after the base URL:

https://api.pageroonline.com/{sub-API}/

Where {sub-API} is the name of the “sub API”, for example file, document, network etc.


# Versioning

The Pagero Web API uses URL versioning, which means that the API version is present in the URL. Each sub API is versioned individually, which means that the base URL including version for a sub API will be:

https://api.pageroonline.com/{sub-API}/{version}/


# Media types

A media type describes the format of provided data, for example application/json or application/pdf.

In a request, the accepted media type should be put in the Accept header.

In a response, the media type of the response data will be included in the Content-Type header.

The Pagero Online Web API primarily uses the application/json media type for resource representations. However, other media types such as application/pdf, application/png etc. may also be appropriate for some resources.

If the client requests a media type that the API can not provide for a resource, the response code 406 (Not Acceptable) will be returned.

If the client provides data in a media type that the API does not accept, 415 (Unsupported Media Type) will be returned.


# Content type negotiation

In some cases, the API may be able to return content using different media types (application/pdf, application/xml, etc.). In this case, the client should specify the requested media type through the Accept header.

The Accept header may contain a list of media types in priority order and the server will then use the first media type it supports in the response.


# Resources

Resources are represented using JSON (JavaScript Object Notation), media type application/json.

JSON properties use camelcase notation.

In general there are two types of resources, instance resources and collection resources.

Resources that represent a collection are always in plural form.

  • /documents

An instance resource is in most cases a collection resource, where a specific instance of the collection is pointed out by a resource identifier (path parameter).

  • /documents/123

An instance resource may also exist without being part of a collection resource. In this case, the instance resource is expressed in singular form.

  • /current-user

  • /documents/123/presentation

Resource URIs should either use spinal-case (preferred) or lowercase.

# Path parameters

In API specifications, path parameters should use camel case:

  • /documents/{documentIdentifier}

# Resource representations

There may be several different representations of a resource used throughout the API.

For example, different representations may be used for different operations, such that a GET operation returns one representation of a resource, while a PUT operation for the same resource may use another representation.

# Resource ids

A resource is identified by its’ id.

The type of the id should be string, unless there’s a very good reason for using something else.

The format of the id may vary between different APIs and resources.

A resource id should be completely opaque to clients, meaning that clients should never make any assumptions about the structure of a resource id.

# Timestamps and dates

Timestamps should be formatted in UTC according to the ISO 8601 standard.

  • 2021-07-10T18:02:24.343Z

All incoming timestamps and dates that follow the ISO 8601 standard should be accepted. Outgoing dates should be formatted like yyyy-mm-dd and timestamps should be formatted like yyyy-mm-ddThh:mm:ss.fffZ.

# Enums

Properties that have a limited set of possible values that are not expected to change over time should be declared as enums. Important! Changing an enum available in a response message is considered a breaking change. Therefore, if the available enum values are expected to change over time, it's better to not define the property as an enum. The available values should then instead be available in the description and it should also be made clear that the available values may change over time.

Enum values should use PascalCase formatting, like this:

{
  "documentType": "OrderResponse"
}

# Resource references

A resource may have a reference to another resource. If the referenced resource is an instance resource, the reference can either consist of a simple id, like this:

{
  "userId": "123"
}

Or it can consist of a JSON object with a single ‘id’ property, which is the id of the referenced resource. This variant is often used in combination with resource expansion (see below).

{
  "user": {
      "id": "123"
  }
}

# Resource expansion

The expand query parameter can be used to include full versions of referenced resources directly in the response. The parameter should contain a comma-separated list of resource property names that should be fetched together with the requested resource.

For example, consider the following resource:

{
  "document": {
      "id": "123",
      "documentIdentifier": "45354",
      "creatingUser": {
          "id": "432"
      }
  }
}

The following request will retrieve the document resource, along with the referenced user:

GET /documents/123?expand=creatingUser

{
  "document": {
      "id": "123",
      "documentIdentifier": "45354",
      "creatingUser": {
          "id": "432",
          "username": "johndoe",
          "fullname": "John Doe",
          "...": "..."
      }
  }
}

Resource expansion can be used to avoid making unnecessary API requests when it’s known beforehand that a referenced resource will be needed.


# Collection resources

A collection resource will often contain metadata that for example can be used for pagination. This metadata will then be available in the meta object.

This object has the following properties:

Property Description
offset The number of items to skip before starting to collect the result set.
limit The maximum number of items in the collection resource response. Please note that there is always an upper bound to this property which may vary between different APIs and resources.
total The total number of items in the collection.

The actual collection items are available in a property called items. However, if the response contains no metadata, the collection items may be returned as a simple array.

# Example: Collection response with metadata

GET /documents

{
    "meta": {
        "offset": 0,
        "limit": 25,
        "total": 43
    },
    "items": [
        {
          "id": "...",
          "...": "..."
        },
        {
          "id": "...",
          "...": "..."
        }
    ]
}

# Example: Collection response without metadata

[
    {
      "id": "...",
      "...": "..."
    },
    {
      "id": "...",
      "...": "..."
    }
    
]

# Query parameters

Query parameters should use camel case:

  • /documents?searchTerm=foobar

# Pagination

A collection can be paginated using the offset and limit query parameters.


# Sorting

In general, the query parameter sort can be used for sorting on a specific property. The default sort order is ascending and by providing a “-” before the property name, the sort will be descending. The documentation for each resource provides information about which properties that are sortable and which property the collection is sorted on by default.

  • sort=username
  • sort=-createTime

# Errors

If an error occurs, the API will reply with a response containing the appropriate HTTP status code in the 4xx or 5xx range, depending on whether it’s a client or a server error.

The response body will in general contain a single message with the following properties or an array of messages with the properties:

Property Description
technicalMessage A message in English with a technical explanation of the error.
errorCode (optional) An error code for the error. Can be used to provide a more detailed, machine-readable error cause. Possible error codes should be defined for each API resource.
description (optional) A localised description of the error, if applicable.

# HTTP Response Error Codes

Below is a list of the most common HTTP response error codes that may be returned by the API.

Error code Error Description
400 Bad Request There is an issue with how the request was formed. For instance a parameter could have a wrong name or contain invalid data.
401 Unauthorized The provided API key may be wrong or it is not supplied correctly with the request.
403 Forbidden The client is not allowed to access the requested resource.
404 Not found The requested resource was not found. Please make sure the resource exists.
406 Not acceptable The client has requested resource with a media for type that the API can not provide.
409 Conflict There is already a resource with the same criteria. Occurs when the client tries to create a duplicate resource.
412 Pre-condition failed Returned when an ETag is used and the supplied resource is outdated.
415 Unsupported Media Type The client has provided data in a media type that the API doesn’t accept.
500 Internal Server Error An unknown error has occurred on the server. Please contact support if this happens.

# Caching

All responses from the Pagero Web API will provide caching headers, which tell whether the response can be cached or not and for how long the response may be cached.

Below are a number of caching scenarios and their associated cache headers:

Scenario Cache header
Do not store in any cache. Used for sensitive data. Cache-control: no-store
Always re-validate that the resource is fresh. Cache-Control: no-cache
Cache for a specific amount of time (seconds). Cache-Control: max-age=60

# ETags

Some APIs may provide ETags in their responses. Clients should then utilize this in GET, PUT and POST requests in the following way.

# ETags and GET requests

Whenever a client sends a GET request to retrieve a resource, the ETag value of the resource should be provided in the If-None-Match header, if the resource has been previously fetched.

Browsers will in general handle this automatically.

The API will then compare the provided ETag with its’ own ETag, and if they are equal return a 304 Not Modified response.

# ETags and PUT requests

Whenever a client sends a PUT requests to update a resource, the ETag value of the resource should be provided in the If-Match header.

The API will compare the provided ETag with it’s own ETag value for the resource. The resource will then be updated only if the ETags are the same.

If the ETags differ, the client’s version of the resource is outdated and a 412 Precondition failed response will be returned from the API.

# ETags and POST requests

When creating a new instance of a collection resource, it may be important that the collection has not been modified since it was fetched.

In some cases, the API may include an ETag when fetching a collection resource.

This ETag can then be provided in the If-Match header when sending a POST request to ensure that the collection has not been modified.


# Terminology

It’s important to maintain a consistent terminology for resource names across different APIs.

Here is a list of some common API resources:

Resource name Description
user A Pagero user.
company A company. A company is always a customer to Pagero.
companygroup A company group. Used for grouping companies together.
document A business document, like an invoice or an order.
serviceprovider A service provider is an operator for exchanging documents. Companies behind different service providers can exchange documents through service provider interoperability. Pagero is a service provider.
tradingpartner A trading partner is an entity that can send and/or receive documents to/from other trading partners. Trading partners are located behind one (or several) service providers, like for example Pagero. Every Pagero company that can send or receive documents has a related trading partner.