Scan history for a design
Overview
Get each scan across codes using a design.
Use this for detail on one design.
You'll need the template id.
Returns the scans, newest first, 15 per page unless you set per_page.
Prerequisites
- A bearer token. See Authentication.
- The design's id (
templateId), from List QR designs.
Base URL
| Environment | URL |
|---|---|
| Production | https://production-api.shoutaboutus.com |
| Development | https://development-api.shoutaboutus.com |
Endpoint
GET /api/v1/qr-codes/template/{templateId}/scan-history
Authentication
Account token
- The design must belong to the caller's own company; otherwise
404QR code template not found. An id that doesn't exist at all returns422.
QR codes belong to the account company that created them, and every QR endpoint matches on that company exactly; it does not walk the partner hierarchy. A Partner token sees nothing, even for a location inside the partner's own tree: list and stats endpoints return an empty result, and single-record endpoints return
404. The404means "not visible to this token", not "this QR code does not exist". Use an account token for every endpoint in this section.
Rate limit
120 requests per minute, counted per user (the token’s user). See Rate limits.
Request parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
templateId | path | integer | Yes | The design's (template's) id (digits only). |
per_page | query | integer | No | Scans per page, 10 to 100. Values below 10 are raised to 10; above 100 returns 422. Default 15. |
Request body
None.
Request payload
None.
Response body
The payload is inside data; the scans are a page object in data.data.
| Field | Type | Description |
|---|---|---|
status | string | success. |
data | object | One page of scans, newest first. |
data.current_page | integer | This page's number. |
data.data[] | array of objects | The scans on this page, newest first. [] when there are none. |
data.data[].id | integer | The scan's id. |
data.data[].qr_code_id | integer | The QR code that was scanned. |
data.data[].qr_code_template_id | integer or null | The design (template) of that code, if any. |
data.data[].ip_address | string or null | IP address of the scan. |
data.data[].user_agent | string or null | Browser user agent of the scan. |
data.data[].referer | string or null | Referring page, when the browser sent one. |
data.data[].country | string or null | Country of the scan, e.g. US. |
data.data[].city | string or null | City of the scan. |
data.data[].device_type | string or null | Device type, e.g. mobile. |
data.data[].browser | string or null | Browser, e.g. Chrome. |
data.data[].os | string or null | Operating system, e.g. iOS. |
data.data[].latitude | string or null | Latitude of the scan, as a decimal string. |
data.data[].longitude | string or null | Longitude of the scan, as a decimal string. |
data.data[].metadata | object or null | Extra details stored with the scan. |
data.data[].scanned_at | string | When the code was scanned. |
data.data[].deleted_at | string or null | Always null here (deleted scans aren't listed). |
data.data[].created_at | string or null | When the record was created. |
data.data[].updated_at | string or null | When the record was last updated. |
data.first_page_url | string | URL of the first page. |
data.from | integer or null | Position of the first row on this page; null when the page is empty. |
data.last_page | integer | Number of the last page. |
data.last_page_url | string | URL of the last page. |
data.links[] | array of objects | Pager links: previous, each page number, next. |
data.links[].url | string or null | URL of that page; null when there is no such page. |
data.links[].label | string | Link text: a page number, « Previous or Next ». |
data.links[].page | integer or null | Page number the link goes to; null when there is no such page. |
data.links[].active | boolean | true for the current page. |
data.next_page_url | string or null | URL of the next page; null on the last page. |
data.path | string | URL of this endpoint, without query string. |
data.per_page | integer | Scans per page (per_page). |
data.prev_page_url | string or null | URL of the previous page; null on the first page. |
data.to | integer or null | Position of the last row on this page; null when the page is empty. |
data.total | integer | Scans across all pages. |
message | string | QR code template scan history retrieved successfully. |
qr_code_template | object | The design. |
qr_code_template.id | integer | The design's id. |
qr_code_template.name | string | The design's name. |
Response payload
{
"data": {
"status": "success",
"data": {
"current_page": 1,
"data": [
{
"id": 123,
"qr_code_id": 2964,
"qr_code_template_id": 2964,
"ip_address": "203.0.113.5",
"user_agent": "Mozilla/5.0",
"referer": null,
"country": "US",
"city": "New York",
"device_type": "mobile",
"browser": "Chrome",
"os": "iOS",
"latitude": null,
"longitude": null,
"metadata": null,
"scanned_at": "2026-06-15T10:30:00.000000Z",
"deleted_at": null,
"created_at": "2026-06-15T10:30:00.000000Z",
"updated_at": "2026-06-15T10:30:00.000000Z"
}
],
"first_page_url": "https://production-api.shoutaboutus.com/api/v1/qr-codes/template/2964/scan-history?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://production-api.shoutaboutus.com/api/v1/qr-codes/template/2964/scan-history?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "https://production-api.shoutaboutus.com/api/v1/qr-codes/template/2964/scan-history?page=1",
"label": "1",
"page": 1,
"active": true
},
{
"url": null,
"label": "Next »",
"page": null,
"active": false
}
],
"next_page_url": null,
"path": "https://production-api.shoutaboutus.com/api/v1/qr-codes/template/2964/scan-history",
"per_page": 15,
"prev_page_url": null,
"to": 1,
"total": 1
},
"message": "QR code template scan history retrieved successfully",
"qr_code_template": {
"id": 2964,
"name": "Default QR Code Template"
}
}
}Examples
Success payload
A design with one scan: see Response payload.
No scans yet:
{
"data": {
"status": "success",
"data": {
"current_page": 1,
"data": [],
"first_page_url": "https://production-api.shoutaboutus.com/api/v1/qr-codes/template/2964/scan-history?page=1",
"from": null,
"last_page": 1,
"last_page_url": "https://production-api.shoutaboutus.com/api/v1/qr-codes/template/2964/scan-history?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "https://production-api.shoutaboutus.com/api/v1/qr-codes/template/2964/scan-history?page=1",
"label": "1",
"page": 1,
"active": true
},
{
"url": null,
"label": "Next »",
"page": null,
"active": false
}
],
"next_page_url": null,
"path": "https://production-api.shoutaboutus.com/api/v1/qr-codes/template/2964/scan-history",
"per_page": 15,
"prev_page_url": null,
"to": null,
"total": 0
},
"message": "QR code template scan history retrieved successfully",
"qr_code_template": {
"id": 2964,
"name": "Default QR Code Template"
}
}
}Error payload
404 QR code template not found
{
"message": "QR code template not found",
"status": "error",
"errors": []
}422 Id doesn't exist
{
"message": "The selected id is invalid.",
"errors": {
"id": [
"The selected id is invalid."
]
}
}422 per_page above 100
{
"message": "The per page field must not be greater than 100.",
"errors": {
"per_page": [
"The per page field must not be greater than 100."
]
}
}429 Too many requests
{
"message": "Too Many Attempts."
}| Status | Meaning |
|---|---|
200 | One page of scans. |
401 | The token is missing, expired or invalid. |
404 | The design isn't in your company (QR code template not found). |
422 | The design id doesn't exist, or per_page is above 100. |
429 | More than 120 requests in a minute from this user. |
500 | Unexpected server error. |
Example request
curl --request GET \
--url "https://production-api.shoutaboutus.com/api/v1/qr-codes/template/2964/scan-history?per_page=15" \
--header 'Authorization: Bearer <bearer-token>' \
--header 'Accept: application/json'Updated 17 days ago
