Plugboard REST API Developer Guide

Welcome to Plugboard API developer manual pages.

Introduction

Plugboard REST API reference

This document explains some of the basic concepts of the Plugboard API such as Terminology and Authentication. Read the whole document before you start using the API. There are a lot of useful information that is necessary when creating an integration.

The Plugboard REST API reference has a complete set of documented endpoints. The document contains detailed information about query parameters, model schema, response codes and error messages. The document also provides tools to interact with the API directly from your browser window.

Entering user credentials in the top bar and you can issue queries to the API through the “Try now!” button. It’s a great way to get started with the Plugboard API.

Support

If you have questions or feedback, please send an email to api@sharespine.com. If you have a support request, it is important to supply verbose information about what you want to achieve together with requests and response information. Then our technicians have as much information as possible to reproduce and answer your ticket.

Terminology

In order to understand references to specific parts and concept of Plugboard and Plugboard API here are explanations of common words;

Tenant
A top level account belonging to a customer (most often a company).
User
A person logging into Plugboard (a tenant can have one or more users).
Connector
A system integration to a specific remote system. Example of a connector is an e-commerce system, erp or any another system that is supported.
Connection
An instance of a system integration (there can be more than one connection per connector). Example of a connection can be a specific e-commerce site or erp account.
Plug
A specific connection import or export channel (there can be more than one plug per connection). Example of a plug can be “export orders”
Export
The term export is used from the perspective of plugboard. You can export data from plugboard.
Import
The term import is used from the perspective of plugboard. You can import data to plugboard.
Remote system
A remote system is any system that is connected through a "connection". This can be a system using our API-connector or any of our supported connectors e.g erp or e-commerce.

Basics of the REST API

Protocol

The application protocol used is HTTP 1.1 as defined in RFC 2616. HTTP/2 (RFC 7540) is not supported at the moment. Neither is HTTP 1.0 or 0.9.

Clients MUST use SSL/TLS encryption (HTTPS) when accessing the API.

Clients MUST NOT ever use plain unencrypted http as this can result in authentication details being exposed.

HTTP supports a number of methods (commands) that are used by this API:

GET
This verb is used to retrieve a resource. GET requests MUST NOT contain a request body. The server will either provide the data requested or an error.
PUT
This verb is used to change an existing object.
POST
This verb is used to create a new object.
DELETE
This verb is used to remove an object.

In the resource documentation below each resource will have a description of the allowed HTTP methods, what data is expected and what will be returned.

Encoding

Requests to the API MUST be UTF-8 encoded.
Responses from the API are UTF-8 encoded.

Authentication

Due to the usage of HTTP Basic Auth it is REQUIRED that SSL/TLS (HTTPS) be used! The server will reject accesses using HTTP only, however this may still cause client credentials to be exposed unencrypted!

Therefore it is vital that clients NEVER use plain HTTP!

Authentication is achieved using HTTP Basic Auth with a few special HTTP headers. These headers are used to specify which API configuration is to be used. The API MUST be configured before use.

X-Tenant
this HTTP header specifies your tenant code name.
X-ConnectionId
this HTTP header specifies the connection ID of the API connection configuration used.
Authorization
is the username and password provided as HTTP Basic Auth. The header should contain the word Basic word followed by a space and a base64-encoded string username:password.

Example:

            
  X-Tenant: tnt
  X-ConnectionId: 72b7568eb7e165e34e00c489542a0008
  Authorization: Basic dXNlcjp0ZXN0
            
          
  • Authorization headers content MUST be encoded as UTF-8 BEFORE base64 encoding.
  • Clients SHOULD use the "API Root" resource to test user credentials and get information about the API.
  • The API MUST be configured before use. See Create API connection for information on how to get the credentials.

API-URL

The API base URL for this environment is: https:///api.

Example endpoint: https:///api/order/

User-Agent

The User-Agent header is not required, however it is recommended that one is provided containing your application name and possibly some contact information. Sending this information will aid in debugging.

Clients sending the user-agent header MUST ensure it is correctly formatted according to RFC 2616.

If the client wishes to provide an app name and a contact email address it MUST be encoded as follows since @-chars are not allowed everywhere in User-Agent headers.

Example:

            
  User-Agent: my-app/1.0 (test@example.com)
            
          

Local and remote ID's

ID's are local or remote in relation to Plugboard.

A localId is the ID WITHIN plugboard, and NOT an ID provided by the client. API users cannot change or provide localIds, these are the sole responsibility of Plugboard. API clients MAY use localId's as references, since they are stable.

A remoteId is an id supplied by a remote system, for example the API user. The ID's are supplied in two forms:

remoteId
contains the remoteId provided by the current API connection. This property can be changed by the API user, however it MUST be unique per "connectionId" and object type.
remoteIdMap
property provides a map of all remoteId’s associated with the object. The ID’s are keyed by the connection id of the connection that provided them.
Example:
                
  {
    "remoteId":"banan",
    "remoteIdMap":{
      "5377568eb7e165e3b38af6eece4a0001":{
        "connectionId":"5377568eb7e165e3b38af6eece4a0001",
        "remoteId":"/product/26/variant/46"
      },
      "2cd2568eb7e165e3b38b30b3e8c40003":{
        "connectionId":"2cd2568eb7e165e3b38b30b3e8c40003",
        "remoteId":"flarfennugel"
      },
      "4485568eb7e165e3b1bcbb4cc57b0001":{
        "connectionId":"4485568eb7e165e3b1bcbb4cc57b0001",
        "remoteId":"banan"
      }
    }
  }
                
              

Errors

Errors are signalled in two ways:

Firstly, all errors are signalled using the appropriate HTTP error codes, as defined in RFC 2616.

The body of the error response is a JSON document with more details about the error. The document contains these fields:

error
This field is ALWAYS set to 'true'.
time
The server time formatted as dateTime when the error occurred.
code
A numeric error code denoting the type of error.
message
A textual error message.

Example - error might look like this:

            
  {
    "error":true,
    "time":"2019-06-05T06:58:34Z",
    "code":100002,
    "subCode":101019,
    "message":"Field testfield cannot be ordered by",
    "defaultMessage":"Field testfield cannot be ordered by",
    "field":"field",
    "fieldValue":"unsortableField",
    "helpText":null,
    "class":"record.product.proto.ProductError$ProductFieldNotSortable"
  }
            
          

A list of all error codes can be downloaded here: errors.json

However keep in mind that the message texts listed are only the defaults. The messages are usually elaborated when generating the error to provide more information.

Query

Some endpoints have support for query e.g POST /product/query. The query is send as a json object in the request body. See the complete specification in the API-reference documentation.
The query consist of a filter which can contain a search for a specific field OR it can be an "and/or"-operator which contain a list of other filters. The API-reference will define availble fields for a specific endpoint.

Example of a filter that filters on lastModified

This filter will return records number 11-20 where lastModified is greater than "2015-01-02T03:04:05Z" and the result is ordered in an ascending order based on the field lastModified. Note: The list will also contain products that is deleted since the default for deletedFlag is "both". The value must have a type that matches the field that is used in the filter.

          
  {
    "filter": {
      "type": "gt",
      "field": "lastModified",
      "value": {
        "type": "datetime",
        "value": "2015-01-02T03:04:05Z"
      }
    },
    "order": [
      {
        "field": "lastModified",
        "direction": "ascending"
      }
    ],
    "numRecords": 10,
    "offset": 10
  }
          

Example of a filter that contains subclauses

This filter will get records where lastModified is greater than "2015-01-02T03:04:05Z" OR if the field sku is equal to 1001.

The maximum returned records is set by the numRecords. The default value will be used if the values is not present in the body.

  {
    "filter": {
      "type":"or",
      "subclauses":[
        {
            "type": "gt",
            "field": "lastModified",
            "value": {
              "type": "datetime",
              "value": "2020-12-22T06:24:57Z"
            }
        },
        {
            "type": "eq",
            "field": "sku",
            "value": {
              "type": "str",
              "value": "1001"
            }
        }
      ]
    }
  }
          

Get Started

Create API connection

The API needs to be enabled in plugboard. The setup is the same as for any other integration in Plugboard. The first step is to setup a system integration of the type Plugboard API. The integration is added in the admin area for "My Plugboard". The login details you get will allow access to the Plugboard API for a given tenant.

Follow the steps below:
  1. Login to My Plugboard (https://my.plugboard.io)
  2. Go to System integrations -> Settings
  3. Click on Add system integration
  4. Choose Plugboard API as System
  5. Enter a name e.g. "API"
  6. Click on API Credentials
  7. Copy value of field X-ConnectionId and X-Tenant
  8. Click Save
  9. A new widget will appear underneath

Parameters

X-tenant
is the tenant name. You can see it under API Credentials
X-ConnectionId
is a unique id for the API-connection. You can see it under API Credentials
username
is the username for the user that you want to use for the API calls. It is recommended that you have a specific user for the API.
password
is the login password for the user you selected.

Read more about in the section Authentication
This value is to be used in the top bar of API-reference (together with the other three regular authentication details). See: API-reference documentation

Check Connection

Test the credentials by accessing the root API-endpoint https://api.plugboard.io/api/. Expected response should have HTTP Status Code: 200 and contain some meta data for the API-connection.

With the API-reference page

Test with swagger on the API-reference page.

  1. Click in Authorize and make sure to authorize all Available authorizations.
  2. Go to API Root, click on Try it out
  3. Click on Execute button.

With curl

Test the endpoint with curl.

            
  curl --location --request GET 'https://api.plugboard.io/api/' \
  --header 'X-ConnectionId: {connectionId}' \
  --header 'X-Tenant: {your tenant}' \
  --header 'Authorization: {Base64(username:password)}'
            
          

Basic types

Field rules (input)

When receiving fields from client side Plugboard applies the following logic:

Field is not set
No change, Plugboard keeps current value as is.
Field is set to null
Plugboard null:s the field and will not display it in responses or as null in future.
Field is set to value (including empty string)
Plugboard sets the field to the assigned value.

Field rules (output)

If Plugboard don't have value it will output either no field or field with null value.

Fields with empty strings are only outputted if field is of type string and field has value and is explicitly an empty string.

Decimal values

Decimal values (like amounts etc.) MUST be encoded as an JSON string, not as a float/double. This is to avoid rounding and precision issues that can arise with floats:

Like so:


  {
    "amount": "4.2"
  }
          

and NOT like so:

            
  {
    "amount": 4.2
  }
            
          

See these for more details:

Date-Time (dateTime)

Date/time according to RFC 3339 format.

The server will always send the datetime using the UTC time zone with the 'Z' suffix.

The client SHOULD send the date/time in UTC with a Z suffix, however the client MAY use any format from RFC 3339.

Example:
2010-01-01T08:00:00.00Z

Country code (ccode)

Country codes are defined in the ISO-3166-1 alpha-2 standard.

The server WILL ALWAYS send country codes as upper case, two-letter codes according to ISO-3166-1 alpha-2.

The client SHOULD send codes as upper case.

Example:
SE

Language code (language3)

Language codes are defined in the ISO-639 standard.

The server will ALWAYS send languages as lower case, three-letter codes according to ISO-639-2.

The client MAY use ISO-639-1 two-letter codes. The client SHOULD send codes as lower case.

Example:
swe

Currency code (currency)

Currency codes are defined in the ISO-4217 standard.

The server will ALWAYS send currencies as upper case, three-letter ALPHABETIC codes according to ISO-4217.

The client MAY send numeric ISO-4217 codes.

Example:
SEK

Money

Money is encoded as a decimal amount and a currency code in a "money" object.

amount
field contains the amount as a decimal value serialized as a string. See "Decimal values" above.
currency
field contains a currency code. See "Currency code" above.
decimals
Number of decimals to use.
This SHOULD be an EVEN number! This is because money usually has even number of decimals and it allows some smarter logic for guessing the decimal separator (, or .) later down the chain. Thus 2,4,6,8 are fine. 3,5,7 are not.

Both currency and amount is required when sending a monetary value.

Example money object:


  {
    "currency":"SEK",
    "amount":"42.23",
    "decimals":2
  }
          

Concepts

Attribute

The attribute mainly consists of a name. It is possible to add attribute values to a product or a variant group and to connect these values to the attribute e.g. the attribute named "Size" can be connected to a product and the attribute value "XL" is added to the product. The attribute itself does not contain any attribute values.

The customData field is used to configure attributes in plugboard to match attributes for remote systems. See CustomData

Product price

Plugboard is using pricelists and supports price levels based on qty. To add a price you need to connect a pricelist and to specify the price per qty (purchaseQty).

prices
contains an array of prices. Note that all prices need to be sent when updating the prices field.
pricelist
plugboard supports multiple pricelist. It is mandatory to have at least one pricelist.
qtyPrices
plugboard supports prices based on the purchase qty e.g. 1 for 20:- each or if you buy at least 5 it is 12:- each. See example below.
purchaseQty
The limit for when the price is valid e.g 5 means that quantity of at least 5 will qualify
originalPriceExclVat
This field contain the price in the format Money

Example: The following example will add two price levels to one pricelist and one price level to another pricelist


  {
    "prices": [
        {
            "pricelist": {
                "localId": "3fb2568eb7e165e34dd311af5550002b",
            },
            "qtyPrices": [
                {
                    "purchaseQty": "1",
                    "originalPriceExclVat": {
                        "currency": "SEK",
                        "amount": "20.00",
                        "decimals": 2
                    }
                },
                {
                  "purchaseQty": "5",
                  "originalPriceExclVat": {
                      "currency": "SEK",
                      "amount": "12.00",
                      "decimals": 2
                  }
              }
            ]
        },
        {
          "pricelist": {
              "localId": "3fb2568eb7e165e34dd311af5550002c",
          },
          "qtyPrices": [
              {
                  "purchaseQty": "1",
                  "originalPriceExclVat": {
                      "currency": "SEK",
                      "amount": "50.00",
                      "decimals": 2
                  }
              }
          ]
      }
    ]
  }
            
          
  • All prices for a product will be replaced when updating the field "prices" (endpoint PUT /product/{localId})
  • A pricelist should only exist once within the prices array.

Order row

The order row can be any of product, paymentfee, shippingfee, handlingfee, discount, voucher, comment, rounding.

Product (rowType)

pricePerUnitExclVat
The price is per unit and excludes tax and including any discount.
The field contains the price that the customer should pay i.e. including any discount. The row sum in the example below is 200.00 SEK (NOT 180.00 SEK).
rowDiscountExclVat
Contains the discount for the row excluding tax.

Example of discount on a product row. The sum that should be paid in this case is 200.00 SEK:


  {
    "rowType": "product",
    "sku": "a-product",
    "title": "A product",
    "qty": "1",
    "pricePerUnitExclVat": {
        "currency": "SEK",
        "amount": "200.00",
        "decimals": 2
    },
    "rowDiscountExclVat": {
        "currency": "SEK",
        "amount": "20",
        "decimals": 0
    }
  }
            

Discount (rowType)

pricePerUnitExclVat
The price is per unit and excludes tax and including any discount just like any other row. Use a negative value to give a discount on an order.

Example of discount as a separate row. The sum that should be paid in this case is 180.00 SEK (200-20):


  {
    "rowType": "product",
    "sku": "a-product",
    "title": "A product",
    "qty": "1",
    "pricePerUnitExclVat": {
        "currency": "SEK",
        "amount": "200.00",
        "decimals": 2
    },
    "rowDiscountExclVat": {
        "currency": "SEK",
        "amount": "20",
        "decimals": 0
    }
  },
  {
    "rowType": "discount",
    "sku": "discount",
    "title": "A discount",
    "qty": "1",
    "pricePerUnitExclVat": {
        "currency": "SEK",
        "amount": "-10.00",
        "decimals": 2
    }
  }
            

Comment (rowType)

Example: A comment as an order row


  {
    "rowType": "comment",
    "comment": "Comment as an order row"
  }
            

Record source

The record source contain information of the origin of the record. There are two types of sources:
user
A user can in some cases create a record directly from the admin interface. The source will only contain type=user and a login. This information is readonly from the API.
connection
A record can be created through a connection which can be a part of an API-connector or any other connector, see Terminology In this case the record source contain information of connectionType, connectionId, code and connectionName. The field code is the only field that can be modified through the API. The field can be used to identify a specific source in case the remote system support multiple sources.

Content Group

Content Group enables the possibility to send different texts depending on the receiving system. It is possible to create a content group called "marketplace x". This content group will be displayed in the edit page as "Alternative content group".

Some connections in plugboard have a setting for content group . The connection can be configured to use a content group (in this example called "marketplace x") which means that this connection will always send the content in the content group instead of the standard value.

The alternative text from the content group can be found under in the API under alternateContent. One example is the GET endpoint for /product/{localId} (see API-reference)

Example of content group object:

            
  "alternateContent": {
    "3fb2568eb7e165e34dd311af5550002b": {
      "contentGroupId": "3fb2568eb7e165e34dd311af5550002b",
      "title": "string",
      "title_lang": {
        "swe": "Exempeltext",
        "eng": "Example text"
      },
      "shortDescription": "string",
      "shortDescription_lang": {
        "swe": "Exempeltext",
        "eng": "Example text"
      },
      "description": "string",
      "description_lang": {
        "swe": "Exempeltext",
        "eng": "Example text"
      }
    }
  }
            
          

Custom data (customData)

Some objects allow custom data to be attached to them. The custom data is formatted as a dictionary, where the dictionary key is the custom data parameter and the value is an object containing information about the parameter.

Parameters are separated into modules, and modules themselves have different keys. If a custom key is needed the moduleId MUST begin with "x-" so as not to cause conflicts. The moduleId and key MUST NOT contain pipe ("|") characters.

The dictionary key used in the customData object is comprised of connectionId + "|" + moduleId + "|" + key.

The information provided in the object is:

moduleId
The module id this parameter relates to.
key
The key within the module.
type
The type of the parameter, can be one of string, bool, integer, decimal, bytes.
connectionId
If this item is specific to a particular connection only. (This value is optional)
value
The value, according to type.

The connectionId, moduleId and key parameters are case sensitive!

Example of custom data object:

            
  {
    "customData":{
      "5377568eb7e165e3b38af6eece4a0001|test|href":{
        "connectionId":"5377568eb7e165e3b38af6eece4a0001",
        "moduleId":"test",
        "key":"href",
        "type":"string",
        "value":"/pricelist/2"
      },
      "5377568eb7e165e3b38af6eece4a0001|test|href2":{
        "connectionId":"5377568eb7e165e3b38af6eece4a0001",
        "moduleId":"test",
        "key":"href2",
        "type":"string",
        "value":"/pricelist/42"
      }
    }
  }
            
          

Tax model

The API supports both Sales tax and VAT (Value Added Tax).

Sales tax

Sales tax is a tax on the SALE of the item.
Sales tax (e.g US) is collected by the retailer when the final sale in the supply chain is reached via a sale to the end consumer. End consumers pay the sales tax on their purchases.

VAT (Value Added Tax)

VAT is a tax on value added to an item, for example if you buy it cheap and sell it for more then the value increase itself is taxed, not the sale. VAT (e.g. EU countries) is collected by all sellers in each stage of the supply chain. Suppliers, manufacturers, distributors and retailers all collect the value added tax on taxable sales. Suppliers, manufacturers, distributors, retailers and end consumers all pay the VAT on their purchases.

Description of the model

The fields below is also described in the TaxationItem model in our Swagger page.
  • The taxType field contains a tax type which is enum with possible values vat or salestax
  • The label field contains a string that describes the tax.
  • The percentage field for the tax rate. The rate is a string where the value "25.0" is used to represent a 25% tax rate.
  • The taxableAmount field contains a Money object that represent the amount that is used to calculate the tax.
  • The tax field contains a Money object that represent the tax.
  • The customData field contains custom data, see the section Custom data

Example of the tax object:


        {
          "taxType":"vat",
          "label": "Describe the tax",
          "percentage":"25",
          "taxableAmount":{
             "currency":"SEK",
             "amount":"100.00",
             "decimals":2
          },
          "tax":{
             "currency":"SEK",
             "amount":"25.00",
             "decimals":2
          },
          "customData":{}
       }
      

Example usage of the tax object:


        "perUnitTaxes":[{
          "taxType":"vat",
          "label": "Describe the tax",
          "percentage":"25",
          "taxableAmount":{
             "currency":"SEK",
             "amount":"100.00",
             "decimals":2
          },
          "tax":{
             "currency":"SEK",
             "amount":"25.00",
             "decimals":2
          },
          "customData":{}
       }],
      

Deprecated VAT-fields

The VAT fields e.g vatRatePercent are deprecated but still exists in the API and contains correct values. It is highly recommended to stop using these fields and start using the new tax model. The tax fields will always contain the correct tax values e.g a GET request for an object will contain both the vat field and the tax field no matter which field you used when creating the object. The VAT fields will be removed completely in the future.

Example of the deprecated vat fields:


        "vatRatePercent":"25",
        "vatPerUnit":{
          "currency":"SEK",
          "amount":"25.00",
          "decimals":2
        }
      

Language support

Removal of keys

To remove keys from a custom data object you need to send the key value as null.

Example:


  {
    "5377568eb7e165e3b38af6eece4a0001|test|href" : null
  }
          

Just ignoring the key will not remove or change it, allowing you to only send the keys you wish to change.

Language support

Language tagged fields are supported in two ways by this API so as to simplify client implementations.

Each API user has a default language configured. The api provides information about this in the "API Root" block.

The API client SHOULD support multiple languages, however the client MAY only support one language. For clients that do not support multiple languages the language used MUST be the default language configured for the user.

Each string field with language information is encoded twice in the JSON document. First the field is encoded as a normal string using the language configured for this user.

Example:


  {
    "title":"the title"
  }
          

Then a language tagged version of the field, with the suffix "_lang" whose value is a JSON document with language codes as keys and the localized text as value.

Example:


  {
    "title_lang": {
      "swe":"Titeln",
      "eng":"The title"
    }
  }
          

Example - This results in an object like this:


  {
    "title":"the title",
    "title_lang": {
      "swe":"Titeln",
      "eng":"The title"
    }
  }
          

This enables forward and backward compatibility as current fiends that are extended with language information in the future retain the semantics in the document and just get an additional field containing the language information. Older clients will then just ignore this new field and continue as before.

Removal of translations

Example - To remove a translation you need to send that value as "null":


  {
    "title":"the title",
    "title_lang": {
        "swe":"Titeln",
        "eng": null
    }
  }
          

Just ignoring the translation will not remove or change it, allowing you to only send the translations you wish to change. See Field rules (input)

Use cases

Product

Get products

Get the products from the API if the products already exists in plugboard. You will need to get the products from the API to get the unique id in plugboard. Make sure to save the related values of SKU and localId (or remoteId and localId). The remoteId is related to the API and is null if the product was imported from another system. Read more about remoteId at Local and remote ID’s.

Endpoint:
GET /product?modifiedAtOrAfter=2020-09-24T17:23:01Z
Example of a response:
                
  [
      {
          "href": "/api/product/0006463d034d595774bf76d0311a21be",
          "localId": "0006463d034d595774bf76d0311a21be",
          "remoteId": "x",
          "sku":"y"
      }
  ]
                
              

All products will be returned if modifiedAtOrAfter is excluded

Create a product

A product can be quite complex and contain a lot of information. This example shows the minimum information required to be able to handle the inventory.

Below is the minimum information that is needed:

remoteId:
must be unique. This could be the internal id from the connected system. Make sure that to save the relation between remoteId and localId in the connected system. localId is the unique identifier within plugboard.
vatRatePercent:
is mandatory and must be provided
stock:
the available stock
stockType:
an enum see the API reference for available options
sku:
a unique sku for the product. The sku should be the same both connected systems.
Endpoint:
POST /product
Example of a request body:
                
  {
    "remoteId": "x",
    "vatRatePercent": "25",
    "stock": "10",
    "stockType":"stocked",
    "sku":"z"
  }
                
              
Make sure to save the localId from the response. Response:
                
  {
      "localId": "0006463d034d595774bf76d0311a21be",
      "remoteId": "x",
      "....":"....."
  }
                
              

Query products

It is possible to use the query endpoint to find a product by SKU. This can be used to find a specific product or set of products. This enpoint should not be used at each update, save the localId and use that to target the correct product.

Endpoint:
POST /product/query
Example query to find a specific SKU:
                  
  {
    "filter": {
        "type": "eq",
        "field": "sku",
        "value": {
          "type": "str",
          "value": "997"
        }
    },
    "deletedFlag": "not-deleted",
    "numRecords": 100,
    "offset": 0
  }
                  
                
Response will be an array of products. Example response:
                  
  [
    {
      "localId": "0006463d034d595774bf76d0311a21be",
      "remoteId": "x",
      "....":"....."
    }
  ]
                  
                

Add a picture

  1. Create a file:
    Use POST /file/
    Request body:
      {
        "name": "myfile",
        "mimeType": "image/jpeg",
        "publicAccess": true
      }
                      Response body:
      {
        "name": "myfile",
        "mimeType": "image/jpeg",
        "publicAccess": true,
        "localId": "3fb2568eb7e165e34dd311af5550002b",
        ...
      }
                      
                    
  2. Upload the filecontent:
    Use PUT /file/{localId}/data with Content-Type:application/octet-stream

    Example: /file/3fb2568eb7e165e34dd311af5550002b/data

  3. Alternative1: Connect the file to a product as a product picture. The picture will be connected to a specific product and SKU.
    Use POST /product/{localId}/picture OR POST /product/by-remote-id/picture?remoteId={remoteId}
    Note that localId and remoteId in the url relates to the product and NOT the file.

    The fileId in the body is the localId for the file. See response from step 1 above.
    Request body:
      [
        {
          "fileId": "3fb2568eb7e165e34dd311af5550002b"
        }
      ]
                      
                    
  4. Alternative2: Connect the file to a product variant group picture.
    The product variant group picture is not related to a specific product (or SKU). A product variant group can contain 0 to X number of products which each have their own SKU and potentially their own pictures.
    Use POST /product/variantgroup/{localId}/picture.
    The fileId in the body is the localId for the file. See response from step 1 above.
    Request body:
      [
        {
          "fileId": "3fb2568eb7e165e34dd311af5550002b"
        }
      ]
                      
                    

Inventory

Update inventory

Plugboard needs products to be able to handle the inventory. The products can either be added by the API or it can be imported into plugboard from any of our connectors.

Update stock value

Make a PUT-call to update the product’s stock value in plugboard. localId is the unique identifier within plugboard.

Endpoint:
PUT /product/{localId}
Request body:
                
  {
    "stock": "10"
  }
                
              

Order

Get orders

This endpoint can be used to import new orders and also to get updated orders. The modifiedAtOrAfter will only return order that have a changed timestamp. The timestamp is change at any change to the order e.g order status.

Query parameter:
modifiedAtOrAfter Date-Time (dateTime)
Endpoint:
GET /api/order?modifiedAtOrAfter=2020-09-24T17:23:01Z
Example response body:
                
  [
    {
      "href": "/api/order/00061e1066ab0aca7473627d3d488c86",
      "localId": "00061e1066ab0aca7473627d3d488c86",
      "remoteIdMap": {},
      "remoteRefMap": {},
      "created": "2020-09-10T10:56:10Z",
      "lastModified": "2020-09-25T10:24:02Z",
      ".....":"....."
    },
    {
      "href": "/api/order/00061e1066ab0aca7473627d3d488c86",
      "localId": "00061e1066ab0aca7473627d3d488c86",
      "remoteIdMap": {},
      "remoteRefMap": {},
      "created": "2020-09-10T10:56:10Z",
      "lastModified": "2020-09-25T10:24:02Z",
      ".....":"....."
    }
  ]
              
              

All orders will be returned if modifiedAtOrAfter is excluded

Update order status

The order status is updated by a simple PUT call. The orderStatus is an enum and you can find the available option under section Models->orderStatus at the API-reference

Endpoint:
PUT /order/{localId}
Example response body:
            
  {
    "orderStatus": "completed"
  }
            
          

Create Order Example


  curl -X POST --header 'Content-Type: application/json'
       --header 'Accept: application/json'
       --header 'X-Tenant: %tenant%' --header 'X-ConnectionId: %connectionId%'
       --header 'Authorization: %auth%' -d '{ \
        "customerType": "company", \
        "currency": "SEK", \
        "totalSumExclVat": { \
            "currency": "SEK", \
            "amount": "1.0" \
        }, \
        "totalVat": { \
            "currency": "SEK", \
            "amount": "1.0" \
        } \
     }' 'https:///api/order/'
      

Replace %variable% with your unique id.

Output:


  {
    "href": "/api/order/0006d682a5ecee8f64227e481f4ab4b9",
    "remoteId": null,
    "localId": "0006d682a5ecee8f64227e481f4ab4b9",
    "remoteIdMap": {},
    "created": "2018-06-28T06:51:49Z",
    "lastModified": "2018-06-28T06:51:49Z",
    "customData": {},
    "customerType": "company",
    "currency": "SEK",
    "totalSumExclVat": {
      "currency": "SEK",
      "amount": "1.00"
    },
    "totalVat": {
      "currency": "SEK",
      "amount": "1.00"
    },
    "billingAddress": null,
    "shippingAddress": null,
    "orderRows": [],
    "source": {
      "connectionType": "api",
      "connectionId": "000772bee96aae826403d0ed08590008",
      "code": null,
      "connectionName": "API"
    },
    "shipments": []
  }
      

Changelog

2021-04-13

Version 7

Added new endpoints for product prices. For more info see Plugboard REST API reference
New endpoints are:
  • product/{localId}/price
  • product/by-remote-id/price
  • product/{localId}/price/{pricelistLocalId}
  • product/by-remote-id/price/by-remote-Id
2021-03-23

Version 6

  • New section describing the tax model
  • Settlement uses a new tax model. All vat fields for settlement have been removed.

Settlement

  • Settlement uses a new tax model. All vat fields for settlement have been removed.
  • BREAKING CHANGEAll "Vat"-fields have been removed from Settlement endpoints.
  • BREAKING CHANGEThe "Tax"-fields should be used instead. These fields uses the new Tax Model.

Z-Report

  • Z-Reports uses a new tax model. All vat fields for z-report have been removed.
  • BREAKING CHANGEAll "Vat"-fields have been removed from Z-report endpoints. The "Tax"-fields should be used instead. These fields uses the new Tax Model

Payment Transaction Event

  • Payment transaction event uses the new Tax Model. All VAT-fields are deprecated and it is highly recommended to start using the Tax-fields.

Invoice

  • Invoice uses the new Tax Model. All VAT-fields are deprecated and it is highly recommended to start using the Tax-fields.
  • BREAKING CHANGEFields specifiedVatPerUnit and specifiedRowDiscountVat have been removed

Order

  • Order uses the new Tax Model. All VAT-fields are deprecated and it is highly recommended to start using the Tax-fields.
  • BREAKING CHANGEFields specifiedVatPerUnit and specifiedRowDiscountVat have been removed
2019-06-05

Version 5

  • Added lots of information to error response.
2019-05-06

Version 4

  • Added "rounding" row type.
2019-04-25

Version 3

  • Added orderType for orders.
2019-03-21

Version 2

  • Added Cash Registers
  • Added Z-Reports
  • Added Payment Methods
  • Added Payments
2018-12-07

Version 1

First public version.

Future changes should remain backwards compatible enough so clients written againts older versions should work with no changes as long as the client ignores any new fields in responses.