You can use Webhooks to subscribe to certain events when they occur. Webhooks provide a way to respond to real-time events as they happen without having to constantly poll the API. When an event occurs that matches your webhook scope, a POST HTTP request will be sent to your webhook URL.

Setup

To quickly get started testing webhooks, you can use something like RequestBin to inspect and explore the payload.

Check out the Core API Reference on how to create a webhook.

Retries

The POST HTTP request to your URL expects an HTTP 200 response code. Any other response code that is not exactly a 200 will result in the Webhook to retry with an exponential backoff strategy.

Scopes

Scope

Description

Matches all events.

project.*

Matches all project events.

project.created

Fires when a project is created.

project.updated

Fires when a project is updated.

project.label_added

Fires when a label is added to a project

photo.*

Matches all photo events.

photo.created

Fires when a photo is created and processed by our system.

photo.updated

Fires when any edits (annotations) are made to a photo.

photo.tag_added

Fires when a tag is added to a photo

comment.*

Matches all comment events.

comment.created

Fires when a new comment is created.

document.*

Matches all document events

document.created

Fires when a document is created for a project

video.*

Matches all video events

video.created

Fires when a video is created for a project

todo_list.*

Matches all todo_list events

todo_list.created

Fires when a todo list is created

todo_list.completed

Fires when a todo list is completed

todo_list.deleted

Fires when a todo list is deleted

task.*

Matches all task events

task.completed

Fires when a task is completed

Example Response Body

{
  "event_type": "project.created" - (String) This will correspond to the event and scope that triggered the webhook.
  "created_at": 1661361759 - (Integer) This is the integer timestamp when the webhook request was sent.
  "payload": {...} - (Object) This is the object that corresponds to the event that occurred, and will typically match the structure of the associated object.  e.g. "project.*" webhook payloads will match the Project object.
  "webhook_id": 42 - (Integer) This is the id of the webhook object that the webhook request came from.
}

Validating your payload

Because your webhook URL is open to the public, for security reasons, we recommend validating that the request came from CompanyCam by using the token parameter you supplied calling the create webhook endpoint with the X-CompanyCam-Signature header from the event.

To validate that the data came from CompanyCam, you need to calculate the base64 encoded HMAC hash of the request body using the SHA1 algorithm and your webhook token as the key. If the value matches the header's signature, you can be sure the request was sent from CompanyCam.

const crypto = require('crypto');
const webhookToken = 'YOUR_WEBHOOK_TOKEN';

function validateFrontSignature(data, signature) {
    var hash = crypto.createHmac('sha1', webhookToken)
                     .update(JSON.stringify(data))
                     .digest('base64');

   return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(signature));
}

Did this page help you?