Webhooks
In addition to retrieving shipment updates via the GET APIs you can receive them by webhook PUSH. A webhook is an endpoint hosted by you that you have registered to receive shipment updates on. When you have a webhook configured, changes to your shipments will be sent (pushed) to your hosted endpoint via an HTTP request.
- For details on the standard message format we will push to your system, see our Example of webhook payload.
- To see examples of webhook configurations for specific integration such as Azure Shared Access Signature (SAS), see our Webhook Configuration Examples.
- Additionally, please review these important sections: Push Retry Logic and Webhook Recommendations.
Setup and Configuration
Create or Update a PUSH Configuration
This is a one-time activity to set up a webhook or to update an existing webhook configuration.
Workflow
Complete these steps:
- Prepare a
PUT
request to /api/v4/webhooks. - Complete the request schema.
{ "authParams": {}, "authType": "API_KEY", "authenticationMethods": [ { "parameters": {}, "type": "API_KEY" } ], "configName": "string", "id": 0, "method": "GET", "methodParams": {}, "payloadFormat": "JSON", "url": "string", "version": 0 }
- Send the request.
Expected Response
You have successfully submitted the request when you receive a 200 OK
response. Here is a sample of the minimum response schema:
{ "authParams": {}, "authType": "API_KEY", "authenticationMethods": [ { "parameters": {}, "type": "API_KEY" } ], "configName": "string", "id": 0, "method": "GET", "methodParams": {}, "payloadFormat": "JSON", "url": "string", "version": 0 }
Errors
If there was a problem with your request, you will receive one of the following error codes:
400 Invalid request
401 Invalid or missing credentials
403 User not authorized to perform this operation
404 Not Found
Fields and Objects
Field | Description |
---|---|
authenticationMethods | A list of authentication methods that consists of type and parameters fields. Typically, only one form of authentication is used (though it is possible to have two API keys or both an API key and OAuth2 authentication). Supported types are API_KEY, BASIC, OAUTH2, MTLS and AD_OAUTH2_CERT. |
authenticationMethods.parameters | The webhookAuthenticationMethod parameters. The fields of a parameters object vary for each authentication method. All fields are strings unless noted otherwise. See Authentication Method Fields for more information on the fields for each authentication method. |
configName | A unique name used to identify the push configuration. |
id | A unique identifier of the push configuration. Assigned by the push configuration API service and used for updates only. |
method | The HTTP method associated with the webhook endpoint. If not provided, will default to POST. Supported values: "GET" , "POST" , "PUT" , "PATCH" . |
methodParams | A map of optional method parameters. If provided, these will appear as query parameters on the URL. |
url | The URL of the webhook endpoint. |
version | An optional version of the push configuration. |
Retrieve a Webhook Configuration by Name
Requirements
Have the following information:
webhookName
Workflow
Complete these steps:
- Prepare a
GET
request to /api/v4/webhooks/name/{webhookName}. - Send the request.
Expected Response
You have successfully submitted the request when you receive a 200 OK
response. Here is a sample of the minimum response schema:
{ "authParams": {}, "authType": "API_KEY", "authenticationMethods": [ { "parameters": {}, "type": "API_KEY" } ], "configName": "string", "id": 0, "method": "GET", "methodParams": {}, "payloadFormat": "JSON", "url": "string", "version": 0 }
Errors
If there was a problem with your request, you will receive one of the following error codes:
400 Invalid request
401 Invalid or missing credentials
403 User not authorized to perform this operation
404 Not Found
Retrieve All Webhook Configurations
Workflow
Complete these steps:
- Prepare a
GET
request to /api/v4/webhooks. - Send the request.
Expected Response
You have successfully submitted the request when you receive a 200 OK
response. Here is a sample of the minimum response schema:
{ "webhookEndpoints": [ { "authParams": {}, "authType": "API_KEY", "authenticationMethods": [ { "parameters": {}, "type": "API_KEY" } ], "configName": "string", "id": 0, "method": "GET", "methodParams": {}, "payloadFormat": "JSON", "url": "string", "version": 0 } ] }
Errors
If there was a problem with your request, you will receive one of the following error codes:
400 Invalid request
401 Invalid or missing credentials
403 User not authorized to perform this operation
404 Not Found
Authentication Method Fields
API Key authentication
A new HTTP header is created for each supplied api key (max 2).
api_key_name
: the name of the API Key.api_key_value
: the value of the API Key.
Example Payload with API Key Authentication Method
{ "configName": "{configName}", "url": "{url to invoke}", "method": "POST", "methodParams": {}, "authType": "API_KEY", "authenticationMethods": [ { "parameters": { "api_key_name": "{key name}", "api_key": "{api key}" }, "type": "API_KEY" } ] }
Basic authentication
Applied to the 'Authorization' header with the 'Basic' identifier. Values are concatenated (with a separating colon character) and encoded to base64.
username
: username for authentication.password
: password for authentication.
Example Payload with Basic Authentication Method
{ "configName": "{config name}", "url": "{url to invoke}", "method": "POST", "methodParams": {}, "authenticationMethods": [ { "parameters": { "password": "{password}", "username": "{username}" }, "type": "BASIC" } ] }
OAuth2 authentication
The OAuth2 bearer token is generated then applied to the 'Authorization' header with the 'Bearer' identifier. The generated token will be cached, and refreshed after expiry.
grantType
: Type of authentication granted to the OAuth2 provider. Currently only 'client_credentials' is supported.accessTokenUri
: endpoint used to grant the bearer token.clientId
: unique client identifier.clientSecret
: authentication key for the client; functionally similar to a password.clientAuthenticationScheme
: identifies whether the OAuth2 fields are supplied to the authorization granter in the header or the request body. Accepted values areheader
andform
. A header will be added as 'Content-Type: application/x-www-form-urlencoded'.extraParams
: Optional - An object containing additional fields to be added to the request to the access token provider.
Example Payload with OAuth2 Authentication Method
{ "configName": "{config name}", "url": "{url to invoke}", "method": "POST", "authenticationMethods": [ { "type": "OAUTH2", "parameters": { "accessTokenUri": "{auth endpoint to generate token}", "clientSecret": "xxx", "clientId": "xxx", "clientAuthenticationScheme": "form", //form or header "grantType": "client_credentials" } } ] }
Mutual TLS authentication
Mutual TLS relies on a two-way handshaking when establishing an HTTPS connection. After the client verifies the server certificate (as normal in TLS), the server requests a certificate from the client and verifies it. This way both the client and server are authenticated to each other.
In addition, MTLS also allows the client to "trust" specific endpoints, allowing the webhook to be hosted on a server with a self-signed certificate. The trusted endpoint's CA certificate is provided along with the client cert and key.
MTLS authentication uses a significantly simpler configuration than OAUth2. All that is required is the client certificate chain (usually a single cert, but may have more than one), the private key, and an (optional) trusted CA certificate.
See PEM Format for more information how to encode certificates.
Example Payload with Mutual TLS Authentication Method
{ "configName": "{config name}", "url": "{url to invoke}", "method": "POST", "authenticationMethods": [ { "type": "MTLS", "parameters": { "pemCertificateChain": "<pem-formatted client cert(s)>", "pemPrivateKey": "<pem-formatted private key>", "pemEndpointCertificate": "<pem-formatted trusted CA cert>" } } ] }
Azure cert-based OAuth2 authentication
This authentication type uses the Azure certificate-based OAuth2 implementation documented here.
The parameters
payload for AD_OAUTH2_CERT is an extension of the OAUTH2 payload, with a couple of new fields added to support the certificate.
The AD_OAUTH2_CERT authorization is very complex, and requires strict rules on the values passed in.
See PEM Format for more information how to encode certificates.
Example Payload with Azure Cert-Based OAuth2 Authentication Method
{ "configName": "{config name}", "url": "{url to invoke}", "method": "POST", "authenticationMethods": [ { "type": "AD_OAUTH2_CERT", "parameters": { "grantType": "client_credentials", "accessTokenUri": "<Url for generating access token>", "clientId": "<Microsoft client ID>", "tokenName": "client_assertion", "scope": [ "<OAuth2 scope>" ], "extraHeaders": {}, "extraParams": { "audience": "https://login.microsoftonline.com/<Microsoft Tenant Id>/oauth2/v2.0/token", "tenant": "<Microsoft Tenant Id>" }, "clientAuthenticationScheme": "header", "authorizationScheme": "header", "pemCertificate": "<PEM-formatted cert...>", "pemPrivateKey": "<PEM-formatted key...>" } } ] }
PEM format
Because we are dealing with ReST APIs, all certificate and key information must be provided in PEM format.
PEM is a textual format that is a base-64 encoding of the binary data. All of the certificate processing tools support PEM files for both input and output, so it is simple to extract PEM-based resources from other formats.
For example, to extract a PEM-formatted certificate from a PKCS12 (.pfx
) archive, you can use the open-source openssl
tool:
openssl pkcs12 -in certname.pfx -nokeys -out cert.pem
Likewise, to extract the private key use:
openssl pkcs12 -in certname.pfx -nocerts -out key.pem -nodes
Encoding of PEM resources
Standard PEM data looks something like this:
-----BEGIN CERTIFICATE----- MIIDUDCCAjigAwIBAgIQeUL2u4TVSW6mA/vZ9ErD6DANBgkqhkiG9w0BAQsFADAl MSMwIQYDVQQDExpNU0MtT2NlYW5JbnNpZ2h0c1Byb2plY3Q0NDAeFw0yMjA2Mjgw [... many, many lines removed...] zYTtADSP+ntsjphz1/lXZq9pMq/lcNLipxjSlIlEYxH3/UKV -----END CERTIFICATE-----
There may be multiple sections in a PEM file, with individual resources marked with BEGIN/END blocks as shown above. Unfortunately, because of these markers, the line breaks are important. Since JSON ignores newlines, we will need a way to encode these in our JSON payloads.
We deal with this by encoding newlines with a \n
delimiter. Since the base64-encoded contents will ignore whitespace, the block between the begin and end markers can be a single string.
For example, encoding the certificate above with a \n
delimiter would use in something like this:
{ "certificate" : "-----BEGIN CERTIFICATE-----\n MII ... lots of characters removed ... KJ=\n -----END CERTIFICATE-----\n" }
Additional Information
Webhook Configuration Examples
- Azure Integration: Using Shared Access Signatures (SAS)
{ "configName": "{config name}", "url": "https://{azure application or service}?sr={service resource}&sig={signature}&se={expiration time}&skn={shared access key name}", "method": "POST", "methodParams": {}, "methodHeaders": {}, "authenticationMethods": [], "payloadFormat": "JSON" }
Push Retry Logic
It is expected that webhooks will not always have 100% uptime. To address this our system will queue up messages for later retries if they can't be delivered.
While the client’s webhook is up and receiving requests, pushes will be sent as soon as they are available. When the client’s webhook goes down, the project44 system will detect the outage and begin queuing up any messages targeted for that webhook. It will retry connecting every few minutes to detect when the client webhook is back online. Once back online, the system will resume from where it was last successful and push its queue of messages to the client’s webhook. Messages will be delivered in the same order which they were originally intended to be delivered.
How are different HTTP status codes handled?
The system will not retry all errors because there are certain errors that are expected rejections. Various response codes from the webhook indicate a failure which cannot be resolved by retrying such as the data being rejected. The table below indicates which http status codes and error conditions are treated as a success, retriable error, or non-retriable error. The behavior described applies to any of the retriable responses:
Type of Response | HTTP Status Codes | Retry Behavior |
---|---|---|
Successful delivery | Any 2xx status code (including but not limited to):
| Mark the message as delivered and proceed to the next message(s) |
Retriable responses |
| Detect that the webhook is down and begin retrying. All other unsent messages will enqueue behind this message and wait until this message succeeds or expires before they are sent. |
Non-Retriable responses | Any 3xx status code (redirects will not be followed). Any other 4xx status codes (including but not limited to):
| Mark the message as failed and proceed to the next message(s). These messages will not be retried. |
How Long Will project44 Hold My Data For?
project44 will hold messages in a queue to be retried for up to 48 hours. After this time, the message will expire and the system will move onto the next message in the queue.
Webhook Recommendations
Webhook Response Time
project44 recommends that your webhook returns a response within a few seconds, however we will wait up to 20 seconds before we consider the request timed out. Once the message has timed out, it will be retried in a few minutes and will keep being retrying until the message is successfully delivered or expires after 48 hours. Since messages must be delivered in order, any messages that timeout may delay later messages being sent to the webhook.
The common recommendation is to acknowledge the receipt of messages before any processing on your side.
Concurrent Requests
When possible, project44 may send concurrent requests to your webhook for messages that don't need to be sent in order. For example, position updates for two unrelated shipments may be sent at the same time. This allows for lower latency between project44 and your webhook. project44 recommends your webhook support up to 12 concurrent requests for best throughput and lowest latency data.
Delivery Semantics
project44 recommends your webhook be idempotent. This means that the same message can be sent to your webhook more than once and not cause any duplicate data. Under normal circumstances project44 will not send the same message twice if we get a successful response back but there could be cases where a response was not received, such as an unexpected network failure, that will cause the message to be sent again.