Skip to main content
Version: 1.0.0

API Reference

The Propeller REST API is based on resource-oriented URL's, returns JSON-encoded responses and uses standard HTTP response codes, authentication and HTTP methods. The main goal of the REST API is efficiently importing/exporting large amounts of data in/out of the Propeller platform.

HTTP methods

Propeller REST API supports POST, GET, PATCH, and DELETE HTTP methods.

Authentication

The REST API uses the oAuth 2.0 client credentials grant type for authentication, every API requests needs a valid access token.

Request an access token

  1. Request an access token by executing a POST request to the token endpoint. This POST request should include the Client Id and Client Secret.
  2. A successful access token request will return the following result:
{
"refresh_token_expires_in": "0",
"api_product_list": "[Propeller REST APIs]",
"api_product_list_json": [
"Propeller REST APIs"
],
"organization_name": "propeller-platform-prod",
"developer.email": "developer@propel.us",
"token_type": "BearerToken",
"issued_at": "1646873717224",
"client_id": "veNqlG9u5JAce1AccAnuiqxFL1NvVMHS0H8Qu8omHBW7ykjT",
"access_token": "ARAo4GjuI1bGSyenSKx5oYfFGuFQ",
"application_name": "a1ca275a-2abb-4bd3-82b0-3ae699d75e40",
"scope": "",
"expires_in": "1899",
"refresh_count": "0",
"status": "approved"
}
  1. Parse the access_token value from this result and use it as a bearer token in subsequent API requests.

  2. After 30 minutes the requested access_token expires and a new token needs to be requested.

Lookup keys

The REST API offers multiple ways to identify resources. In Propeller terminology these are called lookup keys. For example: a product can be identified by its Propellor internal idbut also by an sku. A sku however, is not guaranteed to be unique in the catalogue, as multiple products with the same sku can exist. If multiple resources are found based on the lookup key / value combination the result of the request will be an error. In case of multiple products with the same sku a GET or PATCH request to this product will result in an error.

Lookup KeyDescription
idUnique Propeller id of an object
externalIdUnique external id
sourceId/sourceExternal system unique id to a Propeller resource. sourceId always needs to be combined with a source. Source is typically the name of a supplier or ERP system the data originates from.
skuStock-keeping unit code referencing a product
supplierCode/supplierCode of a supplier referencing a product
codeCode referencing any other resource (e.g. a pricesheet)

Source Id/ Source lookup key is most commonly used in Bulk endpoints. If you're creating/ updating products from an external system, the name of that system would typically be the source and sourceId would be the product's id or code in that system. This id should be unique in that system and the combination source/sourceId is unique in Propeller. When using the GET, DELETE, UPDATE endpoints with lookup key sourceId you can use it without source, but if multiple resources are found you will get an error. In that case use source as well.

Supplier code / supplier is another common way of looking up products. The difference between the sourceId is that the combination does not have to be unique. When it's not and you try to use the GET, UPDATE, DELETE endpoints you will get an error that multiple resources have been found.

Expanding resources

Some resources allow to request additional information as an expanded resource by using the expands request parameter. This parameter is available on all GET REST API requests and applies to the response of that request only.

In many cases, an object contains a related object in its response properties. For example, an Orderitem may have an associated Product id. Those objects can be expanded inline with the expands request parameter.

Expand parameterDescription
orderItemsexpands the order resource with orderItems
orderItems.productexpands the orderItems resource with the product resource
translationexpands translated fields for all available languages.
inventoryBalanceexpands all inventory resources for a product
defaultProductexpand the cluster or option resource with the default product resource

Pagination

Querying resources and especially retrieving a lot of data can be potentially really expensive. Therefor, endpoints that retrieve a lot of results are paginated. Use page and offset query parameters to request a certain page of the result in GET endpoints. When using search endpoints (POST HTTP method), page and offset are part of the payload.

Page

You can request a certain page of the result using the page query/ payload parameter.

Offset

You can set the maximum number of results to return using the offset query/ payload parameter. The minimum value is 1 and the maximum can differ per API. This is specified in more details in endpoints that support pagination. The default offset on most endpoints is 12.

Response

This response retrieves 2 results in the data, the number of results per page is 2 and page requested is 1. total is the number of records for the page requested, while itemsFound is the total number of results.

{
"data": [
{
id: 56897
},
{
id: 36975
}
],
"messages": [
"Completed"
],
"start": 1,
"pages": 20,
"total": 2,
"offset": 2,
"itemsFound": 35,
"end": 2,
"page": 1
}

Errors

This section describes error codes used in the Propeller platform REST APIs and their meaning. For details about the API-specific error-codes, consult the documentation dedicated to that API.

CodeError TypeStatus CodeMessageReason
10005InvalidJSONPayload400Invalid JSON PayloadJSON provided in payload is not valid
10006InvalidLookupKey400Invalid lookup keyLookup key is not supported in the specific API. Check API specific lookup keys
10007SchemaValidationException400Schema Validation ErrorJSON schema validation. Response contains the details of the issue
10008NotFound404Resource not foundResource deleted, non-existing or insufficient permissions
10015PaginatedResponseException400Pagination not properly initializedoffset or page are not initialized properly. These should be positive integers. Possible maximum limit exceeded on offset
10016LookupKeyNotFound400Lookup key not found in payloadBulk endpoints by a certain lookup key require that the lookup key is provided in the payload
10017PayloadValidationError400Payload validation errorServer side validation of the payload. Response contains the details of the issue
10018TranslationNotFound404Translation not foundResource deleted, non-existing or insufficient permissions
10019WarehouseNotFound404Warehouse not foundResource deleted, non-existing or insufficient permissions
10020WarehouseInvalidConfiguration400Warehouse invalid configurationWarehouse not properly configured, e.g. not a pick up location

Error Response

When an API call results in an error, the response contains the error property which is an object with the following properties:

PropertyTypeDescription
codestringError code. Generic error codes are listed here, while API specific error codes are listed in each API
statusintegerStatus code
typestringError type. Generic error types are listed here, while API specific error types are listed in each API
messagesarray[string]An array of error messages
moreInfostringURL to a page containing details about the error (under construction)

Example error response:

{
"error": {
"code": 80006,
"status": 404,
"type": "ProductNotFound",
"messages": [
"Product with id [481189] not found"
],
"moreInfo": "https://www.propel.us/docs/errors/80006"
}
}

Localized String

A localized string is a JSON object used for fields that are translatable. A localized string has two properties: to indicate the language as per ISO 639-1 and the value of the translated field in that language.

{
"language": "EN",
"value": ""
}

Bulk endpoints

Bulk endpoints allow for an efficient way of importing/updating large amounts of data with just a single API call. Traditional REST API functionality would allow for a single resource (e.g. a product or user) to be created and a second API request to update this resource. Creating and/or updating multiple resources would mean executing multiple API requests. Working with larger number of resources means this approach would generate a significant number of API calls resulting in inefficient use of resources and import processes taking a lot of time.

The Propeller REST API offers "bulk" functionality to efficiently import/update resources. A bulk request typically contains a payload of multiple resources of a single type (e.g. product, user, category or inventory). Based on the lookupKey Propeller will decide if a resource needs to be created or updated.

Bulk endpoints take away the need for multiple API calls to determine if a resource needs to be created or updated and allow for creating/updating multiple resources in on API request.

Directives

Directives are a powerful Propeller REST APIs concept only used in bulk endpoints. Use directives for actions that are otherwise only doable via a lot of single endpoint API requests. Directives concept is easiest to understand via use cases.

  • Let's assume a large number of products is being created/ updated using the Product Bulk endpoint and Propeller's back office is used to maintain some of the data, e.g. product names. When products are created via the bulk endpoint they should not be created with an empty product name. That name can later be changed and we don't want to overwrite it. If it were a single resource endpoint, the GET endpoint could be used to check if the product exists, find the name, compare it, etc. That is not really efficient on a large scale. This is where skipIfNotEmpty directive comes handy. Use this directive when you only want to set a field with the value from the payload if it's current value is an empty string.
  • Another use case is using Propeller to move resources in a different parent container that the one they were originally created in. Let's assume you have a list of products that belong in certain categories and those products are created via the Bulk endpoints. If you decide to maintain the catalogue structure from within Propeller you would typically move products around manually or via Propeller's rule engine. To avoid a Bulk endpoint would move them back to their original endpoint, use the skipMoveOnUpdate directive.
  • When creating categories/ product translations you typically have a list of all the active translations you want the resource to be translated in. When using a single resource endpoint you can delete translations one by one, but in the Bulk endpoints use mergeTranslationsOnUpdate to reset i.e. delete the ones that are not in the payload.
NameDescriptionFields
skipIfNotEmptyOn update, skip updating fields of an existing resource that are not emptyarray of field names, API specific
e.g. for products : names, descriptions, etc.
skipMoveOnUpdateOn update, skip moving an existing resource in the parent resource providedempty array
mergeTranslationsOnUpdateOn update, delete all translation for a resource that are not provided in the payloadempty array
skipCreateSkip creating new, only update existing resourcesempty array

Use Cases

Usergroups - users bulk import

The user rest api is typically used in a B2B environment where a predefined set of customers is allowed access to a webshop / portal. Typically those customers are managed in an ERP and/or CRM system and in order for these customers to have access to the webshop, they need to have an account in Propeller meaning these customers need to be imported into Propeller.

A common way for an ERP/CRM system to handle the concept of customers is to have an entity called customer/debtor or relation and within this entity there are one or multiple contacts. The customer/debtor in this case is a company/organization and has a unique debtorId . The contacts are typically persons within the organization with each their own e-mail address/telephone number and multiple different invoice, delivery and visiting addresses.

A typical way to get the ERP / CRM customers into Propeller is to create a Propeller usergroup for each customer and within this usergroup, for each contact, a Propeller user .

Most of the time the number of customers/contacts which need to be imported will be multiple thousands (if not more). In these cases it is important to use the user and usergroup bulk endpoints, these make sure creating/updating the usergroups / users / addresses / attributes is done in efficiently.

To create the usergroups and users in Propellor two different bulk endpoints need to be used:

  1. the usergroup bulk endpoint
  2. the user bulk endpoint

Via the usergroup bulk endpoint multiple usergroups representing companies will be created:

{
"usergroups": [
{
"sourceId": "x-123",
"source": "MBC",
"language": "EN",
"parent": {
"sourceId": 999112000
"source": "MBC"
},
"name": "Company X"
},
{
"sourceId": "y-456",
"source": "MBC",
"language": "EN",
"parent": {
"sourceId": 999112000
"source": "MBC"
},
"name": "Company Y"
},
{
"sourceId": "z-789",
"source": "MBC",
"language": "EN",
"parent": {
"sourceId": 999112000
"source": "MBC"
},
"name": "Company Z"
}
]
}

The above usergroup bulk endpoint will create or update three usergroups. In this case we use the sourceId / source combination as lookupKey / lookupValue combination. When using the sourceId / source combination as lookup key, it's possible to identify resources in Propeller based on keys / identifiers from the ERP / CRM system. In the usergroup example, the source of the data is Microsoft Business Central (MBC) and the sourceId is a unique id / code for a certain customer / organization in Microsoft business central. The combination of the source and sourceId field will make sure there is only one resource found when referencing a usergroup based on these lookup values.

In advanced setup's its possible to import resources (e.g. customers / contacts) from multiple sources, If usergroups / users would also be imported from a second ERP / CMS system there is a change the sourceId would not be available anymore since it is used already by the first import. Because Propeller uses the combination of sourceId / source to uniquely identify a resource it is possible to import data from multiple different sources using the same sourceId's. A second usergroup import from e.g. Exact Globe could look like this:

{
"usergroups": [
{
"sourceId": "x-123",
"source": "EXACTGLOBE",
"language": "EN",
"parent": {
"sourceId": "999112000"
"source": "EXACTGLOBE"
},
"name": "Company XX"
},
{
"sourceId": "y-456",
"source": "EXACTGLOBE",
"language": "EN",
"parent": {
"sourceId": "999112000"
"source": "EXACTGLOBE"
},
"name": "Company YY"
},
{
"sourceId": "z-789",
"source": "EXACTGLOBE",
"language": "EN",
"parent": {
"sourceId": "999112000"
"source": "EXACTGLOBE"
},
"name": "Company ZZ"
}
]
}

In this case the sourceId's from MBC and Exact Globe are the same but because Propeller uses the additional field source to identify a resource it is possible to keep using the identifiers generated by the ERP / CRM.

Once the usergroups are created the users can be created via the user bulk endpoint. To make sure a user is created inside the correct usergroup within the user resource a parent object is added pointing to the usergroup using the source / sourceId of the usergroup

{
"users": [
{
"source": "MBC",
"sourceId": "3002196",
"language": "NL",
"parent": {
"sourceId": "x-123",
"source" : "MBC"
},
"firstName": "Miles",
"middleName": "",
"lastName": "McCoy",
"debtorId": 12345,
"login" : "miles@xx.com"
"company" : "Company X"
"email": "miles@xx.com",
"mobile": "001445888",
"phone": "001445888",
"title": "Mr.",
"gender": "M"
},
{
"source": "MBC",
"sourceId": "3002197",
"language": "NL",
"parent": {
"sourceId": "x-123",
"source" : "MBC"
},
"firstName": "Bernie",
"middleName": "",
"lastName": "Sawer",
"debtorId": 12345,
"login" : "bernie@xx.com"
"company": "Company X",
"email": "bernie@xx.com",
"mobile": "001445888",
"phone": "001445888",
"title": "Mr.",
"gender": "M"
},
{
"source": "MBC",
"sourceId": "3002200",
"language": "NL",
"parent": {
"sourceId": "x-456",
"source" : "MBC"
},
"firstName": "Delia",
"middleName": "Ferdi",
"lastName": "Finney",
"debtorId": 67890,
"login" : "Delia@yy.com"
"company": "Company Y",
"email": "bernie@yy.com",
"mobile": "001445888",
"phone": "001445888",
"title": "Ms.",
"gender": "F"
}
]
}

A user / usergroup import is something which needs to be executed frequently since changes in the ERP / CRM should be made available in Propeller, new customers need to get access to the webshop and in certain situations access to the webshop needs to be revoked. Using the bulk endpoints, the payload only needs to be defined once without any logic.

Order export

Order searching is typically used in combination with exporting orders to ERP/financial/other external systems. Within the Propeller order workflow there will be the need to export orders at a certain point. Most of the times the need to export an order is when the order transitions to a certain status (e.g. CONFIRMED). Via the order search api it is possible to retrieve a list of orders which are in status CONFIRMED and have not been exported yet (using the fields below)

{
"status": "CONFIRMED",
"exported": false
}

Once the orders have been exported it is good practice to update the order and mark it as "exported" field using the order update api. Searching for orders with the above payload will then only result in an list of orders without the previously exported orders.

Authentication

Security Scheme Type:

http

HTTP Authorization Scheme:

basic