Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

Introduction

This document explains how to connect to Ably and receive “push feeds” where messages are sent by Genius Sports to clients as sporting actions occur. E.g. a message may describe a goal being scored or a sporting fixture starting.

A catalog of available feeds may be found in API Explorer for Genius Ably Push Feeds which describes the available data in detail.

Terminology

  • Ably Channel - Channels are the medium through which messages are distributed. Clients attach to channels to subscribe to messages, and every message published to a unique channel is broadcast by Ably to all subscribers. This messaging pattern is commonly called the https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern. You can read more about Ably Channels here.

  • Access Token - Ably’s authentication token required to establish a connection with Ably. You can learn more about this /wiki/spaces/FEED/pages/3248259146.

  • Client Library - Ably’s public open-source SDKs provided to clients to simplify the software development work required by users of Ably. More information is available here.

Technology Overview

The API is implemented using the Ably platform. Ably acts as a high-performance communication hub between Genius Sports and clients of the API around the World.

Getting Started

The example code we show throughout this document is in C#. Ably supports many different programming languages and has documentation on the Ably Website including example code for each of them.

This section describes the steps needed to connect to Ably and receive messages.

The easiest way to consume messages from Ably is to download the Ably client-side library for your language of choice.

For example if using Visual Studio and .Net (C#) you can install the library using the following command in Visual Studio’s Package Manager Console:

Install-Package ably.io

The example .Net code below requires the following Ably namespaces:

using IO.Ably;
using IO.Ably.Realtime;

It is also possible to connect directly without using Ably’s own libraries and more information about that is available here.

Before you can start using the code below you will need to get the following secrets from Genius Sports Support Team:

  • Client ID

  • Client Secret

  • API Key

1. Obtaining an Access Token for the Match State Platform API

First, you will need to get an access token for the Match State Platform API.

var url = "https://auth.api.geniussports.com/oauth2/token";
var body = new Dictionary<string, string> {
	{"grant_type", "client_credentials"},
	{"client_id", "CLIENT_ID"},
	{"client_secret", "CLIENT_SECRET"}
};

var httpClient = new HttpClient();
var response = await httpClient.PostAsync(url, new FormUrlEncodedContent(body));
var responseBody = await response.Content.ReadAsStringAsync();

var tokenEnvelope = JsonConvert.DeserializeObject<JObject>(responseBody);
var accessToken = tokenEnvelope["access_token"].ToString();

2. Consuming the Fixture Schedule

To be able to connect to Ably channel you will need to know the Fixture ID. You can get the fixtures with available feeds using the MS Platform Schedule API.

var sourceId = "GeniusPremium";
var sportId = 17; // American Football
var from = DateTime.UtcNow.ToString("s");
var to = DateTime.UtcNow.AddDays(2).ToString("s");
var baseUrl = "https://platform.matchstate.api.geniussports.com/api/v1";
var url = $"{baseUrl}/sources/{sourceId}/sports/{sportId}/schedule?from={from}&to={to}";

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Authorization", "{ACCESS_TOKEN}");
httpClient.DefaultRequestHeaders.Add("x-api-key", "{API_KEY}");

var response = await httpClient.GetAsync(url);
var responseBody = await response.Content.ReadAsStringAsync();

var schedule = JsonConvert.DeserializeObject<JArray>(responseBody);
var fixtureId = schedule[0]["fixtureId"].ToString();

3. Obtaining an Ably Access Token and a Channel Name

Now when you have a {FIXTURE_ID} you will need to call the appropriate endpoint as described in Match State Platform Access Control API to get the Ably Channel Name and Ably Access Token.

Important: The FIXTURE_ID should be scheduled in a period of 7 days in the future, by the MS Platform Schedule API in order for the Access Control API to return a channel & token.

async Task<(string channelName, string accessToken)> GetAblyFeed()
{
    var sourceId = "GeniusPremium";
    var sportId = 17; // American Football
    var fixtureId = "{FIXTURE_ID}";
    var baseUrl = "https://platform.matchstate.api.geniussports.com/api/v1";
    var url = $"{baseUrl}/sources/{sourceId}/sports/{sportId}/fixtures/{fixtureId}/liveaccess";
    
    var httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Add("Authorization", "{ACCESS_TOKEN}");
    httpClient.DefaultRequestHeaders.Add("x-api-key", "{API_KEY}");
    
    var response = await httpClient.GetAsync(url);
    var responseBody = await response.Content.ReadAsStringAsync();
    
    var ablyFeed = JsonConvert.DeserializeObject<JObject>(responseBody);
    var ablyChannelName = ablyFeed["channelName"].ToString();
    var ablyAccessToken = ablyFeed["accessToken"].ToString();
    return (ablyChannelName, ablyAccessToken);
}

4. Refreshing an Ably Access Token

An Ably Access Token will normally expire after some time. To handle that problem you will need to implement the method that Ably Client will call to refresh the token:

async Task<object> AblyAuthCallback(TokenParams arg)
{
    (_, string accessToken) = await GetAblyFeed();
    return new TokenDetails
    {
        Token = accessToken
    };
}

5. Connecting to Ably and Subscribing to a Channel

Now everything is ready to start listening for the Match State.

(string ablyChannelName, string ablyAccessToken) = GetAblyFeed(); // Code sample (3)

var ably = new AblyRealtime(new ClientOptions 
{
	Token = ablyAccessToken,
	AuthCallback = AblyAuthCallback, // Code sample (4)
	Environment = "geniussports",
	FallbackHosts = new string[]
	{
		"geniussports-a-fallback.ably-realtime.com",
		"geniussports-b-fallback.ably-realtime.com",
		"geniussports-c-fallback.ably-realtime.com",
		"geniussports-d-fallback.ably-realtime.com",
		"geniussports-e-fallback.ably-realtime.com"
	}
});

IRealtimeChannel channel = ably.Channels.Get(ablyChannelName);
channel.Subscribe(message => {
  Console.WriteLine($"Message: {message.Name}:{message.Data} received");
});

See API Explorer for Genius Ably Push Feeds for information about the available channels, their names, and message formats.

More information and examples of how to subscribe to channels can be found in the official ReadMe files in Ably’s GitHub account for the downloaded SDK.

Technical Details

Environments and Ably

Genius Sports provides the following Ably environments for customer use:

  • Production

  • UAT

Which Ably environment a client connects to is determined by the Access Token so please take care to use the correct key for each environment.

API Changes and Versioning

From time to time Genius Sports may make changes to the format of the data provided through its API. Where possible these changes will be made in a non-breaking additive manner. Clients of the contract should be notified, and if they are not interested in the new fields they can simply ignore them.

On rare occasions, a breaking change to the contract may be required. This will be done in a rolling update manner with the older and newer version of the contract published simultaneously in different Ably channels for a pre-defined period in order to provide users of the contract time to upgrade before the old contract channel is turned off.

Monitoring Feed Liveness and Data Reliability

Monitoring your connection to Ably

The AblyRealtime object that is returned when connecting to Ably exposes a property Connection. The Connection exposes an On method that allows the client to subscribe to channel events such as: Initialized, Connecting, Connected, Disconnected, Suspended, Closing, Closed, Failed

var ably = new AblyRealtime(new ClientOptions 
{
	Token = "{ABLY_ACCESS_TOKEN}",
	AuthCallback = AblyAuthCallback,
	Environment = "geniussports",
	FallbackHosts = new string[]
	{
		"geniussports-a-fallback.ably-realtime.com",
		"geniussports-b-fallback.ably-realtime.com",
		"geniussports-c-fallback.ably-realtime.com",
		"geniussports-d-fallback.ably-realtime.com",
		"geniussports-e-fallback.ably-realtime.com"
	}
});

ably.Connection.On(ConnectionState.Disconnected, args => {
  Console.WriteLine("Disconnected");
});

ably.Connection.On(ConnectionState.Suspended, args => {
  Console.WriteLine("Suspended");
});

The Connection exposes another property State, having one of the following values: Initialized, Connecting, Connected, Disconnected, Suspended, Closing, Closed, Failed.

Any other state than Connected means that the connection to Ably is lost. This property is constantly updated by the client-side library.

For more details consult Ably’s documentation.

Message Expiry

By default, a message will be available to be consumed from a channel for two minutes from publication. This means consumers experiencing brief connection drops will not miss any messages. If a consumer is offline for more than two minutes they can either:

  • Simply wait for the next message to be published if the messages they are consuming are complete in themselves, rather than being event-based

  • Request the latest information from the appropriate REST API i.e. essentially using the REST API as a bootstrap mechanism.

Technical Support

Support Contact Details

To get a Client Id, Client Secret and API Key please contact: apikey@geniussports.com

For technical support for an integrating customer please contact customerintegrations@geniussports.com. For live customers please contact, Genius Sports Support Team at the following address: support@geniussports.com.

Frequently Asked Questions

Why did Genius Sports select Ably as the technology to deliver a Push API for clients?

Ably provides market-leading technology for worldwide, low latency, highly resilient message delivery. Ably supports many different programming languages through its client libraries and also supports direct access through Web Sockets for customers who prefer to write their own access logic.

How do I obtain a client library to connect to Ably?

Following the Ably documentation the users can download the client-side library for the language of their choice from here.

For example, Genius Sports uses the following client-side library itself for .Net https://github.com/ably/ably-dotnet version 1.2

What Operating Systems and Languages does Ably support?

Any OS that supports the client-side libraries. In our case, these are all major OPs - Windows, Linux, Macintosh. The Ably Realtime client library is available in the most popular languages and platforms including JavaScript, iOS, Android, Java, .NET, Node.js, Ruby, and more.

  • No labels