curl --request POST \
--url https://app.octavehq.com/api/v2/resource/check-drift \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data @- <<EOF
{
"resourceOId": "rs_1234567890",
"propose": false,
"guidance": "Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it."
}
EOFimport requests
url = "https://app.octavehq.com/api/v2/resource/check-drift"
payload = {
"resourceOId": "rs_1234567890",
"propose": False,
"guidance": "Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it."
}
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
resourceOId: 'rs_1234567890',
propose: false,
guidance: 'Flag any oversell percentage that differs from the library\'s proof point, even when the doc hedges it.'
})
};
fetch('https://app.octavehq.com/api/v2/resource/check-drift', 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://app.octavehq.com/api/v2/resource/check-drift",
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([
'resourceOId' => 'rs_1234567890',
'propose' => false,
'guidance' => 'Flag any oversell percentage that differs from the library\'s proof point, even when the doc hedges it.'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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://app.octavehq.com/api/v2/resource/check-drift"
payload := strings.NewReader("{\n \"resourceOId\": \"rs_1234567890\",\n \"propose\": false,\n \"guidance\": \"Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("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://app.octavehq.com/api/v2/resource/check-drift")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"resourceOId\": \"rs_1234567890\",\n \"propose\": false,\n \"guidance\": \"Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.octavehq.com/api/v2/resource/check-drift")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"resourceOId\": \"rs_1234567890\",\n \"propose\": false,\n \"guidance\": \"Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it.\"\n}"
response = http.request(request)
puts response.read_body{
"_metadata": {
"requestId": "requestId",
"timestamp": "2021-01-01T00:00:00.000Z",
"usage": 0,
"message": "message"
},
"material": true,
"skippedReason": "<string>",
"assessments": [
{
"entityType": "Product",
"entityOId": "<string>",
"entityName": "<string>",
"classification": "contradicts",
"warrantsDocUpdate": true,
"rationale": "<string>",
"changeKinds": [
"positioning_change"
],
"direction": "entity_moved"
}
],
"proposal": {
"summary": "<string>",
"insight": "<string>",
"recommendedAction": "<string>",
"proposedUpstreamEdit": "<string>",
"confidence": 123
},
"editHunks": [
{
"anchor": "<string>",
"replacement": "<string>",
"kind": "replace"
}
],
"suggestionOId": "<string>",
"checkedAt": "<string>",
"tokensUsed": 123
}{
"_metadata": {
"requestId": "requestId",
"timestamp": "2021-01-01T00:00:00.000Z",
"usage": 0,
"message": "message"
},
"message": "<string>"
}Check Resource Drift
Check whether a source doc (Google Doc, Notion page, Linear doc, watched URL) has drifted from the library entities linked to it. Returns a per-entity verdict (contradicts / invalidates / strengthens / validates / immaterial, with change kinds and which side moved) and, when material, a consolidated doc-update proposal. Set propose: true to persist that proposal as a real suggestion for human review — then /suggestion/accept posts the attributed comment upstream. The doc must have linked entities (see /resource/link-entities).
curl --request POST \
--url https://app.octavehq.com/api/v2/resource/check-drift \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data @- <<EOF
{
"resourceOId": "rs_1234567890",
"propose": false,
"guidance": "Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it."
}
EOFimport requests
url = "https://app.octavehq.com/api/v2/resource/check-drift"
payload = {
"resourceOId": "rs_1234567890",
"propose": False,
"guidance": "Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it."
}
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
resourceOId: 'rs_1234567890',
propose: false,
guidance: 'Flag any oversell percentage that differs from the library\'s proof point, even when the doc hedges it.'
})
};
fetch('https://app.octavehq.com/api/v2/resource/check-drift', 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://app.octavehq.com/api/v2/resource/check-drift",
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([
'resourceOId' => 'rs_1234567890',
'propose' => false,
'guidance' => 'Flag any oversell percentage that differs from the library\'s proof point, even when the doc hedges it.'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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://app.octavehq.com/api/v2/resource/check-drift"
payload := strings.NewReader("{\n \"resourceOId\": \"rs_1234567890\",\n \"propose\": false,\n \"guidance\": \"Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("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://app.octavehq.com/api/v2/resource/check-drift")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"resourceOId\": \"rs_1234567890\",\n \"propose\": false,\n \"guidance\": \"Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.octavehq.com/api/v2/resource/check-drift")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"resourceOId\": \"rs_1234567890\",\n \"propose\": false,\n \"guidance\": \"Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it.\"\n}"
response = http.request(request)
puts response.read_body{
"_metadata": {
"requestId": "requestId",
"timestamp": "2021-01-01T00:00:00.000Z",
"usage": 0,
"message": "message"
},
"material": true,
"skippedReason": "<string>",
"assessments": [
{
"entityType": "Product",
"entityOId": "<string>",
"entityName": "<string>",
"classification": "contradicts",
"warrantsDocUpdate": true,
"rationale": "<string>",
"changeKinds": [
"positioning_change"
],
"direction": "entity_moved"
}
],
"proposal": {
"summary": "<string>",
"insight": "<string>",
"recommendedAction": "<string>",
"proposedUpstreamEdit": "<string>",
"confidence": 123
},
"editHunks": [
{
"anchor": "<string>",
"replacement": "<string>",
"kind": "replace"
}
],
"suggestionOId": "<string>",
"checkedAt": "<string>",
"tokensUsed": 123
}{
"_metadata": {
"requestId": "requestId",
"timestamp": "2021-01-01T00:00:00.000Z",
"usage": 0,
"message": "message"
},
"message": "<string>"
}Authorizations
Body
Resource to check plus the propose flag
The resource (doc) oId to check. Get this from /resource/list or /resource/search.
1"rs_1234567890"
When true and the check finds material drift, persist the proposal as a real suggestion on the review rails (visible in the suggestions inbox and via /suggestion/list, /suggestion/accept). When false (default), the check is a pure diagnostic — nothing is created.
What this check should watch for or know, on top of the workspace's standing drift-check guidance: a claim to scrutinise, a recent change the doc must reflect, or context the library does not carry.
2000"Flag any oversell percentage that differs from the library's proof point, even when the doc hedges it."
Response
The drift check verdicts and optional proposal
Show child attributes
Show child attributes
True when the doc warrants an update from the library's state
Why the check was skipped (doc unreadable, no linked entities, unchanged since last check) — null when it ran
Per-linked-entity phase-1 verdicts
Show child attributes
Show child attributes
The consolidated doc-update proposal when material
Show child attributes
Show child attributes
Anchor-validated before/after edits for the doc: every anchor was located verbatim in the live document (unmatched ones are dropped), so they can be applied as-is. Null when the model returned none — a change amounting to a full rewrite has a proposal but no hunks.
Show child attributes
Show child attributes
The persisted suggestion's oId when propose: true created one — pass it to /suggestion/get or /suggestion/accept