Skip to main content

Automatically Creating Third-Party Client Applications

Introduction

CargoX Platform provides an /apps/ API endpoint to selected partners (referred to as Suppliers hereon) that have a need to create client applications for multiple integrations. An example would be an application which does not run in the cloud but needs to be installed on-premise. It makes sense for each such installation to have a separate client_id and client_secret. This endpoint is suitable for such specific cases.

Each supplier is issued an unique ID and a shared secret. The combination of both is used to request new OAuth credentials.

warning

Please keep these credentials extremely safe. They should not be written down. Ideally, they should be baked into the application itself. If that's not possible and they need to be a part of configuration, make sure that the configuration is encrypted.

If these credentials are compromised an attacker may be able to gain access to all existing instances of your application. CargoX might not be able to detect or influence this.

If you need to become a software supplier, contact our support at [email protected].

Authorizing API requests: creating a hash

Each request to this API is authorized using your credentials. This is achieved by calculating a timestamped HMAC hash using your issued shared secret.

Message that uniquely defines a client application consists of three parts:

Parameter keyParameter nameDescription
app_idInstance (Request) IDThe unique request ID. Every instance must use a different ID.
supplier_idSupplier IDYour supplier identification code, provided by CargoX.
timestampUnix timestampCurrent (Unix) time, truncated down to the last minute.
caution

app_id (Application ID) is the unique ID of your request. CargoX will match the app_id and supplier_id in its database and issue only one set of client credentials per combination. This enables you to call the endpoint multiple times (e.g. in case of network errors) and be certain you will always get the same result.

How you pick the app_id is up to you, just make sure they do not overlap. A good ID would be something that does not change -- e.g. you could either generate it on the first run and save it in the database, or use a combination of custom prefix and network card's MAC number.

The HMAC needs to be calculated using the following formula:

HMAC('{app_id}-{supplier_id}-{timestamp}', '{supplier_secret}')

Here are a couple of examples of how to calculate the hash.

import time
import hmac
import hashlib

APP_ID = get_application_id()
SUPPLIER_ID = 'e225d965-205d-4187-b9bd-103f1a54c4d1'
SECRET = '3c49474297c6338cce2788ec0ccee44fe38199bd74de3a03802404b2a7b62cfc'

timestamp = int(time.time() // 60 * 60)
message = '{app_id}-{supplier_id}-{timestamp}'.format(app_id=APP_ID,
supplier_id=SUPPLIER_ID,
timestamp=timestamp)
hash = hmac.new(bytes.fromhex(SECRET), msg=message.encode('utf-8'), digestmod=hashlib.sha256).hexdigest()
important

To prevent replay attacks, the HMAC code includes the timestamp. This means that your request will not be valid indefinitely. More specifically, the server will accept only requests with a timestamp of current and previous minute (to prevent race conditions where the HMAC was generated just before the clock rolls around).

In general, this should be a safe margin. If you're running into issues where your hash code validation is failing, make sure you verify your clock is set up correctly first.

Create a client application

To create a new application, call the /apps endpoint with the following parameters:

Parameter keyParameter nameDescription
app_idInstance (Request) IDThe unique request ID. Every instance must use a different ID.
supplier_idSupplier IDYour supplier identification code, provided by CargoX.
hashHMAC-calculated hashUnique hash calculated for this message.
emailSupplier's emailEmail connected with this account. Must be unique for each instance.

Example: To create a new client application, send the following request:

curl --location --request POST 'https://cargox.digital/api/v3/apps/' \
--form 'app_id=supplier-D89FCA8719BDE9F18C' \
--form 'supplier_id=e225d965-205d-4187-b9bd-103f1a54c4d1' \
--form 'hash=4fef62145de199f3351f6f64f32234f6126d77d66f5614a9c5aa4cdf5f8dcdd9' \
--form '[email protected]'

The above request returns OAuth credentials and application status as a JSON response:

{
"client_id": "rP9wBF8zn8eipsDtYRM5JcnLOazTIl75JXswT20H",
"client_secret": "6819upD3VqLLjvQLVCfTTDKqn4iYBtKdggGZ8km7PYHIWAtpSL0aHuIze3yWOOMBr1AjAdMgvsdoNeA0zgSBLHU2pbKVFkoGidj2x93rsDCWr3nqlgBBTpCEbVaYPaM9",
"allowed_ip_ranges": "",
"status": "active"
}
note

As explained previously, subsequent requests with the same app_id and supplier_id will return existing credentials without creating a new application.

If your hash cannot be validated, you will get back a 403 FORBIDDEN error.

Depending on your agreement with CargoX, the credentials may be enabled automatically. If this is the case, status will display as "status": "active" and you can start using your newly assigned credentials straight away. If the credentials were issued but are not yet confirmed, the status will be shown as "status": "pending".

In case of pending credentials your application should regularly check in with CargoX (see the call below) and inquire about the status of credentials until they switch to active state.

Fetch application OAuth credentials status

To fetch existing client application OAuth credentials, make the following request:

curl --location --request GET 'https://cargox.digital/api/v3/apps/supplier-D89FCA8719BDE9F18C/?supplier_id=e225d965-205d-4187-b9bd-103f1a54c4d1&hash=411b0dbf528c65219b92c350db9411651d2e5578a0185fc326dd9a09ab7ae487'

The above request returns OAuth credentials and application status as a JSON response:

{
"client_id": "rP9wBF8zn8eipsDtYRM5JcnLOazTIl75JXswT20H",
"client_secret": "6819upD3VqLLjvQLVCfTTDKqn4iYBtKdggGZ8km7PYHIWAtpSL0aHuIze3yWOOMBr1AjAdMgvsdoNeA0zgSBLHU2pbKVFkoGidj2x93rsDCWr3nqlgBBTpCEbVaYPaM9",
"allowed_ip_ranges": "",
"status": "active"
}