curl --request POST \
--url https://api.qa.tech/v1/chat/change-review \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"mode": "pr",
"prUrl": "<string>",
"applicationOverrides": [
{
"applicationShortId": "<string>",
"environment": {
"url": "<string>",
"name": "<string>",
"customHeaders": [
{
"domains": [
"<string>"
],
"headers": {}
}
]
},
"devicePresetShortId": "<string>"
}
],
"context": "<string>",
"forceNewConversation": false,
"actor": "<string>",
"branch": "<string>",
"commitHash": "<string>",
"commitMessage": "<string>",
"repository": "<string>",
"projectShortId": "<string>"
}
'import requests
url = "https://api.qa.tech/v1/chat/change-review"
payload = {
"mode": "pr",
"prUrl": "<string>",
"applicationOverrides": [
{
"applicationShortId": "<string>",
"environment": {
"url": "<string>",
"name": "<string>",
"customHeaders": [
{
"domains": ["<string>"],
"headers": {}
}
]
},
"devicePresetShortId": "<string>"
}
],
"context": "<string>",
"forceNewConversation": False,
"actor": "<string>",
"branch": "<string>",
"commitHash": "<string>",
"commitMessage": "<string>",
"repository": "<string>",
"projectShortId": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
mode: 'pr',
prUrl: '<string>',
applicationOverrides: [
{
applicationShortId: '<string>',
environment: {
url: '<string>',
name: '<string>',
customHeaders: [{domains: ['<string>'], headers: {}}]
},
devicePresetShortId: '<string>'
}
],
context: '<string>',
forceNewConversation: false,
actor: '<string>',
branch: '<string>',
commitHash: '<string>',
commitMessage: '<string>',
repository: '<string>',
projectShortId: '<string>'
})
};
fetch('https://api.qa.tech/v1/chat/change-review', 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.qa.tech/v1/chat/change-review",
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([
'mode' => 'pr',
'prUrl' => '<string>',
'applicationOverrides' => [
[
'applicationShortId' => '<string>',
'environment' => [
'url' => '<string>',
'name' => '<string>',
'customHeaders' => [
[
'domains' => [
'<string>'
],
'headers' => [
]
]
]
],
'devicePresetShortId' => '<string>'
]
],
'context' => '<string>',
'forceNewConversation' => false,
'actor' => '<string>',
'branch' => '<string>',
'commitHash' => '<string>',
'commitMessage' => '<string>',
'repository' => '<string>',
'projectShortId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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 := "https://api.qa.tech/v1/chat/change-review"
payload := strings.NewReader("{\n \"mode\": \"pr\",\n \"prUrl\": \"<string>\",\n \"applicationOverrides\": [\n {\n \"applicationShortId\": \"<string>\",\n \"environment\": {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"customHeaders\": [\n {\n \"domains\": [\n \"<string>\"\n ],\n \"headers\": {}\n }\n ]\n },\n \"devicePresetShortId\": \"<string>\"\n }\n ],\n \"context\": \"<string>\",\n \"forceNewConversation\": false,\n \"actor\": \"<string>\",\n \"branch\": \"<string>\",\n \"commitHash\": \"<string>\",\n \"commitMessage\": \"<string>\",\n \"repository\": \"<string>\",\n \"projectShortId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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("https://api.qa.tech/v1/chat/change-review")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"mode\": \"pr\",\n \"prUrl\": \"<string>\",\n \"applicationOverrides\": [\n {\n \"applicationShortId\": \"<string>\",\n \"environment\": {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"customHeaders\": [\n {\n \"domains\": [\n \"<string>\"\n ],\n \"headers\": {}\n }\n ]\n },\n \"devicePresetShortId\": \"<string>\"\n }\n ],\n \"context\": \"<string>\",\n \"forceNewConversation\": false,\n \"actor\": \"<string>\",\n \"branch\": \"<string>\",\n \"commitHash\": \"<string>\",\n \"commitMessage\": \"<string>\",\n \"repository\": \"<string>\",\n \"projectShortId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qa.tech/v1/chat/change-review")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"mode\": \"pr\",\n \"prUrl\": \"<string>\",\n \"applicationOverrides\": [\n {\n \"applicationShortId\": \"<string>\",\n \"environment\": {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"customHeaders\": [\n {\n \"domains\": [\n \"<string>\"\n ],\n \"headers\": {}\n }\n ]\n },\n \"devicePresetShortId\": \"<string>\"\n }\n ],\n \"context\": \"<string>\",\n \"forceNewConversation\": false,\n \"actor\": \"<string>\",\n \"branch\": \"<string>\",\n \"commitHash\": \"<string>\",\n \"commitMessage\": \"<string>\",\n \"repository\": \"<string>\",\n \"projectShortId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"shortId": "<string>",
"url": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"status": "in_progress",
"runs": [
{
"shortId": "<string>",
"status": "<string>",
"result": "<string>",
"url": "<string>"
}
],
"title": "<string>",
"source": "api",
"messages": [
{
"id": "<string>",
"role": "user",
"createdAt": "2023-11-07T05:31:56Z",
"text": "<string>",
"status": "INITIATED",
"isStreaming": true
}
]
}Start change review chat
Create a new chat conversation and start an autonomous change review from either a PR URL or raw change input.
curl --request POST \
--url https://api.qa.tech/v1/chat/change-review \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"mode": "pr",
"prUrl": "<string>",
"applicationOverrides": [
{
"applicationShortId": "<string>",
"environment": {
"url": "<string>",
"name": "<string>",
"customHeaders": [
{
"domains": [
"<string>"
],
"headers": {}
}
]
},
"devicePresetShortId": "<string>"
}
],
"context": "<string>",
"forceNewConversation": false,
"actor": "<string>",
"branch": "<string>",
"commitHash": "<string>",
"commitMessage": "<string>",
"repository": "<string>",
"projectShortId": "<string>"
}
'import requests
url = "https://api.qa.tech/v1/chat/change-review"
payload = {
"mode": "pr",
"prUrl": "<string>",
"applicationOverrides": [
{
"applicationShortId": "<string>",
"environment": {
"url": "<string>",
"name": "<string>",
"customHeaders": [
{
"domains": ["<string>"],
"headers": {}
}
]
},
"devicePresetShortId": "<string>"
}
],
"context": "<string>",
"forceNewConversation": False,
"actor": "<string>",
"branch": "<string>",
"commitHash": "<string>",
"commitMessage": "<string>",
"repository": "<string>",
"projectShortId": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
mode: 'pr',
prUrl: '<string>',
applicationOverrides: [
{
applicationShortId: '<string>',
environment: {
url: '<string>',
name: '<string>',
customHeaders: [{domains: ['<string>'], headers: {}}]
},
devicePresetShortId: '<string>'
}
],
context: '<string>',
forceNewConversation: false,
actor: '<string>',
branch: '<string>',
commitHash: '<string>',
commitMessage: '<string>',
repository: '<string>',
projectShortId: '<string>'
})
};
fetch('https://api.qa.tech/v1/chat/change-review', 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.qa.tech/v1/chat/change-review",
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([
'mode' => 'pr',
'prUrl' => '<string>',
'applicationOverrides' => [
[
'applicationShortId' => '<string>',
'environment' => [
'url' => '<string>',
'name' => '<string>',
'customHeaders' => [
[
'domains' => [
'<string>'
],
'headers' => [
]
]
]
],
'devicePresetShortId' => '<string>'
]
],
'context' => '<string>',
'forceNewConversation' => false,
'actor' => '<string>',
'branch' => '<string>',
'commitHash' => '<string>',
'commitMessage' => '<string>',
'repository' => '<string>',
'projectShortId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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 := "https://api.qa.tech/v1/chat/change-review"
payload := strings.NewReader("{\n \"mode\": \"pr\",\n \"prUrl\": \"<string>\",\n \"applicationOverrides\": [\n {\n \"applicationShortId\": \"<string>\",\n \"environment\": {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"customHeaders\": [\n {\n \"domains\": [\n \"<string>\"\n ],\n \"headers\": {}\n }\n ]\n },\n \"devicePresetShortId\": \"<string>\"\n }\n ],\n \"context\": \"<string>\",\n \"forceNewConversation\": false,\n \"actor\": \"<string>\",\n \"branch\": \"<string>\",\n \"commitHash\": \"<string>\",\n \"commitMessage\": \"<string>\",\n \"repository\": \"<string>\",\n \"projectShortId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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("https://api.qa.tech/v1/chat/change-review")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"mode\": \"pr\",\n \"prUrl\": \"<string>\",\n \"applicationOverrides\": [\n {\n \"applicationShortId\": \"<string>\",\n \"environment\": {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"customHeaders\": [\n {\n \"domains\": [\n \"<string>\"\n ],\n \"headers\": {}\n }\n ]\n },\n \"devicePresetShortId\": \"<string>\"\n }\n ],\n \"context\": \"<string>\",\n \"forceNewConversation\": false,\n \"actor\": \"<string>\",\n \"branch\": \"<string>\",\n \"commitHash\": \"<string>\",\n \"commitMessage\": \"<string>\",\n \"repository\": \"<string>\",\n \"projectShortId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qa.tech/v1/chat/change-review")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"mode\": \"pr\",\n \"prUrl\": \"<string>\",\n \"applicationOverrides\": [\n {\n \"applicationShortId\": \"<string>\",\n \"environment\": {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"customHeaders\": [\n {\n \"domains\": [\n \"<string>\"\n ],\n \"headers\": {}\n }\n ]\n },\n \"devicePresetShortId\": \"<string>\"\n }\n ],\n \"context\": \"<string>\",\n \"forceNewConversation\": false,\n \"actor\": \"<string>\",\n \"branch\": \"<string>\",\n \"commitHash\": \"<string>\",\n \"commitMessage\": \"<string>\",\n \"repository\": \"<string>\",\n \"projectShortId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"shortId": "<string>",
"url": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"status": "in_progress",
"runs": [
{
"shortId": "<string>",
"status": "<string>",
"result": "<string>",
"url": "<string>"
}
],
"title": "<string>",
"source": "api",
"messages": [
{
"id": "<string>",
"role": "user",
"createdAt": "2023-11-07T05:31:56Z",
"text": "<string>",
"status": "INITIATED",
"isStreaming": true
}
]
}Body
- Option 1
- Option 2
Request body for starting a change review chat
pr Supported VCS providers for pull request URL review mode
github, gitlab Required per-application environment overrides. Optional customHeaders on environment persist auth or protection-bypass headers.
Show child attributes
Show child attributes
Force a brand-new chat instead of reusing the pull request's existing review conversation. Defaults to false, so repeated reviews of the same PR share one chat unless that chat is archived.
Optional post-merge options for this PR. Stored on the review conversation and applied when the PR merges. Overrides GitHub App integration settings for this PR only.
Show child attributes
Show child attributes
Username that triggered the CI job. Example: octocat.
Branch the run was triggered from. Example: main or refs/heads/main.
Full commit SHA the run was triggered for. Used to link the run back to the commit.
Commit message subject for the triggering commit.
Repository the run was triggered from, as owner/name. Example: QAdottech/qatech.
Target a specific project by its prefixed short ID (proj-slug_shortId or proj_shortId), as returned by the projects API. Required for organization-scoped API keys; project-scoped keys may only pass their own project's short ID.
^proj(-.+_.+|_.+)$Response
The request has been accepted for processing, but processing has not yet completed.
Conversation data with recent messages (newest first).
^chat(-.+_.+|_.+)$Dashboard URL for the conversation.
Overall conversation lifecycle. in_progress while the assistant is working or a background test run / research task is still going. Assistant message COMPLETED is not enough — starting a run ends the current turn. Poll until this is completed, failed, or cancelled.
in_progress, completed, failed, cancelled Test runs started from this conversation, newest first. Empty until a run is created. Use shortId with get_run (testCases = all) or nested test-case short IDs from that call with get_run_test_case.
Show child attributes
Show child attributes
Where the conversation originated. api for conversations created via this API, ui for the dashboard, github/gitlab for VCS-triggered chats, and system for everything else.
api, ui, github, gitlab, system Recent messages, newest first. Empty on creation; poll get_chat_conversation to retrieve. Internal wake messages are omitted.
Show child attributes
Show child attributes
Was this page helpful?