curl --request POST \
--url https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"callbackUrl": "<string>"
}
'import requests
url = "https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix"
payload = { "callbackUrl": "<string>" }
headers = {
"x-api-key": "<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>', 'Content-Type': 'application/json'},
body: JSON.stringify({callbackUrl: '<string>'})
};
fetch('https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix', 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.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix",
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([
'callbackUrl' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix"
payload := strings.NewReader("{\n \"callbackUrl\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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("https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"callbackUrl\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"callbackUrl\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"status": "idle",
"result": {
"analysis": "<string>",
"changesSummary": [
"<string>"
],
"suggestedPrompt": "<string>",
"currentPrompt": "<string>",
"rubricIssues": [
"<string>"
],
"perAttempt": [
{
"attemptId": "<string>",
"testCaseName": "<string>",
"analysis": "<string>"
}
],
"skippedAttemptIds": [
"<string>"
],
"edits": [
{
"find": "<string>",
"replace": "<string>"
}
]
},
"stale": true,
"stage": "analyzing",
"progress": {
"outputChars": 123,
"promptChars": 123
}
}
}{
"data": {
"status": "idle",
"result": {
"analysis": "<string>",
"changesSummary": [
"<string>"
],
"suggestedPrompt": "<string>",
"currentPrompt": "<string>",
"rubricIssues": [
"<string>"
],
"perAttempt": [
{
"attemptId": "<string>",
"testCaseName": "<string>",
"analysis": "<string>"
}
],
"skippedAttemptIds": [
"<string>"
],
"edits": [
{
"find": "<string>",
"replace": "<string>"
}
]
},
"stale": true,
"stage": "analyzing",
"progress": {
"outputChars": 123,
"promptChars": 123
}
}
}{
"error": "unauthorized"
}{
"error": "not_found"
}Suggest a Fix for a Run
Ask for one prompt change that would make every failed test in a run pass.
Requesting a fix per attempt produces separate prompts that do not know about each other, and applying one can undo another. This endpoint analyzes all of the run’s failed attempts together and returns a single corrected prompt with a per-attempt breakdown, so failures that share a root cause get one coherent edit.
The wait, polling, and reuse behavior is identical to the per-attempt Suggest a Fix: the request waits up to 105 seconds, wait=0 returns status: running immediately for polling with Get Suggested Fix for a Run, asking again joins a preparation already in progress, and a suggestion prepared within the last 10 minutes is returned instantly.
The run must be finished and must contain at least one failed attempt. On runs with more than 12 failures, the most recent 12 are analyzed and the rest are listed in result.skippedAttemptIds.
curl --request POST \
--url https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"callbackUrl": "<string>"
}
'import requests
url = "https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix"
payload = { "callbackUrl": "<string>" }
headers = {
"x-api-key": "<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>', 'Content-Type': 'application/json'},
body: JSON.stringify({callbackUrl: '<string>'})
};
fetch('https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix', 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.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix",
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([
'callbackUrl' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix"
payload := strings.NewReader("{\n \"callbackUrl\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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("https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"callbackUrl\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.revring.ai/v1/test-suites/{id}/runs/{runId}/suggest-fix")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"callbackUrl\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"status": "idle",
"result": {
"analysis": "<string>",
"changesSummary": [
"<string>"
],
"suggestedPrompt": "<string>",
"currentPrompt": "<string>",
"rubricIssues": [
"<string>"
],
"perAttempt": [
{
"attemptId": "<string>",
"testCaseName": "<string>",
"analysis": "<string>"
}
],
"skippedAttemptIds": [
"<string>"
],
"edits": [
{
"find": "<string>",
"replace": "<string>"
}
]
},
"stale": true,
"stage": "analyzing",
"progress": {
"outputChars": 123,
"promptChars": 123
}
}
}{
"data": {
"status": "idle",
"result": {
"analysis": "<string>",
"changesSummary": [
"<string>"
],
"suggestedPrompt": "<string>",
"currentPrompt": "<string>",
"rubricIssues": [
"<string>"
],
"perAttempt": [
{
"attemptId": "<string>",
"testCaseName": "<string>",
"analysis": "<string>"
}
],
"skippedAttemptIds": [
"<string>"
],
"edits": [
{
"find": "<string>",
"replace": "<string>"
}
]
},
"stale": true,
"stage": "analyzing",
"progress": {
"outputChars": 123,
"promptChars": 123
}
}
}{
"error": "unauthorized"
}{
"error": "not_found"
}Authorizations
API key for authentication. Generate API keys from the RevRing dashboard.
Query Parameters
Set to 0 to return immediately instead of waiting for the suggestion.
0 Body
Optional URL to notify when the suggestion finishes. We POST the completed job there (event test.suggestion.completed, with the same fields as the GET response), so you can stop polling. One delivery attempt, 8 second timeout.
Response
The suggestion, when it was ready in time. The suggestion fields are also present at the top level of data.
A proposed prompt change covering every failed attempt in a test run.
Show child attributes
Show child attributes