The Platform Statistics API provides aggregated data across all services for reporting, billing, and analytics purposes.
Base URL
Authentication
All endpoints require admin authentication.
Endpoints
Retrieve platform-wide notification statistics for a date range.
GET /platform-stats?start_date={start_date}&end_date={end_date}
Parameters
Start date in YYYY-MM-DD format. Defaults to today.
End date in YYYY-MM-DD format. Defaults to today.
Response
{
"email": {
"total": 1250000,
"delivered": 1248500,
"failed": 1500,
"requested": 1250000,
"technical-failure": 500,
"temporary-failure": 750,
"permanent-failure": 250
},
"sms": {
"total": 85000,
"delivered": 84200,
"failed": 800,
"requested": 85000,
"technical-failure": 200,
"temporary-failure": 400,
"permanent-failure": 200
},
"letter": {
"total": 12000,
"delivered": 11950,
"failed": 50,
"requested": 12000,
"technical-failure": 30,
"temporary-failure": 15,
"permanent-failure": 5
}
}
Response Fields
For each notification type (email, sms, letter):
total - Total notifications processed
delivered - Successfully delivered notifications
failed - Total failed notifications
requested - Total requested notifications
technical-failure - Technical failures (system errors)
temporary-failure - Temporary failures (will retry)
permanent-failure - Permanent failures (invalid recipient, etc.)
Get Billing Report Data
Retrieve comprehensive billing data for all services within a financial year date range.
GET /platform-stats/data-for-billing-report?start_date={start_date}&end_date={end_date}
Parameters
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
Both dates must be within the same financial year. The endpoint will return a 400 error if dates span multiple financial years.
Response
[
{
"organisation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organisation_name": "Department for Education",
"service_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"service_name": "Teacher Training Service",
"sms_cost": 125.50,
"sms_chargeable_units": 7606,
"total_letters": 450,
"letter_cost": 202.50,
"letter_breakdown": "200 second class letters at 45p\n250 first class letters at 45p\n",
"purchase_order_number": "PO-2024-12345",
"contact_names": "Jane Smith, John Doe",
"contact_email_addresses": "[email protected], [email protected]",
"billing_reference": "DFE-TTS-2024"
},
{
"organisation_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"organisation_name": "NHS Digital",
"service_id": "d4e5f6a7-b8c9-0123-def1-234567890123",
"service_name": "Appointment Reminders",
"sms_cost": 2450.75,
"sms_chargeable_units": 148530,
"total_letters": 0,
"letter_cost": 0,
"letter_breakdown": "",
"purchase_order_number": "NHS-2024-9876",
"contact_names": "Sarah Johnson",
"contact_email_addresses": "[email protected]",
"billing_reference": "NHS-APT-2024"
}
]
Response Fields
organisation_id - UUID of the organisation (empty string if none)
organisation_name - Name of the organisation (empty string if none)
service_id - UUID of the service
service_name - Name of the service
sms_cost - Total SMS cost in GBP
sms_chargeable_units - Total chargeable SMS units (fragments)
total_letters - Total number of letters sent
letter_cost - Total letter cost in GBP
letter_breakdown - Human-readable breakdown of letter costs by type
purchase_order_number - PO number for billing
contact_names - Billing contact names
contact_email_addresses - Billing contact emails
billing_reference - Service billing reference
The results are sorted by organisation name (blanks last), then by service name. Only services with non-zero costs are included.
Error Responses
{
"message": "Date must be in a single financial year.",
"status_code": 400
}
Or:{
"message": "Input must be a date in the format: YYYY-MM-DD",
"status_code": 400
}
Or:{
"message": "Start date must be before end date",
"status_code": 400
}
Get DVLA Billing Report Data
Retrieve DVLA-specific billing data for letters within a financial year date range.
GET /platform-stats/data-for-dvla-billing-report?start_date={start_date}&end_date={end_date}
Parameters
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
Both dates must be within the same financial year.
Response
[
{
"date": "2024-04-15",
"postage": "second",
"cost_threshold": "sorted",
"sheets": 5,
"rate": 0.31,
"letters": 1250,
"cost": 1937.50
},
{
"date": "2024-04-15",
"postage": "first",
"cost_threshold": "unsorted",
"sheets": 3,
"rate": 0.45,
"letters": 850,
"cost": 1147.50
}
]
Response Fields
date - Date in ISO format (YYYY-MM-DD)
postage - Postage class (first, second, europe, rest-of-world)
cost_threshold - Letter sorting threshold (sorted, unsorted)
sheets - Number of sheets per letter
rate - Rate per letter in GBP
letters - Number of letters sent
cost - Total cost in GBP
Daily Volumes Report
Retrieve daily notification volumes for the platform.
GET /platform-stats/daily-volumes-report?start_date={start_date}&end_date={end_date}
Parameters
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
Response
[
{
"day": "2024-04-15",
"sms_totals": 85000,
"sms_fragment_totals": 102000,
"sms_chargeable_units": 98500,
"email_totals": 1250000,
"letter_totals": 12000,
"letter_sheet_totals": 36000
},
{
"day": "2024-04-16",
"sms_totals": 92000,
"sms_fragment_totals": 110500,
"sms_chargeable_units": 106200,
"email_totals": 1345000,
"letter_totals": 11500,
"letter_sheet_totals": 34500
}
]
Response Fields
day - Date in YYYY-MM-DD format (BST timezone)
sms_totals - Total SMS notifications sent
sms_fragment_totals - Total SMS fragments (160-char chunks)
sms_chargeable_units - Chargeable SMS units
email_totals - Total emails sent
letter_totals - Total letters sent
letter_sheet_totals - Total letter sheets (pages)
Daily SMS Provider Volumes Report
Retrieve daily SMS volumes broken down by provider.
GET /platform-stats/daily-sms-provider-volumes-report?start_date={start_date}&end_date={end_date}
Parameters
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
Response
[
{
"day": "2024-04-15",
"provider": "mmg",
"sms_totals": 45000,
"sms_fragment_totals": 54000,
"sms_chargeable_units": 52000,
"sms_cost": 858.00
},
{
"day": "2024-04-15",
"provider": "firetext",
"sms_totals": 40000,
"sms_fragment_totals": 48000,
"sms_chargeable_units": 46500,
"sms_cost": 767.25
}
]
Response Fields
day - Date in ISO format (YYYY-MM-DD)
provider - SMS provider name (e.g., mmg, firetext)
sms_totals - Total SMS sent via this provider
sms_fragment_totals - Total SMS fragments
sms_chargeable_units - Chargeable units for this provider
sms_cost - Total cost for this provider in GBP
Volumes by Service Report
Retrieve notification volumes grouped by service.
GET /platform-stats/volumes-by-service?start_date={start_date}&end_date={end_date}
Parameters
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
Response
[
{
"service_name": "Teacher Training Service",
"service_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"organisation_name": "Department for Education",
"organisation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"free_allowance": 250000,
"sms_notifications": 5200,
"sms_chargeable_units": 6240,
"email_totals": 125000,
"letter_totals": 450,
"letter_sheet_totals": 1350,
"letter_cost": 202.50
},
{
"service_name": "Appointment Reminders",
"service_id": "d4e5f6a7-b8c9-0123-def1-234567890123",
"organisation_name": "NHS Digital",
"organisation_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"free_allowance": 250000,
"sms_notifications": 98500,
"sms_chargeable_units": 118200,
"email_totals": 450000,
"letter_totals": 0,
"letter_sheet_totals": 0,
"letter_cost": 0.0
}
]
Response Fields
service_name - Name of the service
service_id - UUID of the service
organisation_name - Name of parent organisation (empty string if none)
organisation_id - UUID of parent organisation (empty string if none)
free_allowance - Free SMS allowance for the service
sms_notifications - Total SMS notifications sent
sms_chargeable_units - Total chargeable SMS units
email_totals - Total emails sent
letter_totals - Total letters sent
letter_sheet_totals - Total letter sheets
letter_cost - Total letter cost in GBP
Common Error Responses
{
"message": "Input must be a date in the format: YYYY-MM-DD",
"status_code": 400
}
Invalid Date Range
{
"message": "Start date must be before end date",
"status_code": 400
}
Financial Year Validation
{
"message": "Date must be in a single financial year.",
"status_code": 400
}
Notes
- All dates use the YYYY-MM-DD format
- Times are in UTC unless specified as BST (British Summer Time)
- Financial year runs from April 1st to March 31st
- Cost values are in GBP (Great British Pounds)
- Empty organisation fields return empty strings, not null