Using Liminal Webhooks to Register for Updates 

API Hub Documentation

  • Getting Started with the API Hub

  • Getting Started with Carriers

  • Using Liminal APIs 

  • Status & Image APIs with Webhook Calls

  • Fetching Status from the RESTful API 

With our webhooks, instead of polling our RESTful APIs to determine current shipment status or to fetch document images, you can have Liminal Network send you status updates and/or document images as they become available. 

For Final Mile Photos Webhooks visit: https://account.liminalnetwork.com/account/notify-webhook for more options and a web-based interface. 

For any carrier you have configured with your API key we will automatically call your specified carrier on your behalf approximately once per hour, reporting one of your expected statuses or changes. We’ll start with a sample URL and some code. 

For server-side webhooks and data insertion, as well as client interactions, we will do this using SQLite and Python 3.9+ for availability on the widest variety of development platforms (all OS X, Linux, and Windows dev environments should have functional Python 3.9+ installs available from python.org or your platform’s vendor, potentially already installed). 

If you would like to follow along with fully-annotated source code, please feel free to download the gist at Github.

Let’s get started with a templated URL fetched using Python standard library tools. 

url = "https://api.liminalnetwork.com/{scac}/{method}?pro={pro}&auth={api_key}" 

def register_hook(scac: str, url_or_email: str, status: str, pro: str = "", bol: str = "", tracking: str = "") -> Union[str, dict]: 
    assert pro or bol or tracking 
    base = url.format( 
        scac=scac, 
        method="webhook", 
        pro=pro, 
        api_key=settings.LIMINAL_NETWORK_API_KEY, 
    ) + "&" + urllib.parse.urlencode({"status": status}) 

    if "//" in url_or_email: 
        base += "&" + urllib.parse.urlencode({"webhook": url_or_email}) 
    else: 
        base += "&" + urllib.parse.urlencode({"email": url_or_email}) 

    # handle pro vs bol vs tracking 
    if not pro: 
        # one of the other two should be valid 
        rep = ("bol=" + bol) if bol else ("tracking=" + tracking) 
        base = base.replace("pro=", rep, 1) 

    ret = json.loads(urllib.request.urlopen(full_url).read().decode()) 
    if "webhook_id" in ret: 
        return ret["webhook_id"] 
    
 return ret

Much like the RESTful /status call, our call to /webhook requires a pro, tracking, or bol parameter to know which shipment to check on. We also require a specific status to wait for, or all . With all,  your webhook will receive all status changes, and any document images when they are available. You will want to check the available status messages from each carrier to know which ones to use for your needs. 

After registration, while the webhook is valid, Liminal Network will check the status of your shipment approximately once per hour and post to your listed URL with your requested statuses, encoded as application/json

You will also need to provide a contact method, whether that is an URL or an email. 

What kinds of URLs are enabled for webhooks? 

Your account at Liminal Network requires an email address, and all email addresses at your company must share the same domain name. For a webhook URL to be valid, your URL must share the same domain, or your URL must be a sub-domain of your email domain. 

As an example, let’s say that your registered account is [email protected], then some example valid urls would be: 

If there was an error while registering your webhook, the function we’ve defined above will return the error. For example, if you forgot to provide an url or email, you may see the error: 

{'errors': ['missing email or webhook']} 

Upon success, the function should return a webhook_id, which will look something like: 0_AARiQLWGVJn08tIZdKD5vJJ, and which you can use later to manually explicitly check shipment status while the webhook is valid: 

https://api.liminalnetwork.com/{webhook_id}

Cancelling a Webhook 

To cancel the webhook entirely while the webhook is valid: 

https://api.liminalnetwork.com/{webhook_id}/cancel

On successful cancelation, you should receive: 

{"canceled": "{webhook_id}"} 

What kinds of email addresses are valid for email hooks? 

Much like urls, email addresses for email must have the same domain or a subdomain of email addresses registered for your company. You may include +tags, and any user in the domain when registering an email hook. After registration, while the webhook is valid, Liminal Network will check the status of your shipment approximately once per hour, and email your provided address with your requested status updates. 

As another example, let’s say that your registered account is [email protected], you can register an email hook with the following email addresses: 

Similarly, on any error, you will receive an error message indicating the nature of the error, such as: 

{'errors': ['email domain is not example.com or *.example.com']} 

Upon success, the function should return a webhook_id, which will look something like: 0_AARiQLWGVJn08tIZdKD5vJJ, and which you can use later to manually explicitly check shipment status while the webhook is valid: 

https://api.liminalnetwork.com/{webhook_id}

Or cancel the webhook entirely while the webhook is valid: 

https://api.liminalnetwork.com/{webhook_id}/cancel

On successful cancelation, you should receive: 

{"canceled": "{webhook_id}"} 

Can I test my webhook url against the sandbox? 

Because the Sandbox doesn’t do user validation, we cannot verify which domain you are coming from, and as such, posting to your url doesn’t make much sense. The sandbox is primarily useful for testing your connectivity to Liminal Network and validating your flows before you move on to testing with real data. For a very simple test, you can make a direct request to see the full valid response. 

$ curl "https://api.liminalnetwork.com/sandbox/webhook?auth=qNAJFePYEfzZag1pDqv&pro=123456789&webhook=http://example.com/" 

{"webhook_id": "0_AARiQLWGVJn08tIZdKD5vJJ"}

Any webhook_id returned by the sandbox is only valid for a few seconds of real time. 

Sidebar: How does Liminal Network do this? 

When you register a webhook, we keep a temporary copy of your credentials encrypted in a way that only the specific webhook runner can decrypt. We combine this with your provided SCAC and reference number to perform /status checks and later image and document requests. 

Last Updated | October 3, 2024


Have questions or need some assistance, Drop us a note.

API Hub Documentation

  • Getting Started with the API Hub

  • Getting Started with Carriers

  • Using Liminal APIs 

  • Status & Image APIs with Webhook Calls

  • Fetching Status from the RESTful API