curl --request PUT \
--url https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"summary": "<string>",
"explanation": "<string>",
"reproduction": "<string>",
"fixDetails": "<string>",
"annotationID": "<string>"
}
'import requests
url = "https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation"
payload = {
"summary": "<string>",
"explanation": "<string>",
"reproduction": "<string>",
"fixDetails": "<string>",
"annotationID": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
summary: '<string>',
explanation: '<string>',
reproduction: '<string>',
fixDetails: '<string>',
annotationID: '<string>'
})
};
fetch('https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation', 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.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'summary' => '<string>',
'explanation' => '<string>',
'reproduction' => '<string>',
'fixDetails' => '<string>',
'annotationID' => '<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.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation"
payload := strings.NewReader("{\n \"summary\": \"<string>\",\n \"explanation\": \"<string>\",\n \"reproduction\": \"<string>\",\n \"fixDetails\": \"<string>\",\n \"annotationID\": \"<string>\"\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"summary\": \"<string>\",\n \"explanation\": \"<string>\",\n \"reproduction\": \"<string>\",\n \"fixDetails\": \"<string>\",\n \"annotationID\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"summary\": \"<string>\",\n \"explanation\": \"<string>\",\n \"reproduction\": \"<string>\",\n \"fixDetails\": \"<string>\",\n \"annotationID\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"action": "ignore",
"summary": "<string>",
"source": "manual",
"createdMs": 123,
"updatedMs": 123,
"explanation": "<string>",
"reproduction": "<string>",
"fixDetails": "<string>",
"annotationID": "<string>",
"annotation": {
"id": "<string>",
"headline": "<string>",
"dateMs": 123,
"createdMs": 123,
"updatedMs": 123,
"description": "<string>"
},
"assets": [
{
"id": "<string>",
"fileName": "<string>",
"contentType": "<string>",
"sizeBytes": 123,
"status": "pending",
"createdMs": 123
}
]
}{
"error": {
"message": "Validation failed",
"details": [
{
"field": "projectID",
"message": "required"
}
]
}
}Upsert error recommendation
Creates or fully replaces the error’s recommendation (an error has at most one). Full-replace semantics like the error update: every field is taken from this request, so omitting annotationID reopens a resolved recommendation (the linked annotation IS the resolution).
Required API key permission: observe:errors:write.
curl --request PUT \
--url https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"summary": "<string>",
"explanation": "<string>",
"reproduction": "<string>",
"fixDetails": "<string>",
"annotationID": "<string>"
}
'import requests
url = "https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation"
payload = {
"summary": "<string>",
"explanation": "<string>",
"reproduction": "<string>",
"fixDetails": "<string>",
"annotationID": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
summary: '<string>',
explanation: '<string>',
reproduction: '<string>',
fixDetails: '<string>',
annotationID: '<string>'
})
};
fetch('https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation', 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.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'summary' => '<string>',
'explanation' => '<string>',
'reproduction' => '<string>',
'fixDetails' => '<string>',
'annotationID' => '<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.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation"
payload := strings.NewReader("{\n \"summary\": \"<string>\",\n \"explanation\": \"<string>\",\n \"reproduction\": \"<string>\",\n \"fixDetails\": \"<string>\",\n \"annotationID\": \"<string>\"\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"summary\": \"<string>\",\n \"explanation\": \"<string>\",\n \"reproduction\": \"<string>\",\n \"fixDetails\": \"<string>\",\n \"annotationID\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloud.corbado.io/v1/observe/errors/{errorID}/recommendation")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"summary\": \"<string>\",\n \"explanation\": \"<string>\",\n \"reproduction\": \"<string>\",\n \"fixDetails\": \"<string>\",\n \"annotationID\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"action": "ignore",
"summary": "<string>",
"source": "manual",
"createdMs": 123,
"updatedMs": 123,
"explanation": "<string>",
"reproduction": "<string>",
"fixDetails": "<string>",
"annotationID": "<string>",
"annotation": {
"id": "<string>",
"headline": "<string>",
"dateMs": 123,
"createdMs": 123,
"updatedMs": 123,
"description": "<string>"
},
"assets": [
{
"id": "<string>",
"fileName": "<string>",
"contentType": "<string>",
"sizeBytes": 123,
"status": "pending",
"createdMs": 123
}
]
}{
"error": {
"message": "Validation failed",
"details": [
{
"field": "projectID",
"message": "required"
}
]
}
}Authorizations
Use an Observe API key from the management console. The key selects the project and must grant the permission listed on the operation. Keep this key on your server.
Path Parameters
Error ID (format err-<number>).
Body
Recommended handling of the error.
ignore, observe, fix One-line summary of the recommendation.
What happens and why (root cause), as markdown.
Preconditions and steps to reproduce, as markdown.
The recommended fix in detail, as markdown. Required when action is fix.
Provenance of the recommendation content; defaults to manual.
manual, ai-draft Annotation marking that the recommended action was carried out (format ann-<number>) — linking it IS
resolving the recommendation. Must exist in the project. Omitting it on a later upsert reopens (the
annotation itself is untouched).
Response
The stored recommendation.
Curated guidance attached to an error (at most one per error): what the error is and how to reproduce it, the recommended handling (ignore / observe / fix), and — for fix — the fix in detail. Human-created like the error itself; classification never writes it. Free-text fields are markdown.
Recommendation ID (format erc-<number>).
Recommended handling of the error.
ignore, observe, fix One-line summary of the recommendation.
Provenance of the recommendation content.
manual, ai-draft Creation time in milliseconds since epoch.
Last update time in milliseconds since epoch.
What happens and why (root cause), as markdown.
Preconditions and steps to reproduce, as markdown.
The recommended fix in detail, as markdown. Present when action is fix.
ID of the annotation marking that the recommended action was carried out (format ann-<number>). Its
presence IS the resolved state: the annotation's date is when, its description what was done. Absent
while still open. The link survives the annotation's deletion; annotation is then absent.
Show child attributes
Show child attributes
Media assets (screenshots, videos) attached to this recommendation, oldest first. Only confirmed (ready) uploads appear. View URLs are minted per asset via the downloadUrl endpoint.
100Show child attributes
Show child attributes
Was this page helpful?