Smart Search API Guide


Smart Search is the only AI-powered search engine built for betting and gaming sites. It allows players to interact in a natural way with deep product catalogues providing lightning-fast search results. The product provides a number of key features:

Lightning-fast search results on any channel:

  • Opti-X's proprietary real-time indexing fast-tracks customers to results in 10ms
  • Includes pre-event, live betting and gaming results as standard

Accurate and personalised results from every search:

  • Spelling mistakes and typos auto-corrected as customers type
  • Opti-X's search engine functionality integrates customer's previous search history

From search to bet-slip or game launch in an instant:

  • Search results are returned with direct to betslip or game launch CTAs

Automatic recognition for multiple levels of search term:

  • Sports customers can search by sports, leagues, markets, events - event using local aliases for their favourite teams

Self-learning engine refines and improves results:

  • Search results and conversion data optimised to tailor results to each customer
  • Rules-based verification ensures search results are 100% relevant

Effortless and simple integration:

  • Straightforward inventory integration, often requiring zero operator effort
  • Quickest route to an enhanced customer experience to drive long-term retention

Inventory Integration

As a pre-requisite to search integration we require a (near) real-time view of the inventory to be searched. For Gaming this is the catalogue of games that are available and for sports it is the events, markets and selections that are currently available. There are numerous integration options to provide this information and it often involves limited operator effort. This integration is also required for other Opti-X products (e.g. Recommend or Intelligent Layouts). Details of how to integrate this data can be found in the Integration Guide.

Search Integration

Our Smart Search API provides an endpoint for retrieving results for a given query string. A front end widget is not currently provided (please ask if this is of interest) so front end components e.g. search box and results rendering should be created by the operator.

It is recommended to implement debouncing such that requests are only made to the search service after a small delay post last keyboard input as is best practice with search engines. Our experience suggests that 250ms works well. This avoids flickering results that will be distracting and non meaningful to someone typing quickly. Our search API will return results once at least two characters have been entered as the search term so it is not worth calling the API until this length has been achieved.

Authentication to the API is based on brand and API keys similar to other Opti-X APIs. Your keys can be found within Admin under Developer Tools>API Keys. These are required to be passed as headers in the API request.

CORS: If integrated directly on the front end (as will be the most common integration), as a 3rd party URL our API would trigger a CORS pre-flight OPTIONS request before returning results. This is an in-built security mechanism supported by most browsers. Pre-flight requests will be cached for at least 10 minutes (depending on browser support) which means subsequent OPTIONS requests will not be made.

Search

POST https://api.graphyte.ai/search/v1/query

Headers:x-api-key=api key given at integration
x-brand-key=unique reference for brand
content-type=application/json

Example payload:

{
  "context": {
     "product": "Sports", // or Gaming
     "category": "Football",
     "page": {
        "url": "sports.graphytesports.com",
        "title": "Football Home"
     },
     "channel": "Mobile"  // or Desktop or Tablet
  },
  "query": "tottenham price:2-5 orderby:time_desc",
  "userId": "12345",
  "type": "search"
}

Parameters:

context: Contextual information about the current location of the user

query: Query entered by the user

userId: User identifier if present. Should be the same ID as used for other Opti-X services to enable consistent personalisation

type: “search”

For any questions here please contact your Integration Manager.

Response objects will differ for Gaming and Sports. Search results can be large and by default are gzip compressed. Most libraries will automatically decompress the response for you.

Sports

Example response payload:

{
  "results": {
      "searchId": "5194365c-5b45-4da8-be63-a83eb1edde4f",
      "result_count":1161,
      "execution_time":9.758949279785156,
      "query":"sample query",
      "matched_tokens":["england"],
      "search_results":[
        {
          "categoryName":"Football",
            "classes":[
              {
                "className":"English",
                "types":[
                  {
                    "typeName":"Premier League",
                    "matched_events":[
                      {
                        "eventKey":"232906445",
                        "eventName":"Premier League 2021/22",
                        "eventDateTime":"2022-05-22 15:00:00+00:00",
                        "typeName":"Premier League",
                        "className":"English",
                        "categoryName":"Football",
                        "markets":[
                          {
                            "marketName":"Outright",
                            "marketKey":"527760570",
                            "selections":[
                              {
                                "selectionKey":"1318068704",
                                "selectionName":"Arsenal",
                                "denPrice":1,
                                "numPrice":50,
                                "selectionPriceType":"LP",
                                "decPrice":51.0,
                                "score":0.15245860815048218
                              } ....
                            ]
                          } ...
                        ]
                      } ...
                    ],
                    "matched_selections":[
                      {
                        "eventKey":"228046611",
                        "eventName":"World Cup 2022",
                        "eventDateTime":"2022-12-18 15:00:00+00:00",
                        "typeName":"World Cup",
                        "className":"International",
                        "categoryName":"Football",
                        "markets":[
                          {
                            "marketName":"Outright",
                            "marketKey":"378470883",
                            "selections":[
                              {...}...
                            ]
                          } ...
                        ]
                      } ...
                    ]
                  } ...
                ]
              } ...
            ]
          } ...
        ]
      }
    }
}

Response contents

searchId: unique search ID

result_count: number of returned items

execution_time: search time in ms

query: search query

matched_tokens: matched tokens - this is based on our partial matching technology. For example if you search “rom” it may match to “Roma”, “Roman”, “Romania”, etc.

search_results: a structured list of items from the hierarchy organised by category (e.g. sport), class (e.g. country) and type (e.g. competition) and then broken down into matched_events and matched_selections arrays. This shows search results for either events or bets respectively.

Gaming

Example response payload:

{
  "results":{
    "result_count":22,
    "rec_count":19,
    "execution_time":8.054971694946289,
    "query":"sample query",
    "matched_tokens":["rainbow"],
    "searchId": "a4a86822-f885-4000-aa39-b941a0f10b58",
    "search_results":[
      {
        "gamecode":"nyxrainbowriches",
        "score":0.48419,
        "gamename":"Rainbow Riches",
        "game_category":"Casino",
        "game_class":"Slots",
        "theme":"Irish",
        "provider":"Barcrest"
      },...
    ],
    "rec_results":[
      {
        "gamecode":"deal-or-no-deal-bingo",
        "score":3.70403,
        "gamename":"Deal or No Deal Bingo",
        "game_category":"Bingo",
        "game_class":"Bingo",
        "theme":"TV Show",
        "provider":"Blueprint"
      },...
    ]
  }
}

Response contents

result_count: number of returned items

execution_time: search time in ms

query: search query

matched_tokens: matched tokens - this is based on our partial matching technology. For example if you search “kin” it may match to “Kind”, “King”, “Kingdom”, etc.

search_results: a list of games ordered by relevance to the search term

rec_results: a list of recommended games based on the search that has been performed and personalised to the user.

We would typically recommend that a gaming search engine is rendered with two boxes based on the search results and also below an Also Recommended (or similar copy) section from the rec results.

Popular searches

In order to present some hints to new user (without search history) before any search phrase being entered, additional API call may be performed to get information about frequently searched phrases. This information might be rendered as placeholder in search widget. Recent user search phrases might be shown based on data from cookie.

GET https://api.graphyte.ai/search/v1/popular

Headers:x-api-key=api key given at integration
x-brand-key=unique reference for brand
content-type=application/json

Example response payload:

{
    "result": {
        "execution_time": 0.01430511474609375,
        "popular_searches": [
            "football",
            "horse racing",
            "tennis"
        ]
    }
}

Response contents

execution_time: search time in ms

popular_searches: frequently searched phrases

Clickthrough Integration

In order to complete the feedback cycle and to enable our self-learning algorithms to optimise results over time we need to be informed when people click through on a search results. This clickthrough event should be fired every time someone successfully redirects (e.g. plays, bets, launches) from one of our results. This helps among other things with typo recognition as we can determine what people meant when they searched for a mis-spelt version of a term.

POST https://api.graphyte.ai/search/v1/click

Headers:x-api-key=api key given at integration
x-brand-key=unique reference for brand
content-type=application/json

Example payload:

{
    "type": "track",
    "userId": "1234567",
    "properties": {
        "event_type": "search",
        "event_name": "SEARCH_CLICK",
        "event_value": 1,
        "event_info_1": "football",
        "event_info_2": "2a0f6692-2231-42fd-9d90-89133a470449",
        "event_ref_id": "1533142337",
        "event_ref_type": "selection"
    },
    "timestamp": "2022-03-09T12:30:14.532Z",
    "sentAt": "2022-03-09T12:30:14.532Z",
    "writeKey": "",
    "messageId": ""
}

type: “track”

userId: User identifier if present. Should be the same ID as used for other Opti-X services to enable consistent personalisation

properties:

  • event_type: "search"
  • event_name: "SEARCH_CLICK"
  • event_value: rank in the search results
  • event_info_1: query entered by the user
  • event_info_2: unique identifier of the search - searchId from search results
  • event_ref_id: identifier for the item e.g. selection key or market key or game code
  • event_ref_type: type of item that has been clicked on e.g. selection, market, event, type, class, category or game

timestamp: click timestamp

sentAt: click timestamp

writeKey: API key

messageId: id of a message

If you have any questions please contact your Integration Manager.