UTR Sports Engage API Documentation
UTR Sports Engage API Documentation
Last Updated March 7, 2025
Table of Contents
Details About Requesting Access
Refreshing Expired Access Tokens
Accessing the API Using an Access Token
Scenario 1 - User already logged in
Scenario 2 - User not logged in/switches account
Overview
The Engage API allows cross-platform users (aka users from third-party sites who are UTR Sports members) to connect their accounts. Once their accounts are linked, third-party sites can access endpoints hosted within our Engage API service to retrieve player ratings and extended player profile information. (Check our Swagger docs for the most up-to-date information on available endpoints. You can sign in with an empty username and password.)
Prerequisites
To utilize the UTR Sports OAuth flow, you will need the following:
- Client ID (provided by UTR Sports)
- Client Secret (provided by UTR Sports)
- Redirect URI (created by the client and communicated to UTR Sports)
- Note that, in addition to a production redirect URI, you may provide us with a development/testing version of your redirect URI that we can whitelist.
Authentication
UTR Sports uses OAuth2 for authentication. OAuth allows external applications to request authorization for a user’s data. It will enable users to grant and revoke API access on a per-application basis and keep users’ authentication details safe.
All third parties need to register their applications before getting started. A registered application will be assigned a client ID and client secret. The secret is used for authentication and should never be shared.
Note that to view sample Curl requests and other examples, it’s best to refer to our Swagger documentation here.
When you access Swagger, simply log in without a username or password entered as these documents are public.
OAuth Overview
When OAuth is initiated, the user is prompted by the application to log in or sign up (if the user is not yet already a member) on the UTR Sports website and to give consent to the requesting application. A user can opt out of the scopes requested by the application.
After the user accepts or rejects the authorization request, UTR Sports redirects the user to a URL specified by the application. If the user authorizes the application, the URL query string will include an authorization code and the scope accepted by the user. Apps should check which scopes a user has accepted. Applications complete the authorization process by exchanging the authorization code for a refresh token and a short-lived access token.
Access tokens are used by applications to obtain and modify UTR Sports resources on behalf of the authenticated player. Refresh tokens are used to obtain new access tokens when older ones expire.

This flow is also represented in steps under Sample Test Flow
Requesting Access
To initiate the flow, applications must redirect the user to UTR Sports’s authorization page. At the moment, OAuth is authorized on the web via GET
Prod URL:
https://prod-utr-engage-api-data-azapp.azurewebsites.net/api/v1/oauth/authorize
Note that the URLs above require the parameters outlined in our Swagger docs. You can see a full example of a functioning URL in our sample test flows further down in the doc here.
Details About Requesting Access
The authorization page will prompt the user to grant your application access to their data. Scopes requested by the application are shown as checked boxes, but the user may opt out of any requested scopes. If an application relies on specific scopes to function properly, the application should make that clear before and after authentication.
client_id required integer, in query |
The application’s ID is obtained during registration. |
redirect_uri required string, in query |
URL to which the user will be redirected after authentication. Must be within the callback domain specified by the application. |
third_party_user_id required string, in query |
Unique ID associated with the third party’s site. |
approval_prompt string, in query |
force or auto, use force to always show the authorization prompt even if the user has already authorized the current application, default is auto. |
scope required string, in query |
Comma-separated list of requested scopes (e.g. “ratings” or "ratings,profile,results"). Applications should request only the scopes required for the application to function normally. Note that as of Q1 2025, the available scopes include:
|
state string, in query |
Returned in the redirect URI. Useful if the authentication is done from various points in an app. |
Token Exchange (User-Level Access Token)
UTR Sports will respond to the authorization request by redirecting the user agent to the redirect_uri provided.
If access is denied, error=access_denied will be included in the query string.
If access is accepted, code and scope parameters will be included in the query string. The code parameter contains the authorization code required to complete the authentication process. code is short-lived and can only be used once. The application must now call the POST with its client ID and client secret to exchange the authorization code for a refresh token and short-lived access token (see step 7 under Sample Test Flow for instructions on how to correctly call this endpoint):
Prod URL:
https://prod-utr-engage-api-data-azapp.azurewebsites.net/api/v1/oauth/token
Dev URL:
https://qa-utr-engage-api-data-azapp.azurewebsites.net/api/v1/oauth/token
The state parameter will always be included in the response if it was initially provided by the application.
Request Parameters
client_id required integer, in query |
The application’s ID is obtained during registration. |
client_secret required string, in query |
The application’s secret is obtained during registration. |
code required string, in query |
The code parameter is obtained in the redirect. |
grant_type required string, in query |
The grant type for the request. For initial authentication, must always be "authorization_code". |
A refresh token, access token, and access token expiration date will be issued upon successful authentication.
expires_at integer |
The number of seconds since the epoch when the provided access token will expire |
expires_in integer |
Seconds until the short-lived access token will expire |
refresh_token string |
The refresh token for this user is to be used to get the next access token for this user. Please expect that this value can change anytime you retrieve a new access token. Once a new refresh token code has been returned, the older code will no longer work. |
player string |
A summary of player information (for more details on this response, see the EngageApi.OAuth.TokenExchangeResponse object in Swagger)
|
Refreshing Expired Access Tokens
Access tokens expire six hours after they are created, so they must be refreshed for an application to maintain access to a user’s resources. Every time you get a new access token, we return a new refresh token as well. If you need to make a request, we recommend checking to see if the short-lived access token has expired. If it has expired, request a new short-lived access token with the last received refresh token.

To refresh an access token, applications should call the POST endpoints (specifying grant_type: refresh_token and including the application’s refresh token for the user as an additional parameter):
Prod URL:
https://prod-utr-engage-api-data-azapp.azurewebsites.net/api/v1/oauth/token
Dev URL:
https://qa-utr-engage-api-data-azapp.azurewebsites.net/api/v1/oauth/token
If the application has an access token for the user that expires in more than one hour, the existing access token will be returned. If the application’s access tokens for the user are expired or will expire in one hour (3,600 seconds) or less, a new access token will be returned. In this case, both the newer and older access tokens can be used until they expire.
A refresh token is issued back to the application after all successful requests. The refresh token may or may not be the same refresh token used to make the request. Applications should persist the refresh token contained in the response and always use the most recent refresh token for subsequent requests to obtain a new access token. Once a new refresh token is returned, the older refresh token is invalidated immediately.
Request Parameters
client_id required integer, in query |
The application’s ID is obtained during registration. |
client_secret required string, in the query |
The application’s secret is obtained during registration. |
grant_type required string, in query |
The grant type for the request. When refreshing an access token, must always be "refresh_token". |
code required string, in query |
The code parameter is obtained in the redirect. |
refresh_token required string, in query |
The refresh token for this user is to be used to get the next access token for this user. Please expect that this value can change anytime you retrieve a new access token. Once a new refresh token code has been returned, the older code will no longer work. |
A few recommendations
- Storing the scopes your players accept is great in case you get unexpected results (for example: why am I not getting activities for this user?).
- In general, we recommend storing short-lived access tokens and refresh tokens in separate tables

Token Exchange (Client-Level Access Token)
The client-level access token will be used by the third party to access the endpoints that are not user-specific like the POST Results endpoint which will have the involvement of multiple users.
Steps to Obtain Client-Level Access Token and Test POST Results Endpoint
- Use the login.microsoftonline.com endpoint to request an access token for the test third-party application.
- Provide the following required details in the request:
- Client ID: The unique identifier for the test third-party application. Provided by UTR Sports.
- Client Secret: The secret associated with the Client ID. Provided by UTR Sports.
- Tenant: Provided by UTR Sports.
- Grant Type: client_credentials.
- Scope: Define the required API permissions. Provided by UTR Sports. Please reach out to api-developers@utrsports.com for the scope for your application.
- Execute the request to retrieve the client-level access token. Store the token securely for use in subsequent steps.
- Use this curl request to get the client-level access token for the third-party
curl --request POST \
--url https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data client_id={client_id} \
--data client_secret={client_secret} \
--data scope={scope}
A client-level access token and access token expiration time will be issued upon successful authentication.
expires_in integer |
Seconds until the short-lived access token will expire |
access_token string |
The access token for this client is to be used to get the next access token for this user. Please expect that this value can change anytime you retrieve a new access token. Once a new refresh token code has been returned, the older code will no longer work.
The requested access token. The third party can use this token to authenticate to the secured resource, such as to the post results endpoint.
|
Accessing the API Using an Access Token
Applications use unexpired access tokens to make resource requests to the UTR Sports API on the user’s behalf. Access tokens are required for all resource requests, and can be included by specifying the Authorization: Bearer #{access_token} header.
As of Summer 2024, clients may access our /api/v1/members/ratings endpoint to retrieve rating information for cross-platform users.
Deauthorization
Applications can revoke access to a player's data. This will invalidate all refresh tokens and access tokens that the application has for the player. All requests made using invalidated tokens will receive a 401 Unauthorized response.
The POST endpoints are:
Prod:
https://prod-utr-engage-api-data-azapp.azurewebsites.net/api/v1/oauth/deauthorize
Dev:
https://qa-utr-engage-api-data-azapp.azurewebsites.net/api/v1/oauth/deauthorize
Request Parameters
scope required string, in the query |
The scopes to be deauthorized (e.g. “ratings” or "ratings, profile, results"). To deauthorize all scopes at once, simply leave the request body empty.
Note that as of Q1 2025, the available scopes include:
|
A response will be provided with the revoked access token.
access_token required string, in query |
Responds with the access tokens that were revoked. |
Endpoints
GET /api/v1/members/ratings
This endpoint provides the rating of the member. It requires the user to grant ratings permission. Authentication is done using a user-level access token generated for the user. You can test this in our swagger documentation
curl --request GET \
--url https://prod-utr-engage-api-data-azapp.azurewebsites.net/api/v1/members/ratings \
--header 'Authorization: Bearer <access-token>'
GET /api/v1/members/profile
This endpoint provides the profile information of the member. It requires the user to grant profile permission. Authentication is done using a user-level access token generated for the user. You can test this in our swagger documentation
curl --request GET \
--url https://prod-utr-engage-api-data-azapp.azurewebsites.net/api/v1/members/profile \
--header 'Authorization: Bearer <access-token>'
POST /api/v1/results
This endpoint allows the third party to post results on behalf of the athlete. It requires the user to permit results scope. Authentication is done using a client-level access token generated for the third party. You can test this in our swagger documentation
By default, clients have the ability to post unverified results. Please contact api-developers@utrsports.com if you would like the ability to post results that count towards the verified rating.
- Note: Third-party can only submit results of players who have authorized the results scope
curl --request POST \
--url https://prod-utr-engage-api-data-azapp.azurewebsites.net/api/v1/results \
--header 'Authorization: Bearer <access-token>' \
--header 'Content-Type: application/json-patch+json' \
--header 'accept: application/json' \
--data <Data>
When submitting multiple results through this API, there are a few possible outcomes. Your entire list of results might be fully accepted, partially accepted, or completely rejected. Here's a breakdown of the codes you might receive:
Value |
Status Code |
Description |
1 |
Accepted |
Your entire list of submitted results is valid and will be processed. |
2 |
PartiallyAccepted |
Some of your results are valid, while others contain errors. The system has processed what it could. |
3 |
Denied |
There were issues with all of your submitted results; none were accepted. |
When submitting results, it's possible some individual results might not pass validation on our end. This could result in specific error codes being returned for those problematic results. Here's a list of common error codes you might encounter and what they indicate about each result:
Value |
Status Code |
Description |
1 |
PlayersConsentPending |
Some participants haven't given their approval for the results to be recorded. |
2 |
MissingSecondPlayerDetails |
In a doubles match, information about one of the players is incomplete. |
3 |
InvalidScore |
The entered scores don't follow the rules of the game or are out of range. |
4 |
InvalidTieBreakScore |
The tiebreaker scores entered are incorrect according to the sport's rules. |
5 |
InvalidCountryCode |
The country code used doesn't match a recognized ISO 3166-1 alpha-3 code. |
6 |
InvalidAddress |
The provided address format is incorrect or incomplete. |
7 |
PlayerRecordMissing |
The system can't find a player record linked to one or more participants in the results. |
8 |
InvalidGender |
An invalid gender option is chosen (when only "Male," "Female," or "Mixed" are allowed). |
9 |
EventEndDateNotBeforeStartDate |
The end date of an event is set earlier than its start date. |
10 |
DuplicatePlayerIdsInMatch |
Two or more players are accidentally given the same identifier within a single match. |
11 |
InvalidResultDate |
The date on which the results were recorded falls outside the range of the event's start and end dates. |
Rate Limits
Partners are limited to 1000 requests per minute across all API requests in a rolling window. Requests in excess of this rate limit will return an error response with a 429 status code.
Sample Test Flow
The following steps demonstrate how the OAuth flow and endpoint requests work. You will need to use your client ID and secret to connect your site’s users with their accounts on UTRS.
- The user clicks connect on the client site.
- To simulate this step, use the following URL
- Note that if you go back through the flow a second time, you will need to change approval_prompt=auto to approval_prompt=force (otherwise you will receive an error).
Prod URL:
https://prod-utr-engage-api-data-azapp.azurewebsites.net/api/v1/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&third_party_user_id={third_party_user_id}&approval_prompt=force&scope=ratings,profile,results
QA URL:
https://qa-utr-engage-api-data-azapp.azurewebsites.net/api/v1/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&third_party_user_id={third_party_user_id}&approval_prompt=auto&scope=ratings,profile,results
- The user gets redirected to UTR Sports.
- The user either:
- Confirm the account to connect
- sign in or sign up. Once this is complete, the flow continues.
- The user confirms authentication.
- The user is redirected back to the client site.
- The redirection step includes an authorization code (e.g. www.google.com/?code=abc123…), which is used in subsequent steps.
- From this point forward, the flow is entirely on the backend. To recreate these steps, please see our Swagger documentation to follow along.
- Also please note that the following steps are time-sensitive (authorization codes and access tokens expire after a set amount of time).
- Using the authorization code provided in step 5, request and receive access and refresh token via the /api/v1/oauth/token endpoint.
- Sample POST request body here:
{
"client_id": "{client_id}",
"client_secret": "{client_secret}",
"code": "<authorization code retrieved from step 5>",
"grant_type": "authorization_code"
}
- Using the access token received in the previous step, the client site may now send a GET request to the /api/v1/members/ratings endpoint to retrieve the user’s ratings.
- Include the access token in the header with “Bearer <access-token>”.
curl --request GET \
--url https://prod-utr-engage-api-data-azapp.azurewebsites.net/api/v1/members/ratings \
--header 'Authorization: Bearer <access-token>'
This flow is also represented in a diagram under OAuth Overview