Skip to main content
POST
Hold a decision (bearer twin)

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Headers

x-ankra-organisation-id
string

PAT organisation override.

Path Parameters

decision_id
string<uuid>
required

Body

application/json

Optional body of the approve and set-aside routes.

note
string
Maximum string length: 2000

Response

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.

id
string<uuid>
required
area
enum<string>
required

security or cost; decides which permission approving and running it takes.

Available options:
security,
cost
kind
string
required

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.

subject
object
required

Identity of what the proposal is about (finding_id, cluster_id, addon_name, waste_finding_id ...), one document per kind.

summary
string
required
plan
object
required

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}.

evidence
object
required
status
enum<string>
required
Available options:
proposed,
approved,
held,
set_aside,
running,
succeeded,
failed,
superseded
source
string
required

Which surface computed it (default "surface").

created_by
string | null
required

Ankra user id of whoever posted it.

decided_by
string | null
required

Ankra user id of the last approve or set-aside.

decided_at
string<date-time> | null
required
decision_note
string | null
required
operation_id
string<uuid> | null
required

The platform execution a run dispatched, to watch under /api/v1/org/executions.

receipt
DecisionReceipt · object | null
required

The record of running a proposal: who ran it and when, the platform operation it became, the steps taken and how it ended.

dedupe_key
string
required
executable
boolean
required

Whether the platform has an operation for the kind, so a surface offers "run" only where running can work.

expected_monthly_cents
integer | null
required

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.

baseline_monthly_cents
integer | null
required

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.

baseline_window
DecisionTimeWindow · object | null
required

The 24 hours before the change was dispatched, [from, to); to is when the change ran.

measured_monthly_cents
integer | null
required

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.

measured_at
string<date-time> | null
required

When the measurement loop wrote its verdict (measured, unmeasured or reverted).

measurement_status
enum<string>
required

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.

Available options:
not_applicable,
pending,
measured,
unmeasured_coverage_moved,
unmeasured_no_snapshots,
reverted
verify_until
string<date-time> | null
required

When the verification window closes: seven days after the change ran. The measurement loop settles the row once it has passed.

subject_cluster_id
string<uuid> | null
required

The cluster whose cost snapshots measure the change: plan.parameters.cluster_id, else subject.cluster_id.

verification_status
enum<string>
required

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.

Available options:
not_applicable,
verifying,
passed,
failed,
unverified_no_metrics
verification_days
DecisionVerificationDay · object[]
required

The judged verification days in order, empty until the first 24h after the dispatch has been read.

rollback_of
string<uuid> | null
required

On a right_size_rollback: the right-size it undoes, which reads measurement_status reverted once this rollback succeeds.

parent_id
string<uuid> | null
required

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.

created_at
string<date-time>
required
updated_at
string<date-time>
required
run_after
string<date-time> | null
required

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.