- Introduction to Data
- Track your video performance
- Make API requests
- Setup alerts
- Make your data actionable with metadata
- Track autoplaying videos
- Extend Data with custom metadata
- Track CDN for request metrics
- See how many people are watching
- Build a custom integration
- Understand metric definitions
- Export raw video view data
- Ensure privacy compliance
- Mux Data FAQs
See how many people are watching
Learn how to get the latest view and unique viewer counts for a video.
In this guide:
In this guide you will learn how to use the Real-time Engagement Counts BETA API in order to embed the latest view and unique viewer counts for a particular video ID into your applications.
You will use JSON Web Tokens to authenticate to this API.
Signing keys can be managed (created, deleted, listed) either from the dashboard or via the Mux System API.
When creating a new signing key, the API will generate a 2048-bit RSA key pair and return the private key and a generated key ID; the public key will be stored at Mux to validate signed tokens. Store the private key in a secure manner.
You probably only need one signing key active at a time and can use the same signing key when requesting counts for multiple videos. However, you can create multiple signing keys to enable key rotation, creating a new key and deleting the old only after any existing signed URLs have expired.
Request:
curl -X POST \ -H "Content-Type: application/json" \ -u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET} \ 'https://api.mux.com/system/v1/signing-keys?product=data'
Response
// POST https://api.mux.com/system/v1/signing-keys { "data": { "private_key": "(base64-encoded PEM file with private key)", "id": "(unique signing-key identifier)", "created_at": "(UNIX Epoch seconds)” } }
This can also be done manually via the UI. If you choose to create and download your signing key as a PEM file from UI, you will need to base64 encode it before using it with (most) libraries.
❯ cat /path/to/file/my_signing_key.pem | base64 LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktL...
The following JWT claims are required:
Claim Code | Description | Value |
---|---|---|
sub | Subject of the JWT | The ID for which counts will be returned |
aud | Audience (identifier type) | video_id (Mux Data Video ID) asset_id (Mux Video Asset ID) playback_id (Mux Video Playback ID) live_stream_id (Mux Video Live Stream ID) |
exp | Expiration time | UNIX Epoch seconds when the token expires. Use this to ensure any tokens that are distributed become invalid after a period of time. |
kid | Key Identifier | Key ID returned when signing key was created |
Expiration time
Expiration time should be at least the duration of the video or the expected duration of the live stream. When the signed URL expires, you will no longer receive counts from the API.
Your application should consider cases where the user loads a video, leaves your application, then comes back later at some time in the future and tries to play the video again. You will likely want to detect this behavior and make sure you fetch a new signed URL to make sure the counts that are displayed in your application continue to display.
The steps can be summarized as:
- Load the private key used for signing
- Assemble the claims (
sub
,aud
,exp
,kid
etc) in a map - Encode and sign the JWT using the claims map and private key and the RS256 algorithm.
There are dozens of software libraries for creating and reading JWTs. Whether you’re writing in Go, Elixir, Ruby, or a dozen other languages, don’t fret, there’s probably a JWT library that you can rely on. For a list of open source libraries to use, check out jwt.io.
package main
import (
"encoding/base64"
"fmt"
"log"
"time"
"github.com/dgrijalva/jwt-go"
)
func main() {
myId := "" // Enter the id for which you would like to get counts here
myIdType := "" // Enter the type of ID provided in my_id; one of video_id | asset_id | playback_id | live_stream_id
keyId := "" // Enter your signing key id here
key := "" // Enter your base64 encoded private key here
decodedKey, err := base64.StdEncoding.DecodeString(key)
if err != nil {
log.Fatalf("Could not base64 decode private key: %v", err)
}
signKey, err := jwt.ParseRSAPrivateKeyFromPEM(decodedKey)
if err != nil {
log.Fatalf("Could not parse RSA private key: %v", err)
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
"sub": myId,
"aud": myIdType,
"exp": time.Now().Add(time.Minute * 15).Unix(),
"kid": keyId,
})
tokenString, err := token.SignedString(signKey)
if err != nil {
log.Fatalf("Could not generate token: %v", err)
}
fmt.Println(tokenString)
}
Supply the JWT in the resource URL using the token
query parameter. The API will inspect and validate the JWT to make sure the request is allowed.
Example:
curl 'https://stats.mux.com/counts?token={JWT}'
Response:
{"data": [{"views": 95, "viewers": 94, "updated_at": "2021-09-28T18:21:19Z"}]}