curl --request POST \
--url https://api.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"window": "<string>",
"count": 5
}
'import requests
url = "https://api.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover"
payload = {
"window": "<string>",
"count": 5
}
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({window: '<string>', count: 5})
};
fetch('https://api.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover', 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.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover",
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([
'window' => '<string>',
'count' => 5
]),
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.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover"
payload := strings.NewReader("{\n \"window\": \"<string>\",\n \"count\": 5\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.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"window\": \"<string>\",\n \"count\": 5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover")
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 \"window\": \"<string>\",\n \"count\": 5\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"type": "backfill",
"status": "estimating",
"namespace": "<string>",
"spend_usd": 1,
"progress": {
"documents_done": 1
},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"judgment": "<string>",
"estimate": {
"documents": 1,
"tokens": 1,
"judgment_units": 1,
"cost_usd": 1,
"duration_s": 1,
"downstream": [
{
"judgment": "<string>",
"judgments_per_month": 1,
"cost_usd": 1
}
]
},
"estimated_completion_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"attribute": "<string>",
"referenced": {
"relation": "<string>",
"document_id": "<string>",
"revision": 1
},
"resync": {
"thresholds_before": {},
"thresholds_after": {},
"readers": [
"<string>"
]
},
"group": "<string>",
"proposal": {
"options": [
{
"value": "<string>",
"description": "<string>"
}
],
"proposed": [
{
"value": "<string>",
"description": "<string>",
"absorbs": 1,
"sample_ids": [
"<string>"
]
}
],
"sampled": 100,
"escape_documents": 1,
"unlabelled": 1
},
"simulation": {
"population": 1,
"sampled": 1,
"thresholds": {},
"examples": [
"<string>"
],
"excluded": {
"failed": 1,
"out_of_scope": 1
},
"fanout": {
"documents": 1,
"tokens": 1,
"judgment_units": 1,
"cost_usd": 1,
"duration_s": 1,
"downstream": [
{
"judgment": "<string>",
"judgments_per_month": 1,
"cost_usd": 1
}
]
},
"larger_sample": 123
},
"version": 2,
"report": {
"documents": 1,
"current": {
"type": "bool",
"mean": 123,
"histogram": [
{
"lower": 123,
"upper": 123,
"count": 1
}
]
},
"candidate": {
"type": "bool",
"mean": 123,
"histogram": [
{
"lower": 123,
"upper": 123,
"count": 1
}
]
},
"threshold_flips": {},
"recompute": {
"documents": 1,
"tokens": 1,
"judgment_units": 1,
"cost_usd": 1,
"duration_s": 1,
"downstream": [
{
"judgment": "<string>",
"judgments_per_month": 1,
"cost_usd": 1
}
]
},
"downstream": [
{
"judgment": "<string>",
"judgments_per_month": 1,
"cost_usd": 1
}
]
},
"export": {
"since": "2023-11-07T05:31:56Z",
"until": "2023-11-07T05:31:56Z",
"judgments": [
"<string>"
],
"evaluations": 1,
"files": [
{
"url": "<string>",
"url_expires_at": "2023-11-07T05:31:56Z",
"evaluations": 2,
"bytes": 2
}
],
"expires_at": "2023-11-07T05:31:56Z",
"links_unavailable": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}Propose options for what the escape option holds
Relations (§6.5.4). For a fixed-option choice only: a discover
job samples up to 200 documents in window whose answer is
none_of_the_above (or whose escape_p is at or above the
judgment’s escape threshold), cut to 100,000 tokens together, asks
a general-purpose model for up to count new options, and runs the
proposed version in shadow over the sample. Its proposal is the
current options plus the proposed ones, with how many escape
documents each would absorb and how many stay unlabelled. It never
creates a version: edit the options, create the version, and
activate it through its shadow report.
- Opt-in.
forbiddenuntil an org admin enablessuggestions, because the sample goes to an LLM provider, a disclosed subprocessor, as forsuggest_parts. - Limits. Free, and counted against
suggest_parts’ daily limits (rate_limited). - A
bool, ascoreor anoptions.fromjudgment isinvalid_request: none of them has a fixed escape to propose from.
curl --request POST \
--url https://api.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"window": "<string>",
"count": 5
}
'import requests
url = "https://api.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover"
payload = {
"window": "<string>",
"count": 5
}
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({window: '<string>', count: 5})
};
fetch('https://api.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover', 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.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover",
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([
'window' => '<string>',
'count' => 5
]),
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.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover"
payload := strings.NewReader("{\n \"window\": \"<string>\",\n \"count\": 5\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.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"window\": \"<string>\",\n \"count\": 5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vainona.ai/v1/namespaces/{ns}/judgments/{name}/discover")
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 \"window\": \"<string>\",\n \"count\": 5\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"type": "backfill",
"status": "estimating",
"namespace": "<string>",
"spend_usd": 1,
"progress": {
"documents_done": 1
},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"judgment": "<string>",
"estimate": {
"documents": 1,
"tokens": 1,
"judgment_units": 1,
"cost_usd": 1,
"duration_s": 1,
"downstream": [
{
"judgment": "<string>",
"judgments_per_month": 1,
"cost_usd": 1
}
]
},
"estimated_completion_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"attribute": "<string>",
"referenced": {
"relation": "<string>",
"document_id": "<string>",
"revision": 1
},
"resync": {
"thresholds_before": {},
"thresholds_after": {},
"readers": [
"<string>"
]
},
"group": "<string>",
"proposal": {
"options": [
{
"value": "<string>",
"description": "<string>"
}
],
"proposed": [
{
"value": "<string>",
"description": "<string>",
"absorbs": 1,
"sample_ids": [
"<string>"
]
}
],
"sampled": 100,
"escape_documents": 1,
"unlabelled": 1
},
"simulation": {
"population": 1,
"sampled": 1,
"thresholds": {},
"examples": [
"<string>"
],
"excluded": {
"failed": 1,
"out_of_scope": 1
},
"fanout": {
"documents": 1,
"tokens": 1,
"judgment_units": 1,
"cost_usd": 1,
"duration_s": 1,
"downstream": [
{
"judgment": "<string>",
"judgments_per_month": 1,
"cost_usd": 1
}
]
},
"larger_sample": 123
},
"version": 2,
"report": {
"documents": 1,
"current": {
"type": "bool",
"mean": 123,
"histogram": [
{
"lower": 123,
"upper": 123,
"count": 1
}
]
},
"candidate": {
"type": "bool",
"mean": 123,
"histogram": [
{
"lower": 123,
"upper": 123,
"count": 1
}
]
},
"threshold_flips": {},
"recompute": {
"documents": 1,
"tokens": 1,
"judgment_units": 1,
"cost_usd": 1,
"duration_s": 1,
"downstream": [
{
"judgment": "<string>",
"judgments_per_month": 1,
"cost_usd": 1
}
]
},
"downstream": [
{
"judgment": "<string>",
"judgments_per_month": 1,
"cost_usd": 1
}
]
},
"export": {
"since": "2023-11-07T05:31:56Z",
"until": "2023-11-07T05:31:56Z",
"judgments": [
"<string>"
],
"evaluations": 1,
"files": [
{
"url": "<string>",
"url_expires_at": "2023-11-07T05:31:56Z",
"evaluations": 2,
"bytes": 2
}
],
"expires_at": "2023-11-07T05:31:56Z",
"links_unavailable": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {
"suggested_context": {
"recipe": {
"fields": [
"<string>"
],
"last_n": {},
"window": {},
"max_tokens": 2,
"related": {},
"group": {},
"previous": {
"fields": [
"<string>"
],
"anchor": "<string>"
}
},
"cost_per_answer": 1,
"whole_state_cost_per_answer": 1,
"sampled_documents": 2,
"excluded": [
{
"path": "<string>",
"reason": "id"
}
]
}
}
}
}Authorizations
An organization API key. Keys carry a role (read_write or
read_only) and may be restricted to a namespace prefix such as
acme/*, or to one namespace such as acme/prod/tenant_1. A prefix
matches on a / boundary: acme/prod/tenant_1* covers
acme/prod/tenant_1 and everything under acme/prod/tenant_1/,
never acme/prod/tenant_12.
Headers
Returns the original response verbatim while the node still caches it. Correctness never depends on it.
1Path Parameters
The namespace name, with any / sent as %2F.
Up to 256 bytes. / separates levels of the hierarchy, as in acme/prod/tenant_123.
1 - 256^[A-Za-z0-9._:/-]+$A judgment, attribute or threshold name. Names are path segments in field references, so they never contain ..
1 - 128^[A-Za-z0-9_-]+$Body
Response
The discover job. Its proposal fills in when it is done.
A job row (§7.10.5). A shadow job comes from activating a differing
version without force (§6.9). It starts in awaiting_confirm and
runs its sample while it waits; report fills in when the sample is
done. confirm activates version and the job ends done; cancel
leaves the active version unchanged. On a template prefix, namespace
is the prefix. A reference_index job (entities, E1) builds the index
an entity judgment's relations need (§6.5.2); it starts running, and
attribute names the attribute it indexes. An evaluation_export
job (§9 Plans) starts running, counts evaluations written in
progress.documents_done, never spends, and has export.
From relations: a resync job re-renders the readers of a changed
threshold (resync) and touches the parents whose rendering
flipped; a group_build job computes a new group's or aggregate's
first aggregates with no fan-out (group); a discover job fills
in proposal (§6.5.4); a simulation job fills in simulation
(§6.5.2). Each starts running; discover and simulation never
spend. E3a's fanout jobs are retired: none is created, and a
server may still return an old one until it stops.
backfill, shadow, periodic, namespace_delete, reference_index, fanout, evaluation_export, resync, group_build, discover, simulation estimating, awaiting_confirm, running, paused, done, failed, cancelled A namespace name, or a template prefix: a namespace path ending in
/*, such as acme/prod/*, which every namespace under acme/prod/
inherits judgments from (§7.7). Up to 256 bytes.
1 - 256^[A-Za-z0-9._:/-]+(/\*)?$Judging billed by this job so far, in US dollars.
x >= 0Show child attributes
Show child attributes
RFC 3339, UTC.
RFC 3339, UTC.
A judgment, attribute or threshold name. Names are path segments in field references, so they never contain ..
1 - 128^[A-Za-z0-9_-]+$Show child attributes
Show child attributes
RFC 3339, UTC.
Entities, E1 (§6.5.2). reference_index jobs only, as attributes.<name>. The attribute whose reference index the job builds. Null for other jobs.
^attributes\.[A-Za-z0-9_-]+$Retired with E3a's fanout jobs; null.
Show child attributes
Show child attributes
Relations. resync jobs only.
Show child attributes
Show child attributes
Relations. group_build jobs only, the group whose aggregates it computes.
1 - 128^[A-Za-z0-9_-]+$Relations. discover jobs only; null until done.
Show child attributes
Show child attributes
Relations. simulation jobs only; null until done.
Show child attributes
Show child attributes
Shadow jobs only. The version being activated.
x >= 1Shadow jobs only. Null while the sample runs; progress counts the
sampled documents. A composite version's job has a
CompositeShadowReport (§6.5.1), and when it has too few labels it
fails with an error that starts with insufficient_labels.
- Option 1
- Option 2
Show child attributes
Show child attributes
evaluation_export jobs only (§9 Plans): the range, the evaluations written, and once done the download links.
Show child attributes
Show child attributes