Skip to main content

Touchpoint Scanner Metrics

Retrieve QR scan metrics for touchpoints. The response shape changes based on the metricsType parameter — you can pull a summary across all touchpoints in an experience, drill into a specific user's scan history, or get detailed visit data for a single touchpoint.

Endpoint

GET https://api.distinct.so/v3/touchpoint/metrics

Request Headers

KeyValue
x-distinct-api-keyYour admin API key

Query Parameters

ParameterTypeRequiredDescription
metricsTypeStringYesControls the level of metrics returned. Must be one of EXPERIENCE, USER, or TOUCHPOINT
experienceIdStringConditionalThe experience to scope the query to. Required when metricsType is EXPERIENCE or USER
userIdStringConditionalThe user whose scan history to retrieve. Required when metricsType is USER
touchpointIdStringConditionalThe specific touchpoint to get metrics for. Required when metricsType is TOUCHPOINT
visitsTypeStringNoControls which visit breakdown is included. Only applies when metricsType is TOUCHPOINT. Must be TOTAL or UNIQUE. Defaults to TOTAL
pageSizeIntegerNoNumber of items to return per page. Defaults to 50
offsetIntegerNoNumber of items to skip before returning results. Defaults to 0
info
  • metricsType is always required. Missing or invalid values return 400 Bad Request.
  • experienceId is not required when metricsType is TOUCHPOINT.
  • visitsType has no effect when metricsType is EXPERIENCE or USER.
  • pageSize and offset apply to the paginated totalVisitsDetails and uniqueVisitsDetails fields in the TOUCHPOINT response.

Metrics Type Quick Reference

GoalRequired ParamsOptional Params
All touchpoints in an experiencemetricsType=EXPERIENCE, experienceIdpageSize, offset
A user's scan history in an experiencemetricsType=USER, experienceId, userId
Total visits for a single touchpointmetricsType=TOUCHPOINT, touchpointIdexperienceId, pageSize, offset
Unique visitors for a single touchpointmetricsType=TOUCHPOINT, touchpointId, visitsType=UNIQUEexperienceId, pageSize, offset

Response

All responses share this common envelope:

{
"statusCode": 200,
"message": "Touchpoint scanner metrics fetched successfully",
"data": { ... }
}

The contents of data differ by metricsType — see the sections below.

metricsType = EXPERIENCE

Returns aggregated scan counts for every touchpoint in the experience.

{
"statusCode": 200,
"message": "Touchpoint scanner metrics fetched successfully",
"data": {
"totalTouchpoints": 2,
"touchpoints": [
{
"id": "tp-1",
"name": "Entry Scan",
"value": "entry_scan",
"totalVisits": 3,
"uniqueVisits": 2
},
{
"id": "tp-2",
"name": "Exit Scan",
"value": "exit_scan",
"totalVisits": 1,
"uniqueVisits": 1
}
]
}
}
FieldTypeDescription
totalTouchpointsIntegerTotal number of touchpoints in the experience
touchpoints[].idStringTouchpoint ID
touchpoints[].nameStringTouchpoint display name
touchpoints[].valueStringTouchpoint identifier value
touchpoints[].totalVisitsIntegerAll scans at this touchpoint, including repeat scans by the same user
touchpoints[].uniqueVisitsIntegerDistinct users who scanned at this touchpoint

metricsType = USER

Returns each touchpoint the user scanned within the experience, along with every scan timestamp.

{
"statusCode": 200,
"message": "Touchpoint scanner metrics fetched successfully",
"data": {
"totalTouchpoints": 2,
"touchpoints": [
{
"id": "tp-1",
"name": "Entry Scan",
"value": "entry_scan",
"totalVisits": 2,
"timestampsUTC": [
"2024-01-01T10:00:00Z",
"2024-01-03T10:00:00Z"
]
}
]
}
}
FieldTypeDescription
totalTouchpointsIntegerNumber of touchpoints the user scanned
touchpoints[].totalVisitsIntegerNumber of times this user scanned this touchpoint
touchpoints[].timestampsUTCString[]Ordered list of all scan times in UTC for this user at this touchpoint

metricsType = TOUCHPOINT

Returns detailed scan data for a single touchpoint. The fields present depend on visitsType.

note

touchpoints is a single object in this response (not an array), and totalTouchpoints is not included.

visitsType = TOTAL (default)

{
"statusCode": 200,
"message": "Touchpoint scanner metrics fetched successfully",
"data": {
"touchpoints": {
"id": "tp-1",
"name": "Entry Scan",
"value": "entry_scan",
"totalVisits": 3,
"totalVisitsDetails": {
"items": [
{ "userId": "user-1", "timestampUTC": "2024-01-01T10:00:00Z" },
{ "userId": "user-2", "timestampUTC": "2024-01-02T10:00:00Z" },
{ "userId": "user-1", "timestampUTC": "2024-01-03T10:00:00Z" }
],
"pagination": { "offset": 0, "pageSize": 50 }
}
}
}
}
FieldTypeDescription
totalVisitsIntegerTotal number of scans, including repeats
totalVisitsDetails.items[].userIdStringID of the user who scanned
totalVisitsDetails.items[].timestampUTCStringScan timestamp in UTC
totalVisitsDetails.pagination.offsetIntegerCurrent pagination offset
totalVisitsDetails.pagination.pageSizeIntegerCurrent page size

visitsType = UNIQUE

{
"statusCode": 200,
"message": "Touchpoint scanner metrics fetched successfully",
"data": {
"touchpoints": {
"id": "tp-1",
"name": "Entry Scan",
"value": "entry_scan",
"uniqueVisits": 2,
"uniqueVisitsDetails": {
"items": [
{ "userId": "user-1", "timestampUTC": "2024-01-01T10:00:00Z" },
{ "userId": "user-2", "timestampUTC": "2024-01-02T10:00:00Z" }
],
"pagination": { "offset": 0, "pageSize": 50 }
}
}
}
}
FieldTypeDescription
uniqueVisitsIntegerNumber of distinct users who scanned
uniqueVisitsDetails.items[].userIdStringID of the user who scanned
uniqueVisitsDetails.items[].timestampUTCStringFirst scan timestamp in UTC for this user
uniqueVisitsDetails.pagination.offsetIntegerCurrent pagination offset
uniqueVisitsDetails.pagination.pageSizeIntegerCurrent page size

Example Requests

Experience Metrics

curl -X GET 'https://api.distinct.so/v3/touchpoint/metrics?metricsType=EXPERIENCE&experienceId=<experience-id>&offset=0&pageSize=50' \
-H 'x-distinct-api-key: <admin-api-key>'

Replace the placeholders:

  • <admin-api-key> — your admin API key provided by Distinct
  • <experience-id> — the ID of the experience to query

User Scan History

curl -X GET 'https://api.distinct.so/v3/touchpoint/metrics?metricsType=USER&experienceId=<experience-id>&userId=<user-id>' \
-H 'x-distinct-api-key: <admin-api-key>'

Replace the placeholders:

  • <admin-api-key> — your admin API key provided by Distinct
  • <experience-id> — the ID of the experience to query
  • <user-id> — the ID of the user whose scan history you want

Touchpoint Total Visits

curl -X GET 'https://api.distinct.so/v3/touchpoint/metrics?metricsType=TOUCHPOINT&touchpointId=<touchpoint-id>&offset=0&pageSize=50' \
-H 'x-distinct-api-key: <admin-api-key>'

Replace the placeholders:

  • <admin-api-key> — your admin API key provided by Distinct
  • <touchpoint-id> — the ID of the touchpoint to query

Touchpoint Unique Visitors

curl -X GET 'https://api.distinct.so/v3/touchpoint/metrics?metricsType=TOUCHPOINT&touchpointId=<touchpoint-id>&visitsType=UNIQUE&offset=0&pageSize=50' \
-H 'x-distinct-api-key: <admin-api-key>'

Replace the placeholders:

  • <admin-api-key> — your admin API key provided by Distinct
  • <touchpoint-id> — the ID of the touchpoint to query

Error Responses

400 Bad Request — Missing or Invalid Parameter

{
"statusCode": 400,
"message": "Missing required parameter: metricsType"
}

Cause: A required parameter is missing, or a parameter value is invalid (e.g., an unrecognized metricsType or visitsType value).

404 Not Found — Resource Not Found

{
"statusCode": 404,
"message": "Experience not found"
}

Cause: The provided experienceId, userId, or touchpointId does not exist in the system.

Notes

  1. The x-distinct-api-key will be shared with you by the Distinct team and must be included in every API request.
  2. The metricsType parameter determines the shape of the response — refer to the response sections above for each type.
  3. When metricsType is TOUCHPOINT, the touchpoints field in the response is a single object, not an array.
  4. Pagination (pageSize and offset) only applies to totalVisitsDetails and uniqueVisitsDetails in the TOUCHPOINT response.
  5. The visitsType parameter is only relevant when metricsType is TOUCHPOINT and defaults to TOTAL if omitted.
  6. Optional IP allowlisting — You can share a list of IP addresses with the Distinct team to be whitelisted against your API key for an additional layer of security. When configured, requests from any other IP are rejected with 403.