Register a webhook

POST https://api.imageintelligence.com/v2/webhooks

Registers a webhook to receive events such as IDENTITY_CREATED or IDENTITY_UPDATED (these are the only 2 events supported right now). You can read more about webhooks here.

As of writing this, webhooks is still in BETA. You are only able to register a webhook once and cannot deregister. Please contact support if you need help with deregistering a webhook.

Webhooks are namespaced by organizationId/application pairs. For example, you may have an organization named ACME but have applications for Development, Staging, and Production. Each pair can be isolated such that webhooks from one application do not overlap with webhooks in another.

Verifying webhooks

Webhooks can also be cryptographically signed if a secretKey was registered along with the callback url.

Http/1.1
Content-Length: ...
Content-Type: application/json
X-Niro-Signature: ...
...
{
   ...payload
}
...

Using the X-Niro-Signature header, webhook request payload, and your specified secretKey you can verify that the request was sent from our API. Here's an example in JavaScript, on how you might verify a request:

const crypto = require("crypto");
const webhookRequest = {
  headers: {
    "X-Niro-Signature": "sha=58e581b0643a56967676d8663a4e9cb389597a25",
    "Content-Type": "application/json"
  },
  body: {
    example_id: "1"
  }
};
const secretKey = "jknjknwefbhjghui289whuuh28y02y892y8f/S/zsefzgskjzdrbkg";

// When you receive a request, you want to verify if it is valid.
const hmac = crypto.createHmac("sha256", secretKey);
const comparisonSignature = `sha256=${hmac.update(JSON.stringify(webhookRequest.body)).digest("hex")}`;

// Finally, perform a constant time comparison to avoid timing attacks.
const source = Buffer.from(webhookRequest.headers["X-II-Signature"]);
const comparison = Buffer.from(comparisonSignature);
console.log(crypto.timingSafeEqual(source, comparison));
  • Signatures are encrypted using sha256

Webhook payload

The payload you receive from events throughout our API will vary depending on the type. For convenience, we wrap all requests into an envelope, encasing the data field. Here's an example:

{
  "type": "IDENTITY_CREATED",
  "data": {
    ...
  }
}
  • As mentioned earlier there are only 2 supported event types, IDENTITY_CREATED and IDENTITY_UPDATED. The data component for each event will follow the same shape as a call to GET /identities/{namespace}/{id}.

Request Parameters

NameInDescription
url
required
bodystring

Publicly accessible POST endpoint for receiving events from the API

Max Length: 2048

secretKey
optional
bodystring

Private key used to cryptographically sign the webhook request payload

Min Length: 8, Max Length: 256

Request Sample

{
  "url": "https://api.acme.com/callbacks",
  "secretKey": "lYIzEz2xkJmvJosjXO0T8ZEnDhPjTtBTcErTv9hM0MX86w0UShSQ9qEXC3Fc6SJA"
}

Response Parameters

Successfully registered a webhook

id
required
string
url
required
string
secretKey
optional
string
application
required
string
organizationId
required
string
createdAt
required
number

Response Sample

{
  "id": "c35eed26-2724-4823-871e-df29a44fbe69",
  "url": "https://api.acme.com/callbacks",
  "application": "test-app",
  "organizationId": "acme",
  "secretKey": "lYIzEz2xkJmvJosjXO0T8ZEnDhPjTtBTcErTv9hM0MX86w0UShSQ9qEXC3Fc6SJA",
  "createdAt": 1553053749994
}