curl --request POST \
--url http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--header 'X-QA-Lab-Admin-Id: <x-qa-lab-admin-id>' \
--header 'X-QA-Lab-Nonce: <x-qa-lab-nonce>' \
--header 'X-QA-Lab-Permission: <x-qa-lab-permission>' \
--header 'X-QA-Lab-Signature: <api-key>' \
--header 'X-QA-Lab-Timestamp: <x-qa-lab-timestamp>' \
--data '
{
"scenario_key": "application.applied",
"scenario_version": 1,
"brand_id": 1001,
"athlete_ids": [
2001,
2002
],
"options": {}
}
'import requests
url = "http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview"
payload = {
"scenario_key": "application.applied",
"scenario_version": 1,
"brand_id": 1001,
"athlete_ids": [2001, 2002],
"options": {}
}
headers = {
"X-API-KEY": "<api-key>",
"X-QA-Lab-Admin-Id": "<x-qa-lab-admin-id>",
"X-QA-Lab-Timestamp": "<x-qa-lab-timestamp>",
"X-QA-Lab-Nonce": "<x-qa-lab-nonce>",
"X-QA-Lab-Permission": "<x-qa-lab-permission>",
"X-QA-Lab-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-API-KEY': '<api-key>',
'X-QA-Lab-Admin-Id': '<x-qa-lab-admin-id>',
'X-QA-Lab-Timestamp': '<x-qa-lab-timestamp>',
'X-QA-Lab-Nonce': '<x-qa-lab-nonce>',
'X-QA-Lab-Permission': '<x-qa-lab-permission>',
'X-QA-Lab-Signature': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
scenario_key: 'application.applied',
scenario_version: 1,
brand_id: 1001,
athlete_ids: [2001, 2002],
options: {}
})
};
fetch('http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview', 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 => "http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'scenario_key' => 'application.applied',
'scenario_version' => 1,
'brand_id' => 1001,
'athlete_ids' => [
2001,
2002
],
'options' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>",
"X-QA-Lab-Admin-Id: <x-qa-lab-admin-id>",
"X-QA-Lab-Nonce: <x-qa-lab-nonce>",
"X-QA-Lab-Permission: <x-qa-lab-permission>",
"X-QA-Lab-Signature: <api-key>",
"X-QA-Lab-Timestamp: <x-qa-lab-timestamp>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview"
payload := strings.NewReader("{\n \"scenario_key\": \"application.applied\",\n \"scenario_version\": 1,\n \"brand_id\": 1001,\n \"athlete_ids\": [\n 2001,\n 2002\n ],\n \"options\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("X-QA-Lab-Admin-Id", "<x-qa-lab-admin-id>")
req.Header.Add("X-QA-Lab-Timestamp", "<x-qa-lab-timestamp>")
req.Header.Add("X-QA-Lab-Nonce", "<x-qa-lab-nonce>")
req.Header.Add("X-QA-Lab-Permission", "<x-qa-lab-permission>")
req.Header.Add("X-QA-Lab-Signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview")
.header("X-API-KEY", "<api-key>")
.header("X-QA-Lab-Admin-Id", "<x-qa-lab-admin-id>")
.header("X-QA-Lab-Timestamp", "<x-qa-lab-timestamp>")
.header("X-QA-Lab-Nonce", "<x-qa-lab-nonce>")
.header("X-QA-Lab-Permission", "<x-qa-lab-permission>")
.header("X-QA-Lab-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"scenario_key\": \"application.applied\",\n \"scenario_version\": 1,\n \"brand_id\": 1001,\n \"athlete_ids\": [\n 2001,\n 2002\n ],\n \"options\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["X-QA-Lab-Admin-Id"] = '<x-qa-lab-admin-id>'
request["X-QA-Lab-Timestamp"] = '<x-qa-lab-timestamp>'
request["X-QA-Lab-Nonce"] = '<x-qa-lab-nonce>'
request["X-QA-Lab-Permission"] = '<x-qa-lab-permission>'
request["X-QA-Lab-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"scenario_key\": \"application.applied\",\n \"scenario_version\": 1,\n \"brand_id\": 1001,\n \"athlete_ids\": [\n 2001,\n 2002\n ],\n \"options\": {}\n}"
response = http.request(request)
puts response.read_body{
"data": {
"selection_fingerprint": "<string>",
"scenario": {
"key": "application.applied",
"version": 1,
"display_name": "Applied",
"description": "<string>",
"compensation": {},
"deliverable_count_per_athlete": 3,
"included_content": {
"fixture_files": true,
"brand_chat": true,
"assistant": true
},
"evaluation_correlation": true,
"evaluation_case_ref": "files_need_review_two_turn_v1",
"ordered_turn_count": 2
},
"actors": {},
"review": {}
},
"meta": {
"requested_by_admin_id": 2,
"reference_time": "2023-11-07T05:31:56Z"
}
}{
"message": "Unauthenticated."
}{
"message": "The given data was invalid.",
"errors": {}
}Preview a registered scenario without side effects
Requires one current non-deleted brand and at least one current non-deleted athlete. IDs and roles are resolved again from the database. Definition-specific options are allowlisted. The definition supplies the same compensation, deliverable, included-content, record, date, state, skipped-check, warning, notification, and feature-gate metadata used by creation. Database work performed by a preview definition is always rolled back; preview definitions must not perform file, message, notification, or AI side effects.
curl --request POST \
--url http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--header 'X-QA-Lab-Admin-Id: <x-qa-lab-admin-id>' \
--header 'X-QA-Lab-Nonce: <x-qa-lab-nonce>' \
--header 'X-QA-Lab-Permission: <x-qa-lab-permission>' \
--header 'X-QA-Lab-Signature: <api-key>' \
--header 'X-QA-Lab-Timestamp: <x-qa-lab-timestamp>' \
--data '
{
"scenario_key": "application.applied",
"scenario_version": 1,
"brand_id": 1001,
"athlete_ids": [
2001,
2002
],
"options": {}
}
'import requests
url = "http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview"
payload = {
"scenario_key": "application.applied",
"scenario_version": 1,
"brand_id": 1001,
"athlete_ids": [2001, 2002],
"options": {}
}
headers = {
"X-API-KEY": "<api-key>",
"X-QA-Lab-Admin-Id": "<x-qa-lab-admin-id>",
"X-QA-Lab-Timestamp": "<x-qa-lab-timestamp>",
"X-QA-Lab-Nonce": "<x-qa-lab-nonce>",
"X-QA-Lab-Permission": "<x-qa-lab-permission>",
"X-QA-Lab-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-API-KEY': '<api-key>',
'X-QA-Lab-Admin-Id': '<x-qa-lab-admin-id>',
'X-QA-Lab-Timestamp': '<x-qa-lab-timestamp>',
'X-QA-Lab-Nonce': '<x-qa-lab-nonce>',
'X-QA-Lab-Permission': '<x-qa-lab-permission>',
'X-QA-Lab-Signature': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
scenario_key: 'application.applied',
scenario_version: 1,
brand_id: 1001,
athlete_ids: [2001, 2002],
options: {}
})
};
fetch('http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview', 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 => "http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'scenario_key' => 'application.applied',
'scenario_version' => 1,
'brand_id' => 1001,
'athlete_ids' => [
2001,
2002
],
'options' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>",
"X-QA-Lab-Admin-Id: <x-qa-lab-admin-id>",
"X-QA-Lab-Nonce: <x-qa-lab-nonce>",
"X-QA-Lab-Permission: <x-qa-lab-permission>",
"X-QA-Lab-Signature: <api-key>",
"X-QA-Lab-Timestamp: <x-qa-lab-timestamp>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview"
payload := strings.NewReader("{\n \"scenario_key\": \"application.applied\",\n \"scenario_version\": 1,\n \"brand_id\": 1001,\n \"athlete_ids\": [\n 2001,\n 2002\n ],\n \"options\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("X-QA-Lab-Admin-Id", "<x-qa-lab-admin-id>")
req.Header.Add("X-QA-Lab-Timestamp", "<x-qa-lab-timestamp>")
req.Header.Add("X-QA-Lab-Nonce", "<x-qa-lab-nonce>")
req.Header.Add("X-QA-Lab-Permission", "<x-qa-lab-permission>")
req.Header.Add("X-QA-Lab-Signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview")
.header("X-API-KEY", "<api-key>")
.header("X-QA-Lab-Admin-Id", "<x-qa-lab-admin-id>")
.header("X-QA-Lab-Timestamp", "<x-qa-lab-timestamp>")
.header("X-QA-Lab-Nonce", "<x-qa-lab-nonce>")
.header("X-QA-Lab-Permission", "<x-qa-lab-permission>")
.header("X-QA-Lab-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"scenario_key\": \"application.applied\",\n \"scenario_version\": 1,\n \"brand_id\": 1001,\n \"athlete_ids\": [\n 2001,\n 2002\n ],\n \"options\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost/mogl/mogl-backend/api/internal/qa-scenario-lab/preview")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["X-QA-Lab-Admin-Id"] = '<x-qa-lab-admin-id>'
request["X-QA-Lab-Timestamp"] = '<x-qa-lab-timestamp>'
request["X-QA-Lab-Nonce"] = '<x-qa-lab-nonce>'
request["X-QA-Lab-Permission"] = '<x-qa-lab-permission>'
request["X-QA-Lab-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"scenario_key\": \"application.applied\",\n \"scenario_version\": 1,\n \"brand_id\": 1001,\n \"athlete_ids\": [\n 2001,\n 2002\n ],\n \"options\": {}\n}"
response = http.request(request)
puts response.read_body{
"data": {
"selection_fingerprint": "<string>",
"scenario": {
"key": "application.applied",
"version": 1,
"display_name": "Applied",
"description": "<string>",
"compensation": {},
"deliverable_count_per_athlete": 3,
"included_content": {
"fixture_files": true,
"brand_chat": true,
"assistant": true
},
"evaluation_correlation": true,
"evaluation_case_ref": "files_need_review_two_turn_v1",
"ordered_turn_count": 2
},
"actors": {},
"review": {}
},
"meta": {
"requested_by_admin_id": 2,
"reference_time": "2023-11-07T05:31:56Z"
}
}{
"message": "Unauthenticated."
}{
"message": "The given data was invalid.",
"errors": {}
}Authorizations
Server-to-Server API Key for internal/lambda/cron calls
HMAC-SHA256 signature for a one-use, short-lived Back Office administrator envelope. Used together with the dedicated X-API-KEY credential and the signed administrator, timestamp, nonce, and permission headers.
Headers
Dedicated QA Scenario Lab service credential.
Positive initiating Back Office administrator ID included in the signature.
x >= 142
Ten-digit Unix timestamp. Default maximum age is 300 seconds.
1791194024
One-use UUID included in the signature.
Signed permission claim.
qa_scenario_lab Lowercase hexadecimal HMAC-SHA256 of the canonical request envelope.
64^[a-f0-9]{64}$Body
100"application.applied"
x >= 11
x >= 11001
1 - 50 elementsx >= 1[2001, 2002]