curl --request POST \
--url https://api.cloud.corbado.io/v1/observe/errorFlavours/impact \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"flavourIDs": [
"<string>"
],
"fromDate": "2026-08-01T00:00:00",
"toDate": "2026-08-08T00:00:00",
"flowLimit": 5000,
"baselineFlowListID": "<string>",
"matching": {
"dimensions": [],
"ratio": 5,
"coverage": 0.75,
"minCellSize": 500
},
"errorID": "<string>"
}
'import requests
url = "https://api.cloud.corbado.io/v1/observe/errorFlavours/impact"
payload = {
"flavourIDs": ["<string>"],
"fromDate": "2026-08-01T00:00:00",
"toDate": "2026-08-08T00:00:00",
"flowLimit": 5000,
"baselineFlowListID": "<string>",
"matching": {
"dimensions": [],
"ratio": 5,
"coverage": 0.75,
"minCellSize": 500
},
"errorID": "<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({
flavourIDs: ['<string>'],
fromDate: '2026-08-01T00:00:00',
toDate: '2026-08-08T00:00:00',
flowLimit: 5000,
baselineFlowListID: '<string>',
matching: {dimensions: [], ratio: 5, coverage: 0.75, minCellSize: 500},
errorID: '<string>'
})
};
fetch('https://api.cloud.corbado.io/v1/observe/errorFlavours/impact', 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/errorFlavours/impact",
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([
'flavourIDs' => [
'<string>'
],
'fromDate' => '2026-08-01T00:00:00',
'toDate' => '2026-08-08T00:00:00',
'flowLimit' => 5000,
'baselineFlowListID' => '<string>',
'matching' => [
'dimensions' => [
],
'ratio' => 5,
'coverage' => 0.75,
'minCellSize' => 500
],
'errorID' => '<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/errorFlavours/impact"
payload := strings.NewReader("{\n \"flavourIDs\": [\n \"<string>\"\n ],\n \"fromDate\": \"2026-08-01T00:00:00\",\n \"toDate\": \"2026-08-08T00:00:00\",\n \"flowLimit\": 5000,\n \"baselineFlowListID\": \"<string>\",\n \"matching\": {\n \"dimensions\": [],\n \"ratio\": 5,\n \"coverage\": 0.75,\n \"minCellSize\": 500\n },\n \"errorID\": \"<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.cloud.corbado.io/v1/observe/errorFlavours/impact")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"flavourIDs\": [\n \"<string>\"\n ],\n \"fromDate\": \"2026-08-01T00:00:00\",\n \"toDate\": \"2026-08-08T00:00:00\",\n \"flowLimit\": 5000,\n \"baselineFlowListID\": \"<string>\",\n \"matching\": {\n \"dimensions\": [],\n \"ratio\": 5,\n \"coverage\": 0.75,\n \"minCellSize\": 500\n },\n \"errorID\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloud.corbado.io/v1/observe/errorFlavours/impact")
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 \"flavourIDs\": [\n \"<string>\"\n ],\n \"fromDate\": \"2026-08-01T00:00:00\",\n \"toDate\": \"2026-08-08T00:00:00\",\n \"flowLimit\": 5000,\n \"baselineFlowListID\": \"<string>\",\n \"matching\": {\n \"dimensions\": [],\n \"ratio\": 5,\n \"coverage\": 0.75,\n \"minCellSize\": 500\n },\n \"errorID\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"affected": {
"flowCount": 123,
"completeCount": 123,
"incompleteCount": 123,
"otherCount": 123,
"completionRate": 123,
"rawCompletionRate": 123,
"envMix": [
{
"osName": "<string>",
"browserName": "<string>",
"flowCount": 123,
"completedDurationP50Ms": 123,
"completedFlowsMeasured": 123,
"completionRate": 123
}
],
"flowTypes": [
{
"flowType": "<string>",
"flowCount": 123
}
],
"sampled": true,
"completedDurationP25Ms": 123,
"completedDurationP50Ms": 123,
"completedDurationP90Ms": 123,
"completedFlowsMeasured": 123,
"flowListID": "<string>"
},
"occurrenceCount": 123,
"orphanOccurrenceCount": 123,
"baseline": {
"flowCount": 123,
"completeCount": 123,
"incompleteCount": 123,
"otherCount": 123,
"completionRate": 123,
"rawCompletionRate": 123,
"envMix": [
{
"osName": "<string>",
"browserName": "<string>",
"flowCount": 123,
"completedDurationP50Ms": 123,
"completedFlowsMeasured": 123,
"completionRate": 123
}
],
"flowTypes": [
{
"flowType": "<string>",
"flowCount": 123
}
],
"sampled": true,
"completedDurationP25Ms": 123,
"completedDurationP50Ms": 123,
"completedDurationP90Ms": 123,
"completedFlowsMeasured": 123,
"flowListID": "<string>"
},
"completionLift": 123,
"occurrencesPerFlowAvg": 123,
"affectedUserCount": 123,
"repeatUserCount": 123,
"repeatUserOccurrenceCount": 123,
"repeatUserFlowCount": 123,
"repeatUserFlowListID": "<string>",
"userExposure": [
{
"minOccurrences": 123,
"userCount": 123,
"flowCount": 123,
"occurrenceCount": 123,
"maxOccurrences": 123,
"attemptCount": 123,
"completionRate": 123,
"flowListID": "<string>"
}
],
"unattributedFlows": {
"flowCount": 123,
"occurrenceCount": 123,
"attemptCount": 123,
"completionRate": 123,
"flowListID": "<string>"
},
"terminalIncompleteFlowCount": 123,
"analyzedFlowLimit": 123,
"matchingReport": {
"mode": "matched",
"dimensions": [
"<string>"
],
"prefixesUnavailable": true,
"matchRate": 123,
"uncoveredPrefixShare": 123,
"collapsedStrataCount": 123,
"strata": [
{
"affectedFlowCount": 123,
"baselineFlowCount": 123,
"collapseLevel": 123,
"flowType": "<string>",
"pathPrefix": "<string>",
"errorSubflow": "<string>",
"osName": "<string>",
"browserName": "<string>",
"touchpoint": "<string>",
"applicationID": "<string>"
}
],
"balance": [
{
"dimension": "<string>",
"imbalanceBefore": 123,
"imbalanceAfter": 123
}
]
},
"perFlowType": [
{
"flowType": "<string>",
"affectedFlowCount": 123,
"affectedAttemptCount": 123,
"baselineFlowCount": 123,
"baselineAttemptCount": 123,
"affectedCompletionRate": 123,
"affectedCompletedDurationP50Ms": 123,
"affectedCompletedFlowsMeasured": 123,
"baselineCompletionRate": 123,
"baselineCompletedDurationP50Ms": 123,
"baselineCompletedFlowsMeasured": 123,
"completionLift": 123
}
],
"subflowCompletion": {
"subflowCode": "<string>",
"definitional": true,
"affectedMeasuredCount": 123,
"affectedCompleteCount": 123,
"baselineMeasuredCount": 123,
"baselineCompleteCount": 123,
"affectedCompletionRate": 123,
"baselineCompletionRate": 123,
"completionLift": 123
}
}{
"error": {
"message": "Validation failed",
"details": [
{
"field": "projectID",
"message": "required"
}
]
}
}Analyze the flow impact of error flavours
Compares completion for engaged real-user flows affected by the selected error flavours with
all engaged real-user flows of the same types and date range. The baseline includes affected flows.
Engagement requires a subflow, nested flow or resolved decision, matching the time-series
engagement=engaged filter. Results show correlation, not causation; flows may carry other errors.
Each group includes up to flowLimit flows, newest first (default 5,000; maximum 50,000).
When capped, sampled: true means all reported metrics use that sample. analyzedFlowLimit
reports the applied cap; flowListID identifies the exact analyzed flows.
The baseline completionRate weights rates by the affected group’s osName/browserName mix.
rawCompletionRate reports the unweighted baseline rate.
Outcomes skipped, invisible and visible-auto-skip count as other and are excluded from
completion rates. Occurrences without flows are reported as orphans and excluded from rates.
baseline is absent when no comparable engaged flows exist.
Use naive UTC datetimes (YYYY-MM-DDTHH:mm:ss) for the half-open interval [fromDate, toDate),
with a maximum range of 30 days.
Required API key permission: observe:errorFlavours:read.
curl --request POST \
--url https://api.cloud.corbado.io/v1/observe/errorFlavours/impact \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"flavourIDs": [
"<string>"
],
"fromDate": "2026-08-01T00:00:00",
"toDate": "2026-08-08T00:00:00",
"flowLimit": 5000,
"baselineFlowListID": "<string>",
"matching": {
"dimensions": [],
"ratio": 5,
"coverage": 0.75,
"minCellSize": 500
},
"errorID": "<string>"
}
'import requests
url = "https://api.cloud.corbado.io/v1/observe/errorFlavours/impact"
payload = {
"flavourIDs": ["<string>"],
"fromDate": "2026-08-01T00:00:00",
"toDate": "2026-08-08T00:00:00",
"flowLimit": 5000,
"baselineFlowListID": "<string>",
"matching": {
"dimensions": [],
"ratio": 5,
"coverage": 0.75,
"minCellSize": 500
},
"errorID": "<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({
flavourIDs: ['<string>'],
fromDate: '2026-08-01T00:00:00',
toDate: '2026-08-08T00:00:00',
flowLimit: 5000,
baselineFlowListID: '<string>',
matching: {dimensions: [], ratio: 5, coverage: 0.75, minCellSize: 500},
errorID: '<string>'
})
};
fetch('https://api.cloud.corbado.io/v1/observe/errorFlavours/impact', 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/errorFlavours/impact",
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([
'flavourIDs' => [
'<string>'
],
'fromDate' => '2026-08-01T00:00:00',
'toDate' => '2026-08-08T00:00:00',
'flowLimit' => 5000,
'baselineFlowListID' => '<string>',
'matching' => [
'dimensions' => [
],
'ratio' => 5,
'coverage' => 0.75,
'minCellSize' => 500
],
'errorID' => '<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/errorFlavours/impact"
payload := strings.NewReader("{\n \"flavourIDs\": [\n \"<string>\"\n ],\n \"fromDate\": \"2026-08-01T00:00:00\",\n \"toDate\": \"2026-08-08T00:00:00\",\n \"flowLimit\": 5000,\n \"baselineFlowListID\": \"<string>\",\n \"matching\": {\n \"dimensions\": [],\n \"ratio\": 5,\n \"coverage\": 0.75,\n \"minCellSize\": 500\n },\n \"errorID\": \"<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.cloud.corbado.io/v1/observe/errorFlavours/impact")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"flavourIDs\": [\n \"<string>\"\n ],\n \"fromDate\": \"2026-08-01T00:00:00\",\n \"toDate\": \"2026-08-08T00:00:00\",\n \"flowLimit\": 5000,\n \"baselineFlowListID\": \"<string>\",\n \"matching\": {\n \"dimensions\": [],\n \"ratio\": 5,\n \"coverage\": 0.75,\n \"minCellSize\": 500\n },\n \"errorID\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloud.corbado.io/v1/observe/errorFlavours/impact")
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 \"flavourIDs\": [\n \"<string>\"\n ],\n \"fromDate\": \"2026-08-01T00:00:00\",\n \"toDate\": \"2026-08-08T00:00:00\",\n \"flowLimit\": 5000,\n \"baselineFlowListID\": \"<string>\",\n \"matching\": {\n \"dimensions\": [],\n \"ratio\": 5,\n \"coverage\": 0.75,\n \"minCellSize\": 500\n },\n \"errorID\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"affected": {
"flowCount": 123,
"completeCount": 123,
"incompleteCount": 123,
"otherCount": 123,
"completionRate": 123,
"rawCompletionRate": 123,
"envMix": [
{
"osName": "<string>",
"browserName": "<string>",
"flowCount": 123,
"completedDurationP50Ms": 123,
"completedFlowsMeasured": 123,
"completionRate": 123
}
],
"flowTypes": [
{
"flowType": "<string>",
"flowCount": 123
}
],
"sampled": true,
"completedDurationP25Ms": 123,
"completedDurationP50Ms": 123,
"completedDurationP90Ms": 123,
"completedFlowsMeasured": 123,
"flowListID": "<string>"
},
"occurrenceCount": 123,
"orphanOccurrenceCount": 123,
"baseline": {
"flowCount": 123,
"completeCount": 123,
"incompleteCount": 123,
"otherCount": 123,
"completionRate": 123,
"rawCompletionRate": 123,
"envMix": [
{
"osName": "<string>",
"browserName": "<string>",
"flowCount": 123,
"completedDurationP50Ms": 123,
"completedFlowsMeasured": 123,
"completionRate": 123
}
],
"flowTypes": [
{
"flowType": "<string>",
"flowCount": 123
}
],
"sampled": true,
"completedDurationP25Ms": 123,
"completedDurationP50Ms": 123,
"completedDurationP90Ms": 123,
"completedFlowsMeasured": 123,
"flowListID": "<string>"
},
"completionLift": 123,
"occurrencesPerFlowAvg": 123,
"affectedUserCount": 123,
"repeatUserCount": 123,
"repeatUserOccurrenceCount": 123,
"repeatUserFlowCount": 123,
"repeatUserFlowListID": "<string>",
"userExposure": [
{
"minOccurrences": 123,
"userCount": 123,
"flowCount": 123,
"occurrenceCount": 123,
"maxOccurrences": 123,
"attemptCount": 123,
"completionRate": 123,
"flowListID": "<string>"
}
],
"unattributedFlows": {
"flowCount": 123,
"occurrenceCount": 123,
"attemptCount": 123,
"completionRate": 123,
"flowListID": "<string>"
},
"terminalIncompleteFlowCount": 123,
"analyzedFlowLimit": 123,
"matchingReport": {
"mode": "matched",
"dimensions": [
"<string>"
],
"prefixesUnavailable": true,
"matchRate": 123,
"uncoveredPrefixShare": 123,
"collapsedStrataCount": 123,
"strata": [
{
"affectedFlowCount": 123,
"baselineFlowCount": 123,
"collapseLevel": 123,
"flowType": "<string>",
"pathPrefix": "<string>",
"errorSubflow": "<string>",
"osName": "<string>",
"browserName": "<string>",
"touchpoint": "<string>",
"applicationID": "<string>"
}
],
"balance": [
{
"dimension": "<string>",
"imbalanceBefore": 123,
"imbalanceAfter": 123
}
]
},
"perFlowType": [
{
"flowType": "<string>",
"affectedFlowCount": 123,
"affectedAttemptCount": 123,
"baselineFlowCount": 123,
"baselineAttemptCount": 123,
"affectedCompletionRate": 123,
"affectedCompletedDurationP50Ms": 123,
"affectedCompletedFlowsMeasured": 123,
"baselineCompletionRate": 123,
"baselineCompletedDurationP50Ms": 123,
"baselineCompletedFlowsMeasured": 123,
"completionLift": 123
}
],
"subflowCompletion": {
"subflowCode": "<string>",
"definitional": true,
"affectedMeasuredCount": 123,
"affectedCompleteCount": 123,
"baselineMeasuredCount": 123,
"baselineCompleteCount": 123,
"affectedCompletionRate": 123,
"baselineCompletionRate": 123,
"completionLift": 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.
Body
Flavour IDs to analyze together (format erf-<number>), e.g. an error's member flavours.
1 - 1000 elementsRange start, naive UTC datetime (inclusive).
"2026-08-01T00:00:00"
Range end, naive UTC datetime (exclusive).
"2026-08-08T00:00:00"
Maximum number of flows to analyze PER GROUP (affected and baseline). Both groups are read as raw flow rows, so this is what bounds the analysis; a group that hits the limit is marked sampled and describes the most recent flowLimit flows of that group. Defaults to 5000. High values buy completeness (fewer sampled groups, so per-user tallies see a user's whole history in range) at the cost of a slower analysis.
1 <= x <= 500005000
Optional stored ID list (format idl-<number>, from POST /observe/idLists or a previous analysis) to
use verbatim as the baseline group instead of building one. The listed flows are read as raw rows
(capped at flowLimit, most recent first) and compared against the affected group with the usual
device-mix standardization; matching is ignored when this is set.
Baseline modeling configuration. When present, the baseline is not "all engaged flows of the affected flow types" but a stratified sample matched to the affected group on the requested dimensions — controlling for WHERE in the flow the error happened (pathPrefix) and for the population mix, so the completion comparison isolates the error instead of the route that leads to it. The response's matchingReport describes the strata, the achieved balance, and every fallback taken.
Show child attributes
Show child attributes
The curated error whose impact is being analyzed (format err-<number>). When set, the flavourIDs must
be exactly the error's current member flavours, and the analysis result is stored on the error as its
last-known impact (served as lastImpact in the errors list). Omit for ad-hoc flavour analyses, which
are never stored.
Response
Impact analysis for the given flavours and range.
Show child attributes
Show child attributes
Occurrences of the given flavours on real-user flows in range.
Occurrences in range without an attached flow (inferred / never attached); excluded from all rates.
Show child attributes
Show child attributes
affected.completionRate minus baseline.completionRate (percentage points as a fraction, negative = affected flows complete less). Absent when either side has no completion rate.
Average occurrences per affected flow (occurrenceCount / affected.flowCount). Absent when no flows are affected.
Distinct users among affected flows (flows without a user reference contribute none). Absent when no flows are affected.
Distinct users who hit the analyzed flavours MORE THAN ONCE in range, i.e. at least two occurrences — whether spread over several flows or fired twice within one flow. Subset of affectedUserCount; flows without a user reference contribute none. Absent when no flows are affected. Computed over the analyzed flows, so on a sampled affected group it is a lower bound (a user's earlier flows may fall outside the sample).
Occurrences on the repeat users' flows — how much of occurrenceCount is concentrated on users who keep hitting this.
Affected flows belonging to the repeat users, i.e. the size of the cohort behind repeatUserFlowListID.
Handle of a stored ID list (format idl-<number>) holding the affected flows of the repeat users, for
opening exactly those high-impact users in user search. Empty when no user hit the flavours more than
once.
The distribution behind repeatUserCount: the affected users grouped into occurrence bands (1, 2, 3-4, 5-9, 10+), ascending, empty bands omitted. Every band above the first is made of repeat users, so their user counts sum to repeatUserCount and all bands together to affectedUserCount. Same sampling caveat as repeatUserCount — on a sampled affected group users shift toward the lower bands.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Incomplete affected flows whose last occurrence of the analyzed flavours fell within 10 seconds of the flow's end - the error was (close to) the last thing that happened. Absent when no flows are affected.
The per-group flow cap the analysis ran with (the request's flowLimit, or the default). Together with each group's sampled flag it tells a caller whether raising the limit would change the numbers.
How the baseline group was modeled and how well it mirrors the affected group. Present when the request asked for matching or supplied baselineFlowListID; absent on a plain (unmatched) analysis.
Show child attributes
Show child attributes
The completion comparison split per flow type of the affected group, biggest affected slice first. The group-level completionLift is a weighted mean over these; when the per-type lifts diverge (different sign, or a large spread), the blended number hides differently-hurt flow types and a caller should present this cut instead. Empty when no flows are affected.
1000Show child attributes
Show child attributes
How the ERRORING SUBFLOW itself ended on both sides — did this step succeed, as opposed to completionLift's did the whole flow succeed (possibly via a fallback). The affected side measures the segment the analyzed flavours fired on (falling back to the flow's first segment of the subflow's code when embedding does not locate it); the baseline side the first segment of the same code, so flows that never attempted the subflow are excluded. Flow-type-agnostic by construction: a passkey-login attempt is the same unit in a login and in a signup flow, so this comparison stays clean when the affected group mixes flow types. Absent when the analyzed flavours span several subflow types or none resolves to a known code.
Show child attributes
Show child attributes
Was this page helpful?