API changes: ACTION REQUIRED. Click the following for more info.
Thousands of requests each hour are currently being received with misspelled query parameters or otherwise ill-formed URL syntax.
The REST API currently silently ignores the invalid query params, so the developer isn't aware their intent is not well formed.
Frequent Mistakes Description
/orders?pgsize=100 (or orderspgsiz, pg_siz, pgziz) It must be spelled pgsiz. Close only counts in horseshoes and hand grenades.
/orders?order?pgsiz=100&pgnum=12 The ill-formed second ? makes "order?pgsiz" a query parameter. Therefore, the intended page size of 100 is ignored.
/orders?customerid=5&facilityid=7 Neither customerid nor facilityid are defined parameters for /orders. Numerous other examples similar to this for other URIs are received every day.
The customer/customeralertdefinitions rel has been replaced by the following rels:
Rel Description
customers/emailalertdef and customers/emailalertdefs To setup notitications via email for a customer (c2).
properties/emailtemplate To modify email templates at the threepl (c1) level.
customers/emailtemplate To create/modify email templates at the customer (c2) level
customers/ftpalertdef and customers/ftpalertdefs To setup notitications via ftp for a customer (c2)
API Authentication.

Three types of credentials enable three distinct uses of the API:

Single-Tenant static
used by 3rd party developers to maintain one specific 3PL's data. The credential is issued for a specific 3PL and cannot be used to access any other 3PL's data.
Single-Tenant dynamic
used by internal 3PLCentral applications to maintain any 3PL's data, one at a time, where the 3PL is specified when the token is obtained.
used by internal 3PLCentral applications to maintain tenants, such as adding or provisioning a 3PL.

Step 1: obtain a client id and secret

Request from 3PLCentral a single-tenant static credential to use the API on behalf of a particular 3PL. You will be given a client id and secret. Do not share this information with unauthorized people, for it can be used to access the 3PL's data.

Use this credential to follow the OAuth2 client_credentials flow, consisting of:

  • BASIC authentication to obtain a token, described in steps 2 and 3,
  • BEARER authentication to use the API, described in step 4.

Step 2: encode the BASIC authentication scheme credentials

As described in RFC 2617, BASIC authentication requires sending the userid and password, separated by a single colon (":") character, within a base64 encoded string in the credentials. For OAuth2, the userid and password are the client id and secret.

Assume your client id is fr4zzl3d-g0rp-ni11-b0rk-cr4ck3rj4ck5 and secret is rump3lstiltskin.
Separate with a colon to form the string fr4zzl3d-g0rp-ni11-b0rk-cr4ck3rj4ck5:rump3lstiltskin
Base64-encode it: ZnI0enpsM2QtZzBycC1uaTExLWIwcmstY3I0Y2szcmo0Y2s1OnJ1bXAzbHN0aWx0c2tpbg==
Use in step 3.

Step 3: use BASIC authentication to obtain a token

Make a token request as follows:

  • Authorization header: As per RFC 6749, Client Authentication, put the base64-encoded client id and secret into the HTTP Authorization header, using the BASIC scheme.
  • Payload: Form a JSON payload containing grant_type of client_credentials and a user_login for specifying on whose behalf you are performing the operations, such as creating or updating orders.
  • Send request: POST a request to 3PLCentral's auth server.
For example, making sure to substitute your base64-encoded client id/secret and user login:

POST /AuthServer/api/Token HTTP/1.1
Authorization: Basic ZnI0enpsM2QtZzBycC1uaTExLWIwcmstY3I0Y2szcmo0Y2s1OnJ1bXAzbHN0aWx0c2tpbg==
Content-Type: application/json; charset=utf-8
Accept: application/json
Content-Length: xxx

"grant_type": "client_credentials",
"user_login": "guysmiley"

Note: if using a Single-Tenant dynamic credential, you must also specify a 3PL guid:

"tpl": "[insert the threepl guid here]"

If you encoded a valid client id and secret properly, the response will look like:

HTTP/1.1 200 OK
Content-Length: 581
Content-Type: application/json; charset=utf-8

"access_token":"[access token will be here]",
"expires_in":3600, // seconds
"refresh_token":null, // ignore, this OAuth2 feature not used
"scope":null // ignore, this OAuth2 feature not used

Step 4: use BEARER authentication to access the API

Assume step 3 yielded the token eyJ0eXAiOiJi.eyJleHAiOiIxNDk2MjU0.ASptcg. In practice, it will be much longer.
Use Bearer authentication in subsequent API requests as follows, making sure to substitute your own token:

GET /customers/17 HTTP/1.1
Authorization: Bearer eyJ0eXAiOiJi.eyJleHAiOiIxNDk2MjU0.ASptcg
Accept: application/hal+json

Authentication vs. Authorization

Authentication means who is making the request.
Authorization means to what resources the authenticated requestor is granted access.
The Authorization HTTP header means who, not necessarily what. The process described above is all about who, not what, despite the required use of the HTTP header called Authorization.
A client credential is assigned a set of roles for determining what resources are accessible.
The following HTTP response statuses deal with authentication vs. authorization:

  • status 401: the request is not authenticated
  • status 403: though the request was authenticated, it is not authorized because the roles assigned the credential do not allow it.

This documentation is subject to change, and is updated often and without warning. The models documented may or may not be available to users now or in the future. Use this documentation at your own risk.
Contact [email protected] with any questions about this documentation.