Single Fan View API
The Single Fan View API is designed to enable clients and partners to retrieve data from a subset of FDP modules. As of this writing, the API is read-only, meaning it supports data retrieval from FDP but does not allow writing or modifying data.
GraphQL
The Single Fan View API is built using GraphQL, a powerful query language for APIs, as well as a runtime for executing those queries. GraphQL offers several key advantages that are especially beneficial for this API:
- Flexible querying: Clients can use any standard GraphQL client to query data, without needing custom request logic.
- Precise data fetching: Clients specify exactly which fields they need, and the server responds with only that data, reducing payload size and eliminating over-fetching.
- Client-driven structure: The shape of the response mirrors the structure of the query, giving clients full control over how the data is retrieved and structured.
More information about GraphQL can be found here. Detailed information about the API endpoint for querying FDP modules is available here .
Schema
This section outlines the GraphQL schema for each available FDP module that can be queried. Custom modules are not included in this documentation. If you need to fetch data from a custom module or from a common data module not listed below, please contact our development team for support.
SCV User Schema
type User {
scvUserId: ID!
scvUserIdType: String!
scvClient: String!
originatingSource: String
originatingSourceInsight: String
originatingSourceTstamp: Time
sourceUpdatedTstamp: Time
primarySource: String
deviceId: String
ssoId: String
pushId: String
isPushRevoked: Boolean
emailAddress: String
isEmailSuppressed: Boolean
emailContactId: String
mobileNumber: String
title: String
firstName: String
lastName: String
fullName: String
gender: String
birthDate: Time
age: Int
postcode: String
postcodeTown: String
postcodeRegion: String
postcodeArea: String
countryCode: String
countryName: String
distanceToClub: Float
jobTitle: String
companyName: String
metadata: Map
createdAt: Time
updatedAt: Time
}
extend type Query {
user(scvUserId: ID!): User
}
As shown in the example above, scv_user records can only be queried by id.
The following code snippets illustrate how to query scv_user records by id and what a typical server response looks like:
{
user(scvUserId:"001beda9967ce420104b2c499265d8ba") {
scvUserId,
scvUserIdType,
fullName,
postcode,
postcodeTown,
postcodeArea,
postcodeRegion,
createdAt,
updatedAt
}
}
{
"data": {
"user": {
"scvUserId": "001beda9967ce420104b2c499265d8ba",
"scvUserIdType": "MD5_CLIENT_EMAIL",
"fullName": "Adrian Clarke",
"postcode": "80250",
"postcodeTown": null,
"postcodeArea": null,
"postcodeRegion": null,
"createdAt": "2025-03-21T14:39:43.714066Z",
"updatedAt": "2025-03-21T14:39:43.714066Z"
}
}
}
SCV Retail Schema
type Retail {
scvUserRetailId:String!
scvUserId: ID!
scvClient: String!
sourceSystemName: String
sourceSystemUserId: String
sourceType: String
branchCode: String
branchName: String
departmentName: String
subDepartmentName: String
season: String
productId: String
productDescription: String
productCategory: String
transactionId: String
transactionDate: Time
transactionQuantity: Int
transactionValue: Float
promoCode: String
orderId: String
isRefunded: Boolean
refundDate: Time
createdAt: Time
updatedAt: Time
}
type Retails {
items: [Retail!]!
next: String
}
extend type Query {
retail(scvUserRetailId: ID!): Retail
retails(scvUserId: String!, size: Int! = 50, sort: [String!] = ["-updatedAt"], cursor: String): Retails!
}
As shown in the example above, scv_user_retail records can be queried by scvUserRetailId or by scvUserId, in which case results are paginated.
The following code snippets illustrate how to query scv_user_retail records by scvUserRetailId and what a typical server response looks like:
{
retail(scvUserRetailId:"a2aa326d9ace519b7c0ffdabf9b1c7f7") {
scvUserRetailId
scvUserId,
productId,
promoCode,
productDescription,
productCategory,
transactionId,
transactionDate,
transactionValue,
transactionQuantity,
createdAt,
updatedAt
}
}
{
"data": {
"retail": {
"scvUserRetailId": "a2aa326d9ace519b7c0ffdabf9b1c7f7",
"scvUserId": "63d911e78be3684af1e80bb73665378d",
"productId": "4329",
"promoCode": "5",
"productDescription": "ex",
"productCategory": null,
"transactionId": "48",
"transactionDate": "2022-10-11T01:40:41+01:00",
"transactionValue": 667,
"transactionQuantity": 48,
"createdAt": "2025-03-17T12:52:38.216598Z",
"updatedAt": "2025-03-17T12:52:38.216598Z"
}
}
}
The following code snippets illustrate how to query scv_user_retail records by scvUserId and what a typical server response looks like:
{
retails(scvUserId: "63d911e78be3684af1e80bb73665378d", size: 3) {
items {
scvUserRetailId
scvUserId
productId
createdAt
updatedAt
}
next
}
}
{
"data": {
"retails": {
"items": [
{
"scvUserRetailId": "ce19ece4822dbe3fa023c241911f29f8",
"scvUserId": "63d911e78be3684af1e80bb73665378d",
"productId": "218",
"createdAt": "2025-03-17T12:52:38.216598Z",
"updatedAt": "2025-03-17T12:52:38.216598Z"
},
{
"scvUserRetailId": "a2aa326d9ace519b7c0ffdabf9b1c7f7",
"scvUserId": "63d911e78be3684af1e80bb73665378d",
"productId": "4329",
"createdAt": "2025-03-17T12:52:38.216598Z",
"updatedAt": "2025-03-17T12:52:38.216598Z"
},
{
"scvUserRetailId": "6fde00dc65c664bfd15a4f07e08cf407",
"scvUserId": "63d911e78be3684af1e80bb73665378d",
"productId": "218",
"createdAt": "2025-03-17T12:52:38.216598Z",
"updatedAt": "2025-03-17T12:52:38.216598Z"
}
],
"next": "eyJjaWQiOiJJTkNST1dEIiwic3VpZCI6IjYzZDkxMWU3OGJlMzY4NGFmMWU4MGJiNzM2NjUzNzhkIiwic2giOiI2OGMyYzA5MjliNDljZTk1NDE2ZGQ4Mjg2MWIyNDU5NiIsInN2IjpbIjIwMjUtMDMtMTdUMTI6NTI6MzguMjE2NTk4WiIsIjZmZGUwMGRjNjVjNjY0YmZkMTVhNGYwN2UwOGNmNDA3Il19"
}
}
}
SCV Ticket Schema
type Ticket {
scvUserTicketId: String!
scvUserId: ID!
sourceSystemName: String
sourceSystemUserId: String
sourceType: String
season: String
productId: String
productName: String
productDescription: String
productType: String
productSubType: String
productStartDate: Time
productEndDate: Time
venueName: String
distanceTravelled: Float
competitionName: String
competitionType: String
homeTeamName: String
awayTeamName: String
transactionDate: Time
transactionDaysBeforeStartDate: Int
isTransactionCancelled: Boolean
transactionCancellationDate: Time
transactionValue: Float
transactionPriceBand: String
transactionPriceClass: String
orderId: String
orderValue: Float
paymentMethod: String
seatNumber: String
seatRow: String
blockName: String
areaName: String
standName: String
stadiumName: String
hasLinkedTicketWallet: Boolean
isTicketWalletShared: Boolean
hasAttended: Boolean
arrivalTime: Time
createdAt: Time
updatedAt: Time
}
type Tickets {
items: [Ticket!]!
next: String
}
extend type Query {
ticket(scvUserTicketId: ID!): Ticket
tickets(scvUserId: String!, size: Int! = 50, sort: [String!] = ["-updatedAt"], cursor: String): Tickets!
}
As shown in the example above, scv_user_ticket records can be queried by scvUserTicketId or by scvUserId, in which case results are paginated.
The following code snippets illustrate how to query scv_user_ticket records by scvUserTicketId and what a typical server response looks like:
{
ticket(scvUserTicketId: "5e7b885406fa9aa2d71fa24dc1c2cdc8") {
scvUserTicketId
scvUserId
productId
createdAt
updatedAt
}
}
{
"data": {
"ticket": {
"scvUserTicketId": "5e7b885406fa9aa2d71fa24dc1c2cdc8",
"scvUserId": "001beda9967ce420104b2c499265d8ba",
"productId": "4",
"createdAt": "2025-03-17T12:52:41.585747Z",
"updatedAt": "2025-03-17T12:52:41.585747Z"
}
}
}
The following code snippets illustrate how to query scv_user_ticket records by scvUserId and what a typical server response looks like:
{
tickets(scvUserId: "001beda9967ce420104b2c499265d8ba", size: 3, sort:["-productId", "updatedAt"], cursor: "eyJjaWQiOiJJTkNST1dEIiwic3VpZCI6IjAwMWJlZGE5OTY3Y2U0MjAxMDRiMmM0OTkyNjVkOGJhIiwic2giOiIwZmRjODNmNzU5NTIzNjc4NGIwYTMxNTg5Y2ZlNzFkOSIsInN2IjpbIjQiLCIyMDI1LTAzLTE3VDEyOjUyOjQxLjU4NTc0N1oiLCI3YTRhYzUxNDk4Y2UxNWJjNjVkYzk4NzgyOTdkZmQwNCJdfQ==") {
items {
scvUserTicketId
scvUserId
productId
createdAt
updatedAt
}
next
}
}
{
"data": {
"tickets": {
"items": [
{
"scvUserTicketId": "5e7b885406fa9aa2d71fa24dc1c2cdc8",
"scvUserId": "001beda9967ce420104b2c499265d8ba",
"productId": "4",
"createdAt": "2025-03-17T12:52:41.585747Z",
"updatedAt": "2025-03-17T12:52:41.585747Z"
},
{
"scvUserTicketId": "c3fa65b8200c682af7b48d0003033872",
"scvUserId": "001beda9967ce420104b2c499265d8ba",
"productId": "3",
"createdAt": "2025-03-17T12:52:41.585747Z",
"updatedAt": "2025-03-17T12:52:41.585747Z"
},
{
"scvUserTicketId": "4657bba432ac7ab8ef448e6ab9be09fa",
"scvUserId": "001beda9967ce420104b2c499265d8ba",
"productId": "3",
"createdAt": "2025-03-17T12:52:41.585747Z",
"updatedAt": "2025-03-17T12:52:41.585747Z"
}
],
"next": "eyJjaWQiOiJJTkNST1dEIiwic3VpZCI6IjAwMWJlZGE5OTY3Y2U0MjAxMDRiMmM0OTkyNjVkOGJhIiwic2giOiIwZmRjODNmNzU5NTIzNjc4NGIwYTMxNTg5Y2ZlNzFkOSIsInN2IjpbIjMiLCIyMDI1LTAzLTE3VDEyOjUyOjQxLjU4NTc0N1oiLCI0NjU3YmJhNDMyYWM3YWI4ZWY0NDhlNmFiOWJlMDlmYSJdfQ=="
}
}
}
Unlike the previous examples, the code snippet above specifies a page size of 3, uses -productId and updatedAt as sort fields, and includes a cursor to retrieve the next page of results.
SCV Structured Event Schema
type StructuredEvent {
scvUserStructuredEventId: ID!
scvUserId: ID!
scvClient: String!
sourceSystemName: String
sourceSystemUserId: String
sourceType: String
digitalAppId: String
usageAt: Time
category: String
action: String
label: String
property: String
value: Float
createdAt: Time
updatedAt: Time
}
type StructuredEvents {
items: [StructuredEvent!]!
next: String
}
extend type Query {
structuredEvent(scvUserStructuredEventId: ID!): StructuredEvent
structuredEvents(scvUserId: String!, size: Int! = 50, sort: [String!] = ["-updatedAt"], cursor: String): StructuredEvents!
}
As shown in the example above, scv_user_structured_event records can be queried by scvUserStructuredEventId or by scvUserId, in which case results are paginated.
The following code snippets illustrate how to query scv_user_structured_event records by scvUserStructuredEventId and what a typical server response looks like:
{
structuredEvent(scvUserStructuredEventId: "7faa7bc3620583bc6a27eb70f6e7103d") {
scvUserStructuredEventId
scvUserId
sourceSystemName
sourceSystemUserId
createdAt
updatedAt
}
}
{
"data": {
"structuredEvent": {
"scvUserStructuredEventId": "7faa7bc3620583bc6a27eb70f6e7103d",
"scvUserId": "d76a04e7c89f43c8f8a30affc575641d",
"sourceSystemName": "SNOWPLOW",
"sourceSystemUserId": "895",
"createdAt": "2025-02-27T13:51:15.074019Z",
"updatedAt": "2025-02-27T13:51:15.074019Z"
}
}
}
The following code snippets illustrate how to query scv_user_structured_event records by scvUserId and what a typical server response looks like:
{
structuredEvents(scvUserId: "d76a04e7c89f43c8f8a30affc575641d", size: 3) {
items {
scvUserStructuredEventId
scvUserId
sourceSystemName
sourceSystemUserId
createdAt
updatedAt
}
next
}
}
{
"data": {
"structuredEvents": {
"items": [
{
"scvUserStructuredEventId": "7faa7bc3620583bc6a27eb70f6e7103d",
"scvUserId": "d76a04e7c89f43c8f8a30affc575641d",
"sourceSystemName": "SNOWPLOW",
"sourceSystemUserId": "895",
"createdAt": "2025-02-27T13:51:15.074019Z",
"updatedAt": "2025-02-27T13:51:15.074019Z"
}
],
"next": null
}
}
}
Unlike the previous examples, in the response tab of the code snippet above, the returned cursor (next field) is null, which means there are no other results to be fetched from the API.
Updated about 20 hours ago