import requests
url = "https://platform.ankra.app/api/v1/org/decisions/{decision_id}/hold"
payload = { "note": "<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({note: '<string>'})
};
fetch('https://platform.ankra.app/api/v1/org/decisions/{decision_id}/hold', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));curl --request POST \
--url https://platform.ankra.app/api/v1/org/decisions/{decision_id}/hold \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"note": "<string>"
}
'{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"area": "security",
"kind": "<string>",
"subject": {},
"summary": "<string>",
"plan": {},
"evidence": {},
"status": "proposed",
"source": "<string>",
"created_by": "<string>",
"decided_by": "<string>",
"decided_at": "2023-11-07T05:31:56Z",
"decision_note": "<string>",
"operation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"receipt": {
"steps": [
{
"name": "<string>",
"outcome": "dispatched",
"detail": "<string>",
"evidence": {}
}
],
"claimed_at": "2023-11-07T05:31:56Z",
"executed_by": "<string>",
"dispatched_at": "2023-11-07T05:31:56Z",
"operation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"completed_at": "2023-11-07T05:31:56Z",
"execution_status": "<string>"
},
"dedupe_key": "<string>",
"executable": true,
"expected_monthly_cents": 123,
"baseline_monthly_cents": 123,
"baseline_window": {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z"
},
"measured_monthly_cents": 123,
"measured_at": "2023-11-07T05:31:56Z",
"measurement_status": "not_applicable",
"verify_until": "2023-11-07T05:31:56Z",
"subject_cluster_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"verification_status": "not_applicable",
"verification_days": [
{
"day": 123,
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z",
"state": "clear",
"cpu_p95_share": 123,
"memory_p95_share": 123,
"nodes": 123,
"reporting": 123,
"hottest_node": "<string>",
"reason": "<string>"
}
],
"rollback_of": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"parent_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"run_after": "2023-11-07T05:31:56Z"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "Cluster not found"
}Hold a decision (bearer twin)
Holds an approved proposal before it ran, with the caller’s reason: a held proposal is run by nothing - neither the cost autopilot nor execute - until it is released or set aside. Allowed from approved. The cost autopilot’s pre-notice links here (ankra-cozgu.2.2.1). Gated on the area’s permission: billing.manage for cost, security.manage for security. The token stands in for the browser route’s CSRF double-submit. Bearer-PAT twin of the browser route of the same name under /org; the console’s session cookie is not accepted here and the browser route answers a token with a login redirect.
import requests
url = "https://platform.ankra.app/api/v1/org/decisions/{decision_id}/hold"
payload = { "note": "<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({note: '<string>'})
};
fetch('https://platform.ankra.app/api/v1/org/decisions/{decision_id}/hold', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));curl --request POST \
--url https://platform.ankra.app/api/v1/org/decisions/{decision_id}/hold \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"note": "<string>"
}
'{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"area": "security",
"kind": "<string>",
"subject": {},
"summary": "<string>",
"plan": {},
"evidence": {},
"status": "proposed",
"source": "<string>",
"created_by": "<string>",
"decided_by": "<string>",
"decided_at": "2023-11-07T05:31:56Z",
"decision_note": "<string>",
"operation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"receipt": {
"steps": [
{
"name": "<string>",
"outcome": "dispatched",
"detail": "<string>",
"evidence": {}
}
],
"claimed_at": "2023-11-07T05:31:56Z",
"executed_by": "<string>",
"dispatched_at": "2023-11-07T05:31:56Z",
"operation_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"completed_at": "2023-11-07T05:31:56Z",
"execution_status": "<string>"
},
"dedupe_key": "<string>",
"executable": true,
"expected_monthly_cents": 123,
"baseline_monthly_cents": 123,
"baseline_window": {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z"
},
"measured_monthly_cents": 123,
"measured_at": "2023-11-07T05:31:56Z",
"measurement_status": "not_applicable",
"verify_until": "2023-11-07T05:31:56Z",
"subject_cluster_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"verification_status": "not_applicable",
"verification_days": [
{
"day": 123,
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z",
"state": "clear",
"cpu_p95_share": 123,
"memory_p95_share": 123,
"nodes": 123,
"reporting": 123,
"hottest_node": "<string>",
"reason": "<string>"
}
],
"rollback_of": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"parent_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"run_after": "2023-11-07T05:31:56Z"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": "Cluster not found"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "Cluster not found"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
PAT organisation override.
Path Parameters
Body
Optional body of the approve and set-aside routes.
2000Response
Successful response
One proposal of the decision ledger: what it is about, what the surface computed, where it stands, who decided, and what running it did.
security or cost; decides which permission approving and running it takes.
security, cost What the proposal does, e.g. addon_upgrade, image_rebuild, right_size, off_hours_schedule, waste_cleanup. Only kinds with a platform operation are executable.
Identity of what the proposal is about (finding_id, cluster_id, addon_name, waste_finding_id ...), one document per kind.
The steps the surface computed. plan.parameters is the machine half the executable kinds are called with: addon_upgrade takes {cluster_id, addon_name, chart_version}; off_hours_schedule takes {cluster_id, timezone, schedules: [{action, stop_mode, cron_expression}]}; waste_cleanup takes {waste_finding_id}.
proposed, approved, held, set_aside, running, succeeded, failed, superseded Which surface computed it (default "surface").
Ankra user id of whoever posted it.
Ankra user id of the last approve or set-aside.
The platform execution a run dispatched, to watch under /api/v1/org/executions.
The record of running a proposal: who ran it and when, the platform operation it became, the steps taken and how it ended.
Show child attributes
Show child attributes
Whether the platform has an operation for the kind, so a surface offers "run" only where running can work.
What the surface expected a cost proposal to save per month, in USD cents, recorded when it succeeded: plan.parameters.expected_monthly_cents, else evidence.expected_monthly_cents, each with an optional sibling expected_currency (ISO code, default usd) converted to USD. Null when the proposal declared none, has not run, or is not a cost proposal; never zero for an unknown.
The subject cluster's run rate before the change: the mean monthly_cost_estimate_cents of its cost snapshots over baseline_window, in USD cents. Null until a measurement opens, or when no snapshot covered the window.
The 24 hours before the change was dispatched, [from, to); to is when the change ran.
Show child attributes
Show child attributes
What the change measurably saved per month, in USD cents: baseline_monthly_cents minus the cluster's 24h mean run rate seven days after the change. Negative when the run rate rose. Null unless measurement_status is measured.
When the measurement loop wrote its verdict (measured, unmeasured or reverted).
Where the measured outcome stands: not_applicable (not a cost proposal, not run, or no cluster to measure), pending (inside the seven-day verification window), measured, unmeasured_coverage_moved (the cluster was not priced the same way on both sides), unmeasured_no_snapshots (nothing to read on one side, or the cluster is no longer priced), reverted (the change was undone inside the window). The activity feed's measured / unmeasured / reverted event carries the reason.
not_applicable, pending, measured, unmeasured_coverage_moved, unmeasured_no_snapshots, reverted When the verification window closes: seven days after the change ran. The measurement loop settles the row once it has passed.
The cluster whose cost snapshots measure the change: plan.parameters.cluster_id, else subject.cluster_id.
Where a right-size's seven-day verification stands (ankra-cozgu.1.2): verifying until every day is judged, passed when all seven were clear, failed on the first day any node of the group ran p95 CPU over 60% or p95 memory over 70% of capacity (a right_size_rollback proposal is filed), unverified_no_metrics when no day tripped but at least one could not be read. not_applicable for every other proposal.
not_applicable, verifying, passed, failed, unverified_no_metrics The judged verification days in order, empty until the first 24h after the dispatch has been read.
Show child attributes
Show child attributes
On a right_size_rollback: the right-size it undoes, which reads measurement_status reverted once this rollback succeeds.
On a wave of a right-size ladder (a right_size proposal with source ladder): the right_size_ladder proposal it belongs to. Null for every other proposal.
The earliest time the cost autopilot may run a proposal it approved itself - the end of its pre-notice window, in which a person may hold it; null for a proposal a person approved, which a person runs.