curl --request GET \
--url https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results \
--header 'X-Session-Token: <api-key>'import requests
url = "https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results"
headers = {"X-Session-Token": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-Session-Token': '<api-key>'}};
fetch('https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-Session-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-Session-Token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results")
.header("X-Session-Token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-Session-Token"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "standard-results",
"attributes": {
"standard": "<string>",
"bucket": "day",
"truncated": true,
"counts": {
"met": 123,
"breached": 123,
"exempt": 123,
"not_applicable": 123,
"incomplete": 123
},
"series": [
{
"start": "2026-07-13",
"counts": {
"met": 123,
"breached": 123,
"exempt": 123,
"not_applicable": 123,
"incomplete": 123
}
}
],
"jobs": [
{
"submission_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"result": "met",
"reasons": [
"<string>"
],
"missing": [
"<string>"
],
"inputs": {},
"submitted_at": "2023-11-07T05:31:56Z",
"period_date": "2023-11-07T05:31:56Z",
"payment": {
"submission_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "paid",
"paid_on": "2026-10-30",
"amount": {
"amount": 9250,
"currency": "GBP"
},
"reason": "<string>",
"note": "<string>"
},
"expected_payment": {
"priced": true,
"amount": {
"amount": 9250,
"currency": "GBP"
},
"total": {
"amount": 9250,
"currency": "GBP"
},
"reasons": [
"<string>"
],
"late_payment": {
"amount": 9250,
"currency": "GBP"
},
"source": "platform",
"effective_from": "2023-12-25",
"due_by": "2023-12-25"
}
}
],
"payments_shown": true,
"skipped": 1,
"expected_total": {
"amount": 9250,
"currency": "GBP"
},
"paid_total": {
"amount": 9250,
"currency": "GBP"
}
}
},
"jsonapi": {
"version": "1.0"
}
}{
"id": "98ca4a78-b66f-4234-9719-aaf832ee6669",
"status": "400",
"title": "A validation error was encountered",
"source": {
"parameter": "include"
},
"meta": {
"resource": "wrong_value"
}
}{
"id": "05fc9c8d-73b9-4697-9337-57f7a567a48f",
"status": "401",
"title": "You are not authorised to access this resource",
"detail": "In order to access this resource, you need the 'admin' role.",
"code": "AUTH.001"
}{
"id": "7b4c8f12-3e9a-4d5b-8c6f-1a2b3c4d5e6f",
"status": "404",
"title": "Resource not found",
"detail": "The requested resource could not be found or does not exist.",
"code": "NOT_FOUND.001"
}{
"id": "fe9d9a69-f0a7-4fdc-bb2c-176027f316c5",
"status": "500",
"title": "Internal Server Error",
"detail": "An unexpected error occurred on the server."
}Get a standard's results
Evaluate a standard mapping’s standard over a period, and return each job’s result with its reasons and inputs, the counts by result, and a series of counts per bucket. A job is in the period when the mapping’s period input falls in it. Without date_op, the period is the last 30 days. The rows are the submissions the caller can see, so a contractor reading the form owner’s mapping gets results for its own jobs only. A run evaluates at most 50,000 jobs, and says when it was truncated. A caller who can view standards across the organisation also gets each job’s payment record, and a withdrawn record is left off. A caller who views some forms’ mappings only does not. With submission_id, the run evaluates that one submission whatever its date, and the series is empty. It returns no jobs when the submission is not in analytics yet, and is refused with date_op, date_values or bucket.
curl --request GET \
--url https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results \
--header 'X-Session-Token: <api-key>'import requests
url = "https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results"
headers = {"X-Session-Token": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-Session-Token': '<api-key>'}};
fetch('https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-Session-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-Session-Token", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results")
.header("X-Session-Token", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ctrl-hub.com/v3/orgs/{org_id}/standard-mappings/{standard_mapping_id}/results")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-Session-Token"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "standard-results",
"attributes": {
"standard": "<string>",
"bucket": "day",
"truncated": true,
"counts": {
"met": 123,
"breached": 123,
"exempt": 123,
"not_applicable": 123,
"incomplete": 123
},
"series": [
{
"start": "2026-07-13",
"counts": {
"met": 123,
"breached": 123,
"exempt": 123,
"not_applicable": 123,
"incomplete": 123
}
}
],
"jobs": [
{
"submission_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"result": "met",
"reasons": [
"<string>"
],
"missing": [
"<string>"
],
"inputs": {},
"submitted_at": "2023-11-07T05:31:56Z",
"period_date": "2023-11-07T05:31:56Z",
"payment": {
"submission_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "paid",
"paid_on": "2026-10-30",
"amount": {
"amount": 9250,
"currency": "GBP"
},
"reason": "<string>",
"note": "<string>"
},
"expected_payment": {
"priced": true,
"amount": {
"amount": 9250,
"currency": "GBP"
},
"total": {
"amount": 9250,
"currency": "GBP"
},
"reasons": [
"<string>"
],
"late_payment": {
"amount": 9250,
"currency": "GBP"
},
"source": "platform",
"effective_from": "2023-12-25",
"due_by": "2023-12-25"
}
}
],
"payments_shown": true,
"skipped": 1,
"expected_total": {
"amount": 9250,
"currency": "GBP"
},
"paid_total": {
"amount": 9250,
"currency": "GBP"
}
}
},
"jsonapi": {
"version": "1.0"
}
}{
"id": "98ca4a78-b66f-4234-9719-aaf832ee6669",
"status": "400",
"title": "A validation error was encountered",
"source": {
"parameter": "include"
},
"meta": {
"resource": "wrong_value"
}
}{
"id": "05fc9c8d-73b9-4697-9337-57f7a567a48f",
"status": "401",
"title": "You are not authorised to access this resource",
"detail": "In order to access this resource, you need the 'admin' role.",
"code": "AUTH.001"
}{
"id": "7b4c8f12-3e9a-4d5b-8c6f-1a2b3c4d5e6f",
"status": "404",
"title": "Resource not found",
"detail": "The requested resource could not be found or does not exist.",
"code": "NOT_FOUND.001"
}{
"id": "fe9d9a69-f0a7-4fdc-bb2c-176027f316c5",
"status": "500",
"title": "Internal Server Error",
"detail": "An unexpected error occurred on the server."
}Authorizations
Session token for authentication.
Path Parameters
The unique identifier for the organisation.
The unique identifier for the standard mapping.
Query Parameters
The period to evaluate, as the operator of a range on the mapping's period input. Relative presets (today, yesterday, last_n_days, this_week, this_month, this_quarter, this_year, and the previous full last_week, last_fortnight, last_month and last_quarter) are resolved against the Europe/London timezone when the results are read. between takes two dates, and before and after one, in date_values. Omit it for the last 30 days.
today, yesterday, last_n_days, this_week, this_month, this_quarter, this_year, last_week, last_fortnight, last_month, last_quarter, between, before, after The values date_op takes, comma separated: the number of days for last_n_days, the two ends of a between, or the one date of a before or after. A date, such as 2026-11-02, or a date and time, such as 2026-11-02 09:00:00, is read in Europe/London. An RFC 3339 time, such as 2026-11-02T09:00:00Z, keeps its own offset. A between includes both ends, and a date as its upper bound covers that whole day. before a date excludes that day, and after a date starts on the day after it.
The length of the periods the series counts jobs in. A week starts on Monday. Omit it for weeks.
day, week, month, quarter, year Evaluate this one submission instead of a period. It takes no date_op, date_values or bucket.