Skip to navigation

Overview

Events are a way of being notified of important actions happening within an organization. For example, Polytomic will create a sync.completed event any time a sync finishes. These events are accessible via the events API. We also offer the ability to set up outgoing webhooks which will send realtime events as they happen.

Polytomic is designed for at most once delivery, which means we may fail to send some events. Additionally, events cannot be re-sent once they have been delivered. Therefore, if your use case demands a high level of assurance that all changes to a resource are processed without any missing events, we advise building a fallback polling system that periodically fetches the desired events using the events endpoint.

Retention


Events accessible via the events endpoint are persisted for 48 hours, after which they will not be available.

Event Types

Each event type has its own page with the conditions that fire it, its fields, and an example payload.

Webhooks

Webooks can be set up using the webhook API endpoints. Each webhook will fire events for the organization in which it exists. Currently, only one webhook per organization is allowed.

HMAC Validation

HMAC validation can be used to ensure the events you receive are legitimate. When creating or updating a webook, there’s a required secret field. Polytomic will hash each message and include a Polytomic-Signature header in each POST using that secret. You can use the secret field to validate that the signature matches.

Delivery

We require that the endpoint returns a 2xx response code. If a 2xx is not returned, the event will be retried 5 times with exponential backoff. There are no guarantees around ordering.

Record logs

The sync.completed event includes logs_url, the endpoint that returns an index of the record logs the execution produced.

Consuming Events

Below is a brief example (written in Go) of consuming events from a webhook:

package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"io/ioutil"
"net/http"
"github.com/gin-gonic/gin"
)
var key = []byte("somepassword")
func main() {
r := gin.Default()
r.POST("/webhook", func(c *gin.Context) {
body, _ := ioutil.ReadAll(c.Request.Body)
hash := c.Request.Header.Get("Polytomic-Signature")
sig, err := hex.DecodeString(hash)
if err != nil {
panic(err)
}
mac := hmac.New(sha256.New, key)
mac.Write(body)
if !hmac.Equal(sig, mac.Sum(nil)) {
panic("Invalid signature")
}
fmt.Printf("Headers: %+v, Body: %s", c.Request.Header, string(body))
c.Status(http.StatusOK)
})
r.Run("0.0.0.0:8000")
}