Table of Contents

Webhooks

A webhook is a method of automatically triggering calls to the server when an event happens in the browser.

Webhooks are helpful for implementing complex workflows that require quick response times, such as real-time labeling. Instead of polling the API for static data, webhooks allow subscriptions to the data when certain actions in the browser are performed — leading to “notifications” of these events.

Webhooks can be enabled organization-wide or on specific projects you choose.

Webhook integration

The request header, X-Hub-Signature, is used to verify that notifications are coming from Labelbox. When you create the webhook and the request body payload, this header is created using the secret you provide. A SHA-1 hash is created using the body and encrypted using the secret as a key. You can verify the webhook notification by creating your own SHA-1 hash using the payload and secret. Validating it is the same as in the header.

from flask import Flask, request
import json
import hmac
import hashlib
app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, World!'

# Make sure this is the same secret you provided in the webhook creation
secret = 'example_secret'

@app.route('/webhook-endpoint', methods=['POST'])
def print_webhook_info():
payload = request.data
computed_signature = hmac.new(secret, msg=payload, digestmod=hashlib.sha1).hexdigest()
if request.headers['X-Hub-Signature'] != 'sha1='+computed_signature:
print('Error: computed_signature does not match signature provided in the headers')
return 'Error'

print('=========== New Webook Delivery ============')
print('Delivery ID: %s' % request.headers['X-Labelbox-Id'])
print('Event: %s' % request.headers['X-Labelbox-Event'])
print('Payload: %s' % json.dumps(json.loads(payload.decode('utf8')),indent=4))
return 'Success'

if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000, debug=True)

When starting the above server, you should be able to visit http://0.0.0.0:3000 and see “Hello, World!”

However, Labelbox won’t be able to send messages to http://0.0.0.0:3000 because it’s on your local network.

You can either deploy this server or use ngrok which is a great tool that will provide a public HTTP proxy to your local endpoint.

ngrok http 0.0.0.0:3000
# You'll recieve a public endpoint I.E. https://83a053ae.ngrok.io

If you head to the project and create, update, or delete a label, a notification will be sent to the Python server you have created.

Create a webhook

A webhook is the main interface for subscribing to events that occur within Labelbox. On creation, provide the following values.

project.id (OPTIONAL)

A specific project that the notifications should apply to.

url

The URL endpoint notifications are sent to.

secret

A secret used to validate the request is coming from Labelbox.

topics

Events that a webhook can be subscribed to. The following topics are supported:

  • LABEL_CREATED
  • LABEL_UPDATED
  • LABEL_DELETED
  • REVIEW_CREATED
  • REVIEW_UPDATED

Then use this ngrok URL in the query below.

mutation CreateWebhook {
createWebhook(data:{
project:{
id:"<PROJECT_ID>"
},
url:"<HTTP_URL>",
secret:"example_secret",
topics:{set:[LABEL_CREATED, LABEL_UPDATED, LABEL_DELETED]}
# topics:{set:[REVIEW_CREATED, REVIEW_UPDATED]}
}){
id
}
}

Every time a webhook is triggered, Labelbox will send a POST payload with the relevant information. A notification will be recorded to capture the request and response itself, along with all relevant metadata about the POST. The notification includes the request header, request body, response headers, response body, and response code. This enables you to verify that webhooks are successfully sending data and to debug any potential issues when setting up webhooks.

Update a webhook

After verifying and when entering production, the following update query will change to the production URL.

mutation UpdateWebhook {
updateWebhook(where:{
id:"<WEBHOOK_ID>"
}, data:{
url:"<PRODUCTION_URL>",
}){
id
}
}

Remove a webhook

mutation{
updateWebhook(
data:{
status:INACTIVE
}
where:{
id:""
}
){
id
}
}

Was this page helpful?

Asset metadata

Contact