Web Hooks

You can set up webhooks to have Mixer call your web service when something interesting happens. You'll need to head to the OAuth Clients page on the dev lab and register a client with a secret key. You'll use this to register webhooks.

Want a more event-driven approach? Check out Constellation, our websocket-based pubsub service.

Registering an Event

You can register an event by calling POST /hooks with some details about what you want to subscribe to:

  • events should be a list of available events you want to receive;
  • kind must be set to web (this is required as we may choose to deliver hooks by carrier pigeon, in future iterations);
  • url should be the web address you want us to hit when the event happens;
  • you can optionally pass a secret string we'll use for signing requests to you, see Request Signing.

You'll also need to include your OAuth client ID in the Client-ID header, and your secret key in the Authorization header, in the form Secret somelongstring. All together, this is what a curl request to subscribe to the Mixer channel's broadcast events would look like:

curl -XPOST https://mixer.com/api/v1/hooks \
    -H Client-ID:da400f1a81d7efc477920b5d686e95be6f92c88af09c2342 \
    -H Authorization:'Secret c51ff3c4e44e7be32be2f639b28e3569f1775f8530b95a5d972ace2cb9310ab8' \
    -d '{ "kind": "web", "events":["channel:314:broadcast"], "url":"https://dev.mixer.com/onHook" }'

Receiving an Event

Mixer will make a POST request to the URL you provide. The body will look something like this:

{
    "event": "channel:314:broadcast",
    "payload": {
      "broadcastId": "9976edaf-c327-4560-a1cb-89425cb1131f"
    },
    "sentAt": "2018-02-07T01:36:30.5109036+00:00",
    "id": "7ddc8489-5afd-401d-83cc-49ea95fc9bba"
}
  • event is the name of the event you're getting;
  • payload is the data of the event, as described in the Available Events section;
  • sentAt is the time the event was originally sent;
  • id is a unique identifier for this event sent to you.

Mixer guarantees "at least once" delivery, meaning that if there's a failure somewhere along the line, you might get one event multiple times. In these scenarios, you can use the event id to deduplicate, if you need to.

The request you get will also contain several headers:

  • Poker-Nth-Retry is the number of times we have tried before this request to deliver the event to you;
  • Poker-Hook-Id is the webhook that's triggering this call to you;
  • Poker-Signature is the signature of the request body, see Request Signing.

Request Signing

If you provide a secret string, Mixer will sign requests sent to you. This can be useful to prevent adversaries who may stumble upon or otherwise discover your APIs from triggering fake events; the secret string is shared only between Mixer and yourself.

Mixer will use this as the key in a SHA384 HMAC to sign the body of the request, and you can check our computation. Here's how you would do it in several programming languages, if you have the raw request body as a string and your secret key:

import hmac

# Using Flask-style requests, you may need to adjust it :)
def is_request_valid(request, body: str, secret: str):
    hm = hmac.new(bytes(secret, 'utf-8'), digestmod='SHA384')
    hm.update(bytes(body, 'utf-8'))
    expected = 'sha384=' + hm.hexdigest().upper())
    return hmac.compare_digest(request.headers['poker-signature'], expected)

Here's an example of a full, signed request, that you can use to validate that your code works. The secret used for this request is verysecret.

HTTP/1.1 POST
Host: test.mixer.com:8888
Content-Type: application/json; charset=utf-8
Poker-Nth-retry: 0
Poker-Hook-Id: 6cd6fa9f-b9a5-45b6-bdf0-412fe7859dad
Poker-Signature: sha384=5EB3E48ED381446210D527AA1D88D9A5F36C840DD088665F35BEA51D3FA429837430E81973835774CC0AE69EEDE6AAE7
Content-Length: 183
Connection: Keep-Alive

{"event":"channel:314:update","id":"96445358-d5b1-417e-a9ac-57f1cb001916","payload":{"broacastId":"9976edaf-c327-4560-a1cb-89425cb1131f"},"sentAt":"2018-02-08T03:28:06.8605874+00:00"}

Request Retries

If your server does not return a 2xx response code, Mixer will try to send the hook to you again for several minutes before giving up. If your endpoint consistently fails, your webhook may be automatically disabled. Currently, this can happen when either:

  • 1000 requests in a row to your endpoint fail, or;
  • no requests succeed for at least a week, and we send at least 10 requests.

These conditions are subject to change, but for the most part, if your service has a least one "9" of availability, you don't need to worry. You can always check the status of a webhook, given its ID, by hitting GET /hooks/{hookId}.

Limits and Renewals

We have a per-account limit on the number of webhooks you may register. Right now, the limit is 1450000. Because webhooks are a new system for Mixer, we're ramping up the limits gradually over time. Starting at 00:00:00 2018-02-17 UTC, all developers were given a base limit of `100,000 webhooks. This limit is increased by 50,000 every seven days afterwards, to a maximum of 3,000,000.

By default, webhooks expire after 90 days unless they're renewed using POST /hooks/{hookId}/renew. The exact renewal date is returned in the webhook after it's created, for example:

{
    "deactivationReason": null,
    "events": [
      "channel:314:broadcast"
    ],
    "id": "875829e3-52c5-4976-a053-2861d8c3bc79",
    "isActive": true,
    "kind": "web",
    "url": "https://dev.mixer.com/onHook",
    "expiresAt": "2018-05-17T00:30:06.1751718+00:00",
    "renewUrl": "https://mixer.com/api/v1/hooks/875829e3-52c5-4976-a053-2861d8c3bc79/renew"
}

We provide several other APIs you can use to manage your registered webhooks. You can read more about them in our API docs in the REST Reference.

Available Events

The available events to register for web hooks match our constellation live events. To see a list of available events. Please checkout the live events section of our constellation reference here