# Commitment Plans (Beta)

Agent-friendly commitment plan endpoints

## List commitment plans

> Returns commitment plans scoped to one segment for the given provider. \`segment\_id\` defaults to the provider-resources segment — same fallback as POST/PUT — so the typical caller sees the plans tied to their default segment without cross-segment duplicates. Further filters (template, status, flags) narrow within that scope. Coverage metrics (current\_coverage / projected\_coverage) are omitted here for speed; fetch the detail endpoint for those.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans":{"get":{"parameters":[{"in":"query","name":"provider","description":"Cloud provider (aws, azure, gcp)","schema":{"type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"required":true},{"in":"query","name":"segment_id","description":"Optional segment ID to scope results. Defaults to the provider resources segment if not specified.","schema":{"type":"string","format":"uuid","default":null,"nullable":true},"required":false},{"in":"query","name":"template_id","description":"Filter to plans generated from this template (GET /commitment-plan-templates)","schema":{"type":"string","format":"uuid","default":null,"nullable":true},"required":false},{"in":"query","name":"status","description":"Filter by plan status (e.g. 'draft', 'in_progress')","schema":{"default":null,"type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress",null],"nullable":true},"required":false},{"in":"query","name":"is_recommended","description":"Filter to the flagged recommended plan","schema":{"type":"boolean","default":null,"nullable":true},"required":false},{"in":"query","name":"is_system_generated","description":"Filter to system-generated (default) plans — the three built-ins (Recommended / Balanced / High Savings) vs. user-created plans.","schema":{"type":"boolean","default":null,"nullable":true},"required":false},{"in":"query","name":"is_renewal","description":"Switch which flavor the list returns. Omitted (default) and false both return segment-scoped non-renewal plans — backward-compatible with the pre-renewal contract. Set to true to fetch renewal plans (which aren't segment-scoped — `segment_id` is ignored). There's no combined view; renewals and non-renewals are queried separately.","schema":{"type":"boolean","default":null,"nullable":true},"required":false}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommitmentPlanList"}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"List commitment plans","description":"Returns commitment plans scoped to one segment for the given provider. `segment_id` defaults to the provider-resources segment — same fallback as POST/PUT — so the typical caller sees the plans tied to their default segment without cross-segment duplicates. Further filters (template, status, flags) narrow within that scope. Coverage metrics (current_coverage / projected_coverage) are omitted here for speed; fetch the detail endpoint for those."}}},"components":{"schemas":{"CommitmentPlanList":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]}},"required":["created_at","id","is_calculating","is_renewal","max_term","minimum_commitment","name","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Create a commitment plan

> Creates a new commitment plan for the given segment. The plan is generated asynchronously; the response echoes the initial plan with is\_calculating=true and omits coverage fields (meaningless mid-recalc). Poll GET /commitment-plans/{plan\_id} once is\_calculating=false to get the full detail including coverage and per-service breakdowns.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans":{"post":{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitmentPlanList"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommitmentPlanArgs"}}}},"tags":["Commitment Plans (Beta)"],"summary":"Create a commitment plan","description":"Creates a new commitment plan for the given segment. The plan is generated asynchronously; the response echoes the initial plan with is_calculating=true and omits coverage fields (meaningless mid-recalc). Poll GET /commitment-plans/{plan_id} once is_calculating=false to get the full detail including coverage and per-service breakdowns."}}},"components":{"schemas":{"CommitmentPlanList":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]}},"required":["created_at","id","is_calculating","is_renewal","max_term","minimum_commitment","name","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false},"CreateCommitmentPlanArgs":{"type":"object","properties":{"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"segment_id":{"type":"string","format":"uuid","default":null,"description":"Optional segment ID to scope results. Defaults to the provider resources segment if not specified.","nullable":true},"name":{"type":"string","description":"Human-readable plan name"},"configuration":{"description":"Inputs that drive plan generation","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]}},"required":["configuration","name","provider"],"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Create a renewal commitment plan

> Creates a new commitment plan that renews a set of expiring commitments. The plan covers the same resources the source commitments were covering, with the contract specs supplied in \`configuration\` driving the renewal recommendation. The plan is generated asynchronously — the response echoes the initial plan with \`is\_calculating=true\`; poll GET /commitment-plans/{plan\_id} until that flips to see the generated line items.\
> \
> Renewal plans always sit on the provider-resources segment; \`segment\_id\` is not accepted. The usage window the recommender feeds on is derived automatically from the source commitments' end dates, so \`configuration.lookback\_days\` is omitted (the field is rejected if sent). \`configuration.resource\_ids\` is also rejected — \`configuration.renewal\_commitment\_ids\` carries the scope for a renewal plan, parallel to how \`configuration.resource\_ids\` scopes an infrastructure plan on the regular create endpoint.\
> \
> Each generated line item carries a \`renewal\_commitment\_id\` linking it back to the source commitment it is proposed to replace. Pair with GET /commitment-plans/{plan\_id}/renewal-commitments to see the source commitments side-by-side.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/renewals":{"post":{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitmentPlanList"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRenewalCommitmentPlanArgs"}}}},"tags":["Commitment Plans (Beta)"],"summary":"Create a renewal commitment plan","description":"Creates a new commitment plan that renews a set of expiring commitments. The plan covers the same resources the source commitments were covering, with the contract specs supplied in `configuration` driving the renewal recommendation. The plan is generated asynchronously — the response echoes the initial plan with `is_calculating=true`; poll GET /commitment-plans/{plan_id} until that flips to see the generated line items.\n\nRenewal plans always sit on the provider-resources segment; `segment_id` is not accepted. The usage window the recommender feeds on is derived automatically from the source commitments' end dates, so `configuration.lookback_days` is omitted (the field is rejected if sent). `configuration.resource_ids` is also rejected — `configuration.renewal_commitment_ids` carries the scope for a renewal plan, parallel to how `configuration.resource_ids` scopes an infrastructure plan on the regular create endpoint.\n\nEach generated line item carries a `renewal_commitment_id` linking it back to the source commitment it is proposed to replace. Pair with GET /commitment-plans/{plan_id}/renewal-commitments to see the source commitments side-by-side."}}},"components":{"schemas":{"CommitmentPlanList":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]}},"required":["created_at","id","is_calculating","is_renewal","max_term","minimum_commitment","name","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false},"CreateRenewalCommitmentPlanArgs":{"type":"object","properties":{"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Human-readable plan name"},"configuration":{"description":"Inputs that drive plan generation, including the source `renewal_commitment_ids`. Renewal config omits `lookback_days` (derived from source commitments' end dates) and `resource_ids` (replaced by `renewal_commitment_ids` inside this same object).","allOf":[{"$ref":"#/components/schemas/RenewalCommitmentPlanConfiguration"}]}},"required":["configuration","name","provider"],"additionalProperties":false},"RenewalCommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating renewal line items. Each spec is a (commitment_type, contract_term, payment_option) triple — the recommender picks the best mix matching these specs against the expiring commitments' usage.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"renewal_commitment_ids":{"type":"array","minItems":1,"description":"Expiring commitment ids to renew. Required and non-empty. All ids must belong to the caller's org and the supplied provider, and each must have a non-null end_date (used to derive the usage-window for the renewal recommendation).","items":{"type":"string","format":"uuid"}}},"required":["contract_specs","renewal_commitment_ids"],"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Get default commitment plans

> Returns the three default Archera commitment plans: Recommended (30-day), Balanced (1-year), and High Savings (3-year).

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/default":{"get":{"parameters":[{"in":"query","name":"provider","description":"Cloud provider (aws, azure, gcp)","schema":{"type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"required":true},{"in":"query","name":"segment_id","description":"Optional segment ID to scope results. Defaults to the provider resources segment if not specified.","schema":{"type":"string","format":"uuid","default":null,"nullable":true},"required":false}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommitmentPlan"}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"Get default commitment plans","description":"Returns the three default Archera commitment plans: Recommended (30-day), Balanced (1-year), and High Savings (3-year)."}}},"components":{"schemas":{"CommitmentPlan":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]},"current_coverage":{"type":"number","description":"Commitment coverage of reservable spend today, from existing commitments (0-1) — the BEFORE picture, pre-plan."},"projected_coverage":{"type":"number","description":"Commitment coverage of reservable spend if this plan is applied (0-1) — the AFTER picture, post-plan."}},"required":["created_at","current_coverage","id","is_calculating","is_renewal","max_term","minimum_commitment","name","projected_coverage","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Get recommended commitment plan

> Returns the single recommended commitment plan for the organization. This is typically the 30-day Recommended plan. Returns 204 if no plan is available.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/recommended":{"get":{"parameters":[{"in":"query","name":"provider","description":"Cloud provider (aws, azure, gcp)","schema":{"type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"required":true},{"in":"query","name":"segment_id","description":"Optional segment ID to scope results. Defaults to the provider resources segment if not specified.","schema":{"type":"string","format":"uuid","default":null,"nullable":true},"required":false}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitmentPlan"}}}},"204":{"description":"No Content"},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"Get recommended commitment plan","description":"Returns the single recommended commitment plan for the organization. This is typically the 30-day Recommended plan. Returns 204 if no plan is available."}}},"components":{"schemas":{"CommitmentPlan":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]},"current_coverage":{"type":"number","description":"Commitment coverage of reservable spend today, from existing commitments (0-1) — the BEFORE picture, pre-plan."},"projected_coverage":{"type":"number","description":"Commitment coverage of reservable spend if this plan is applied (0-1) — the AFTER picture, post-plan."}},"required":["created_at","current_coverage","id","is_calculating","is_renewal","max_term","minimum_commitment","name","projected_coverage","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Get commitment plan details

> Returns details for a specific commitment plan by ID, including per-service breakdowns.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}":{"get":{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitmentPlanDetail"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not Found"},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"Get commitment plan details","description":"Returns details for a specific commitment plan by ID, including per-service breakdowns."}}},"components":{"schemas":{"CommitmentPlanDetail":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]},"current_coverage":{"type":"number","description":"Commitment coverage of reservable spend today, from existing commitments (0-1) — the BEFORE picture, pre-plan."},"projected_coverage":{"type":"number","description":"Commitment coverage of reservable spend if this plan is applied (0-1) — the AFTER picture, post-plan."},"covered_services":{"type":"array","description":"List of cloud services covered by this plan, with per-service savings and commitment breakdowns","items":{"$ref":"#/components/schemas/CoveredService"}}},"required":["created_at","current_coverage","id","is_calculating","is_renewal","max_term","minimum_commitment","name","projected_coverage","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"CoveredService":{"type":"object","properties":{"service_name":{"type":"string","description":"Cloud service name (e.g. 'Amazon EC2', 'Amazon RDS')"},"num_commitments":{"type":"integer","description":"Number of individual commitments covering this service"},"current_coverage":{"type":"number","description":"Commitment coverage of this service's reservable spend today, from existing commitments (0-1) — the BEFORE picture, pre-plan."},"projected_coverage":{"type":"number","description":"Commitment coverage of this service's reservable spend if this plan is applied (0-1) — the AFTER picture, post-plan."},"commitment_financials_monthly_rate":{"description":"730-hour monthly-rate financials for this service. cloud_provider_cost is `{total}` only (no recurring/amortized split at per-service level). commitment_savings has no rebate field on plans.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]}},"required":["current_coverage","num_commitments","projected_coverage","service_name"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Update a commitment plan

> Update the plan's name and/or configuration. Replacing \`configuration\` triggers a recalculation — the response will have is\_calculating=true and line-item financials are invalid until generation completes. Rejected if the plan is currently calculating, is a system-generated default, or is locked for purchase.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}":{"put":{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitmentPlanList"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not Found"},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommitmentPlanArgs"}}}},"tags":["Commitment Plans (Beta)"],"summary":"Update a commitment plan","description":"Update the plan's name and/or configuration. Replacing `configuration` triggers a recalculation — the response will have is_calculating=true and line-item financials are invalid until generation completes. Rejected if the plan is currently calculating, is a system-generated default, or is locked for purchase."}}},"components":{"schemas":{"CommitmentPlanList":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]}},"required":["created_at","id","is_calculating","is_renewal","max_term","minimum_commitment","name","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false},"UpdateCommitmentPlanArgs":{"type":"object","properties":{"name":{"type":"string","description":"New plan name"},"configuration":{"description":"New plan configuration. Replacing this triggers a full regeneration of the plan's line items and financials. The plan's scope axis lives here too — `resource_ids` for infrastructure scope, `renewal_commitment_ids` for renewal scope (mutually exclusive). Sending the wrong scope field for the plan type is rejected; convert plan types by deleting and re-creating.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]}},"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Delete a commitment plan

> Delete a commitment plan. Rejected if the plan is currently calculating, is a system-generated default, or is locked for purchase. Irreversible.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}":{"delete":{"responses":{"204":{"description":"No Content"},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not Found"},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"Delete a commitment plan","description":"Delete a commitment plan. Rejected if the plan is currently calculating, is a system-generated default, or is locked for purchase. Irreversible."}}},"components":{"schemas":{"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Apply (purchase) a commitment plan

> Executes the plan's selected line items as actual commitment purchases. Marks the plan as edited and records the initiating user. The plan is then processed by the commitment-purchase workflow — inspect the plan status afterwards for progress. Rejected if the plan is currently calculating or already locked.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/apply":{"post":{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitmentPlanDetail"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not Found"},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"Apply (purchase) a commitment plan","description":"Executes the plan's selected line items as actual commitment purchases. Marks the plan as edited and records the initiating user. The plan is then processed by the commitment-purchase workflow — inspect the plan status afterwards for progress. Rejected if the plan is currently calculating or already locked."}}},"components":{"schemas":{"CommitmentPlanDetail":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]},"current_coverage":{"type":"number","description":"Commitment coverage of reservable spend today, from existing commitments (0-1) — the BEFORE picture, pre-plan."},"projected_coverage":{"type":"number","description":"Commitment coverage of reservable spend if this plan is applied (0-1) — the AFTER picture, post-plan."},"covered_services":{"type":"array","description":"List of cloud services covered by this plan, with per-service savings and commitment breakdowns","items":{"$ref":"#/components/schemas/CoveredService"}}},"required":["created_at","current_coverage","id","is_calculating","is_renewal","max_term","minimum_commitment","name","projected_coverage","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"CoveredService":{"type":"object","properties":{"service_name":{"type":"string","description":"Cloud service name (e.g. 'Amazon EC2', 'Amazon RDS')"},"num_commitments":{"type":"integer","description":"Number of individual commitments covering this service"},"current_coverage":{"type":"number","description":"Commitment coverage of this service's reservable spend today, from existing commitments (0-1) — the BEFORE picture, pre-plan."},"projected_coverage":{"type":"number","description":"Commitment coverage of this service's reservable spend if this plan is applied (0-1) — the AFTER picture, post-plan."},"commitment_financials_monthly_rate":{"description":"730-hour monthly-rate financials for this service. cloud_provider_cost is `{total}` only (no recurring/amortized split at per-service level). commitment_savings has no rebate field on plans.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]}},"required":["current_coverage","num_commitments","projected_coverage","service_name"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Copy a commitment plan, optionally applying line-item edits

> Creates a draft copy of an existing commitment plan, including its line items and resource matches. The copy is a regular user-created plan (is\_default=false, is\_recommended=false) and is editable via PUT /commitment-plans/{plan\_id}. Useful for forking a system-generated default plan (Recommended / Balanced / High Savings) so it can be modified — defaults themselves are read-only. The copy inherits the source plan's already-computed line items and financials, so it is ready immediately (is\_calculating=false).\
> \
> Optionally apply line-item edits during the copy via two mutually exclusive modes:\
> \
> \- Explicit: pass \`line\_item\_updates\` referencing the SOURCE plan's line\_item\_ids; the server translates them to the copy's new IDs internally and applies them atomically.\
> \- Resolution: pass \`target\_contract\_term\` (+ optional \`target\_payment\_option\` / \`target\_line\_item\_ids\`) and the server swaps every selected (or scoped) line item on the copy to the closest candidate at or below the target term. Saves the LLM having to enumerate per-line edits when the user wants a uniform shape change on the new plan.\
> \
> If any edit fails (unknown source line\_item\_id, invalid offer, integer-coercion error on a unit-basis offer's \`selected\_amount\`, duplicate line\_item\_id within \`line\_item\_updates\`), the entire copy + updates rolls back — no orphan copy persists. This is the canonical 'copy to edit' workflow; saves the round trip and ID-translation logic vs a separate copy + update sequence.\
> \
> Returns the new plan in CommitmentPlanListSchema shape — id + headline financials + configuration; covered\_services and coverage fields are intentionally omitted because computing them eagerly loads per-service summaries (expensive) and the typical caller just needs the post-edit totals to confirm the copy. Follow up with \`commitment\_plan\_details\` on the returned id if you need the full breakdown. In resolution mode the response additionally carries a \`resolution\` array with one entry per scoped line item (\`actual\_term\` / \`actual\_payment\_option\` / \`actual\_term\_reason\` of \`exact\_match\`, \`fallback\_closest\_shorter\`, or \`no\_alternative\`). Surface no\_alternative outcomes to the user so they understand why coverage may be partial.\
> \
> Rejected if the source plan is currently being calculated.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/copy":{"post":{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanLineItemUpdateResponse"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not Found"},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CopyCommitmentPlanArgs"}}}},"tags":["Commitment Plans (Beta)"],"summary":"Copy a commitment plan, optionally applying line-item edits","description":"Creates a draft copy of an existing commitment plan, including its line items and resource matches. The copy is a regular user-created plan (is_default=false, is_recommended=false) and is editable via PUT /commitment-plans/{plan_id}. Useful for forking a system-generated default plan (Recommended / Balanced / High Savings) so it can be modified — defaults themselves are read-only. The copy inherits the source plan's already-computed line items and financials, so it is ready immediately (is_calculating=false).\n\nOptionally apply line-item edits during the copy via two mutually exclusive modes:\n\n- Explicit: pass `line_item_updates` referencing the SOURCE plan's line_item_ids; the server translates them to the copy's new IDs internally and applies them atomically.\n- Resolution: pass `target_contract_term` (+ optional `target_payment_option` / `target_line_item_ids`) and the server swaps every selected (or scoped) line item on the copy to the closest candidate at or below the target term. Saves the LLM having to enumerate per-line edits when the user wants a uniform shape change on the new plan.\n\nIf any edit fails (unknown source line_item_id, invalid offer, integer-coercion error on a unit-basis offer's `selected_amount`, duplicate line_item_id within `line_item_updates`), the entire copy + updates rolls back — no orphan copy persists. This is the canonical 'copy to edit' workflow; saves the round trip and ID-translation logic vs a separate copy + update sequence.\n\nReturns the new plan in CommitmentPlanListSchema shape — id + headline financials + configuration; covered_services and coverage fields are intentionally omitted because computing them eagerly loads per-service summaries (expensive) and the typical caller just needs the post-edit totals to confirm the copy. Follow up with `commitment_plan_details` on the returned id if you need the full breakdown. In resolution mode the response additionally carries a `resolution` array with one entry per scoped line item (`actual_term` / `actual_payment_option` / `actual_term_reason` of `exact_match`, `fallback_closest_shorter`, or `no_alternative`). Surface no_alternative outcomes to the user so they understand why coverage may be partial.\n\nRejected if the source plan is currently being calculated."}}},"components":{"schemas":{"PlanLineItemUpdateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]},"resolution":{"type":"array","description":"Per-line-item resolution outcome when `target_contract_term` was passed. One entry per line item that was IN SCOPE for the request (covers `no_alternative` items too — those are not in the applied updates but are surfaced here so callers can see what the server couldn't satisfy). `actual_term_reason` is one of: `exact_match` (landed at target), `fallback_closest_shorter` (used the longest available term ≤ target with same payment option), `no_alternative` (no candidate satisfied — line item left unchanged). Absent / null on explicit-mode calls.","items":{"$ref":"#/components/schemas/HypotheticalLineItem"},"nullable":true}},"required":["created_at","id","is_calculating","is_renewal","max_term","minimum_commitment","name","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"HypotheticalLineItem":{"type":"object","properties":{"line_item_id":{"type":"string","format":"uuid","description":"Line item ID."},"actual_term":{"description":"The contract term this line item actually contributes to the rollup at. Equals the target term when an exact match exists; otherwise the longest available term <= target with the same payment option, or the line item's current term as a last resort.","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month",null],"nullable":true},"actual_payment_option":{"description":"Payment option of the candidate this line item contributes. Equals the target payment option except when actual_term_reason='no_alternative' (falls back to current, which may have a different payment option).","type":"string","enum":["no_upfront","partial_upfront","all_upfront",null],"nullable":true},"actual_term_reason":{"type":"string","enum":["exact_match","fallback_closest_shorter","no_alternative"],"description":"Why this line item landed at actual_term. exact_match = target available; fallback_closest_shorter = used the longest available term <= target with same payment option; no_alternative = nothing qualified, kept at current."}},"required":["actual_payment_option","actual_term","actual_term_reason","line_item_id"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false},"CopyCommitmentPlanArgs":{"type":"object","properties":{"target_contract_term":{"default":null,"description":"Server-side resolution mode. Set to a target contract term and the server resolves the per-line-item update set using the same fallback rule the comparison endpoint projects: exact match on (term, payment) where available, else closest shorter term with the same payment option (GRI preferred within tier). Mutually exclusive with explicit per-line-item updates — pass one OR the other, not both. Preferred over enumerating updates manually because the server can't silently omit entries from a list it builds itself.","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month",null],"nullable":true},"target_payment_option":{"default":"no_upfront","description":"Target payment option for resolution mode. Defaults to no_upfront — most users are uncomfortable with cash at signing, so this matches the default framing for plan comparisons. Ignored when `target_contract_term` is null.","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]},"target_line_item_ids":{"type":"array","default":null,"description":"Optional subset of line items to update under resolution mode. If omitted, applies to all selected line items in the plan. Ignored when `target_contract_term` is null.","items":{"type":"string","format":"uuid"},"nullable":true},"name":{"type":"string","default":null,"description":"Name for the copied plan. If omitted, defaults to '<source plan name> <today's date>'.","nullable":true},"line_item_updates":{"type":"array","default":null,"description":"Optional list of line-item edits to apply during the copy. Each entry has the same shape as `update_commitment_plan_line_items`'s `updates` (line_item_id + optional is_selected / account_id / offer-swap triple). Entries reference the SOURCE plan's line_item_ids; the server translates them to the copy's new IDs internally and applies them atomically. If any edit fails, the entire copy + updates rolls back. Use this for the canonical 'copy to edit' workflow — saves the round trip and ID-translation logic that would otherwise live on the client. Mutually exclusive with `target_contract_term` (resolution mode).","items":{"$ref":"#/components/schemas/LineItemUpdateEntry"},"nullable":true}},"additionalProperties":false},"LineItemUpdateEntry":{"type":"object","properties":{"line_item_id":{"type":"string","format":"uuid","description":"ID of the line item to update."},"is_selected":{"type":"boolean","description":"Include this line item in the plan's top-level financials and apply it when the plan is purchased."},"account_id":{"type":"string","description":"Cloud account ID this commitment is scoped to.","nullable":true},"offer_id":{"type":"string","format":"uuid","description":"Swap this line item's offer. Pair with `lease_menu_item_id` and `selected_amount` from the same comparison entry."},"lease_menu_item_id":{"type":"string","format":"uuid","description":"Lease attached to the chosen offer. Must come from the same comparison entry as `offer_id`. NULL VS OMITTED MATTERS: explicitly passing `null` clears the existing lease (converting a leased Archera-guaranteed commitment into a native one); omitting the field leaves the existing lease in place. To switch a leased GRI line item to a native offer, you MUST pass `null` here — otherwise the old lease stays attached and the line item's effective `contract_term` (derived from the lease's lockin hours) won't change.","nullable":true},"selected_amount":{"type":"number","description":"Commitment amount for the offer — unit count for RIs / unit-based CUDs, dollar-basis for Savings Plans / spend-based CUDs."}},"required":["line_item_id"],"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Get commitment plan line items

> Returns individual commitment recommendations within a plan, including offer details, per-line-item savings, and costs. Each line item has an is\_selected field: if false, the line item is excluded from the plan and its costs/savings are NOT included in the plan's top-level metrics. Pass \`line\_item\_ids\` to fetch a specific subset (e.g. a single line item).

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/line-items":{"get":{"parameters":[{"in":"query","name":"line_item_ids","description":"Optional list of line-item ids to scope the response to. When omitted, returns every line item in the plan.","schema":{"type":"array","default":null,"items":{"type":"string","format":"uuid"},"nullable":true},"required":false,"explode":true,"style":"form"},{"in":"query","name":"renewal_commitment_ids","description":"Renewal plans only: scope to line items proposed as the replacement for these specific expiring commitments. Useful for \"show me what's being proposed to replace commitment X.\" Rejected with 400 on non-renewal plans (their line items have no renewal linkage; this guards against stale/wrong plan ids silently returning unrelated rows).","schema":{"type":"array","default":null,"items":{"type":"string","format":"uuid"},"nullable":true},"required":false,"explode":true,"style":"form"},{"in":"query","name":"order_by","description":"Field to order results by","schema":{"type":"string","default":"monthly_net_savings","enum":["monthly_net_savings","monthly_total_cost","breakeven_days","discount_rate","upfront_cost"]},"required":false},{"in":"query","name":"desc","description":"Sort descending (default true)","schema":{"type":"boolean","default":true},"required":false},{"in":"query","name":"page","schema":{"type":"integer","default":1,"minimum":1},"required":false},{"in":"query","name":"page_size","schema":{"type":"integer","default":20,"minimum":1,"maximum":10000},"required":false}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommitmentLineItem"}}}},"headers":{"X-Pagination":{"$ref":"#/components/headers/PAGINATION"}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"Get commitment plan line items","description":"Returns individual commitment recommendations within a plan, including offer details, per-line-item savings, and costs. Each line item has an is_selected field: if false, the line item is excluded from the plan and its costs/savings are NOT included in the plan's top-level metrics. Pass `line_item_ids` to fetch a specific subset (e.g. a single line item)."}}},"components":{"schemas":{"CommitmentLineItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Line item identifier"},"is_selected":{"type":"boolean","description":"Whether this line item is included in the plan. If false, this line item is excluded and its costs/savings are NOT reflected in the plan's top-level metrics."},"account_id":{"type":"string","description":"Cloud account ID this commitment applies to","nullable":true},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year')","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"contract_spec":{"description":"Detailed contract specifications including commitment type and properties","allOf":[{"$ref":"#/components/schemas/ContractSpec"}]},"offer":{"description":"Commitment offer details including type, region, and instance info","allOf":[{"$ref":"#/components/schemas/CommitmentOffer"}]},"discount_rate":{"type":"number","description":"Discount rate vs on-demand (0-1)"},"breakeven_days":{"readOnly":true,"description":"Days until this line item pays for itself"},"selected_amount":{"readOnly":true,"description":"Selected commitment amount — either a quantity (for RIs) or a dollar commitment (for Savings Plans), whichever is applicable"},"recommended_amount":{"readOnly":true,"description":"Recommended commitment amount — either a quantity (for RIs) or a dollar commitment (for Savings Plans), whichever is applicable"},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing for this specific line item. NOT a rate — do not sum with monthly-rate fields. Summing the commitment_upfront_cost of all selected line items equals the parent plan's commitment_upfront_cost."},"commitment_financials_monthly_rate":{"description":"Projected line item economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field on plans.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"covered_services":{"type":"array","description":"Cloud service identifiers (e.g. 'AmazonEC2', 'AmazonRDS') that this line item's commitment is expected to cover. Reflects the underlying resources the recommender matched to this commitment, not the offer's raw eligibility.","items":{"type":"string"}},"renewal_commitment_id":{"type":"string","format":"uuid","description":"ID of the expiring commitment this line item is renewing. Populated only on renewal plans (`plan_type=renewal`); null on purchase / infrastructure plans. Use the `renewal_commitment_ids` query param on this endpoint to filter to the line items proposed as replacements for specific expiring commitments.","nullable":true}},"required":["id","is_selected"],"additionalProperties":false},"ContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier"},"properties":{"type":"object","default":{},"description":"Additional contract properties","additionalProperties":{}},"term":{"description":"Contract term","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month",null],"nullable":true},"payment_option":{"description":"Payment option","type":"string","enum":["no_upfront","partial_upfront","all_upfront",null],"nullable":true}},"additionalProperties":false},"CommitmentOffer":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Offer identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"type":{"type":"string","description":"Commitment type (e.g. 'ri', 'savings_plan', 'cud')"},"region":{"type":"string","description":"Cloud region (e.g. 'us-east-1')","nullable":true},"duration_seconds":{"type":"integer","description":"Total commitment duration in seconds"},"instance_type":{"type":"string","description":"Instance type (e.g. 'm5.xlarge'), null for Savings Plans","nullable":true},"instance_family":{"type":"string","description":"Instance family (e.g. 'm5'), null for some commitment types","nullable":true},"offering_class":{"description":"Offering class (e.g. 'standard', 'convertible')","type":"string","enum":["standard","convertible",null],"nullable":true},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront')","type":"string","enum":["no_upfront","partial_upfront","all_upfront",null],"nullable":true},"plan_type":{"type":"string","description":"Plan type (e.g. 'Compute', 'EC2Instance')","nullable":true},"product_description":{"type":"string","description":"Product description (e.g. 'Linux/UNIX')","nullable":true},"display_name":{"type":"string","description":"Human-readable offer name","nullable":true},"is_flexible":{"type":"boolean","description":"Whether the commitment has instance size flexibility","nullable":true}},"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"PaginationMetadata":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of items."},"total_pages":{"type":"integer","description":"Total number of pages."},"first_page":{"type":"integer","description":"First available page number."},"last_page":{"type":"integer","description":"Last available page number."},"page":{"type":"integer","description":"Current page number."},"previous_page":{"type":"integer","description":"Previous page number."},"next_page":{"type":"integer","description":"Next page number."}},"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"headers":{"PAGINATION":{"description":"Pagination metadata","schema":{"$ref":"#/components/schemas/PaginationMetadata"}}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Update commitment plan line items

> Atomically apply line-item edits in a single request. Two modes:\
> \
> \- Explicit: pass \`updates\`, a list where each entry carries the same fields the singular line-item update would accept (selection, account, offer-swap triple) plus the \`line\_item\_id\` selector.\
> \- Resolution: pass \`target\_contract\_term\` (+ optional \`target\_payment\_option\` / \`target\_line\_item\_ids\`) and the server swaps every selected (or scoped) line item to the closest candidate at or below the target term. Saves the LLM having to enumerate many edits when the user wants a uniform shape change.\
> \
> Modes are mutually exclusive. All updates are applied within a single transaction — if any fails (unknown line item, invalid offer, integer-coercion error on a unit-basis offer's \`selected\_amount\`), the whole call is rejected and no changes persist.\
> \
> Returns the updated plan in CommitmentPlanListSchema shape — id + headline financials + configuration; covered\_services and coverage fields are intentionally omitted because computing them eagerly loads per-service summaries (expensive) and the typical caller just needs the post-edit totals to confirm the change. Follow up with \`commitment\_plan\_details\` on the returned id if you need the full breakdown. In resolution mode the response additionally carries a \`resolution\` array with one entry per scoped line item: the \`actual\_term\` / \`actual\_payment\_option\` applied and an \`actual\_term\_reason\` of \`exact\_match\`, \`fallback\_closest\_shorter\`, or \`no\_alternative\` (the latter were left untouched). Surface no\_alternative outcomes to the user so they understand why coverage may be partial.\
> \
> Rejected if the parent plan is currently calculating, is a system-generated default, or is locked for purchase.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/line-items/update":{"post":{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanLineItemUpdateResponse"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not Found"},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLineItemsArgs"}}}},"tags":["Commitment Plans (Beta)"],"summary":"Update commitment plan line items","description":"Atomically apply line-item edits in a single request. Two modes:\n\n- Explicit: pass `updates`, a list where each entry carries the same fields the singular line-item update would accept (selection, account, offer-swap triple) plus the `line_item_id` selector.\n- Resolution: pass `target_contract_term` (+ optional `target_payment_option` / `target_line_item_ids`) and the server swaps every selected (or scoped) line item to the closest candidate at or below the target term. Saves the LLM having to enumerate many edits when the user wants a uniform shape change.\n\nModes are mutually exclusive. All updates are applied within a single transaction — if any fails (unknown line item, invalid offer, integer-coercion error on a unit-basis offer's `selected_amount`), the whole call is rejected and no changes persist.\n\nReturns the updated plan in CommitmentPlanListSchema shape — id + headline financials + configuration; covered_services and coverage fields are intentionally omitted because computing them eagerly loads per-service summaries (expensive) and the typical caller just needs the post-edit totals to confirm the change. Follow up with `commitment_plan_details` on the returned id if you need the full breakdown. In resolution mode the response additionally carries a `resolution` array with one entry per scoped line item: the `actual_term` / `actual_payment_option` applied and an `actual_term_reason` of `exact_match`, `fallback_closest_shorter`, or `no_alternative` (the latter were left untouched). Surface no_alternative outcomes to the user so they understand why coverage may be partial.\n\nRejected if the parent plan is currently calculating, is a system-generated default, or is locked for purchase."}}},"components":{"schemas":{"PlanLineItemUpdateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique plan identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"name":{"type":"string","description":"Plan name (e.g. 'Recommended', 'Balanced', 'High Savings')"},"description":{"type":"string","description":"Human-readable summary of the plan","nullable":true},"is_renewal":{"type":"boolean","description":"True if this plan was created to renew a set of expiring commitments — `configuration.renewal_commitment_ids` is populated when true. False otherwise (covers both purchase and infrastructure flavors — the distinction is not user-meaningful, both cover uncovered resources with new commitments)."},"status":{"description":"Plan status (e.g. 'draft', 'in_progress', 'completed')","type":"string","enum":["new","reviewed","scheduled","completed","draft","needs_review","in_progress"]},"is_calculating":{"type":"boolean","description":"True if the plan is still being computed"},"created_at":{"type":"string","format":"date-time","description":"When the plan was generated"},"usage_start_date":{"type":"string","format":"date-time","description":"Start of the usage window the plan was computed from. Null on renewal plans — renewals derive their window from the source commitments' end dates, not from a lookback (see configuration.renewal_commitment_ids).","nullable":true},"usage_end_date":{"type":"string","format":"date-time","description":"End of the usage window the plan was computed from. Null on renewal plans (see usage_start_date).","nullable":true},"max_term":{"type":"string","description":"Maximum commitment term (e.g. '30_DAY', '1_YEAR', '3_YEAR')","nullable":true},"minimum_commitment":{"type":"number","description":"Minimum total spend being committed to"},"breakeven_days":{"readOnly":true,"description":"Days until the plan pays for itself. If commitments are kept for at least this many days, the plan is a more profitable decision than running on-demand."},"commitment_upfront_cost":{"type":"number","description":"One-time total dollars required at signing if this plan is applied. NOT a rate — do not sum with monthly-rate fields. Typically 0 for the Recommended plan; can be significant for High Savings / All Upfront plans. Always mention explicitly to the user when non-zero."},"commitment_financials_monthly_rate":{"description":"Projected plan economics as 730-hour monthly rates. cloud_provider_cost includes full purchase-term detail (recurring, amortized_upfront). commitment_savings has no rebate field — plans are proposals, no rebates accumulated.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"configuration":{"description":"The inputs that drove plan generation — the max_upfront_cost cap and the list of contract specs considered. Round-trips: a GET response can be round-tripped to PUT to re-run generation after editing.","allOf":[{"$ref":"#/components/schemas/CommitmentPlanConfiguration"}]},"resolution":{"type":"array","description":"Per-line-item resolution outcome when `target_contract_term` was passed. One entry per line item that was IN SCOPE for the request (covers `no_alternative` items too — those are not in the applied updates but are surfaced here so callers can see what the server couldn't satisfy). `actual_term_reason` is one of: `exact_match` (landed at target), `fallback_closest_shorter` (used the longest available term ≤ target with same payment option), `no_alternative` (no candidate satisfied — line item left unchanged). Absent / null on explicit-mode calls.","items":{"$ref":"#/components/schemas/HypotheticalLineItem"},"nullable":true}},"required":["created_at","id","is_calculating","is_renewal","max_term","minimum_commitment","name","provider","status"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"CommitmentPlanConfiguration":{"type":"object","properties":{"max_upfront_cost":{"type":"number","default":0,"description":"Cap on the one-time upfront dollars the generated plan is allowed to include. Defaults to 0 — the recommender excludes any line item with an upfront cost. Pass null to lift the cap entirely. Otherwise, line items with upfront costs are excluded if adding them would exceed the cap.","nullable":true},"lookback_days":{"type":"integer","default":null,"description":"How many days of historical usage to feed into plan generation. Defaults to 7 when omitted — matches the recommender's default and gives a representative recent-week baseline. Increase for workloads with weekly/seasonal variance. NULL on renewal plans: renewals derive their usage window from the source commitments' end dates, so this field has no effect. Sending a non-null value to a renewal plan PUT is rejected so round-tripping is honest.","nullable":true},"contract_specs":{"description":"List of contract specs to consider when generating the plan. Each spec is a triple of (commitment_type, contract_term, payment_option). The plan generator will pick the best mix of offerings matching these specs.","type":"array","items":{"$ref":"#/components/schemas/ConfigurationContractSpec"}},"resource_ids":{"type":"array","default":null,"description":"Optional list of resource composite ids (`<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`, the same form returned as `id` on resource-SKU responses) to scope the generated plan to specific resources. When non-empty, the plan's coverage is restricted to these resources and the plan is created as an infrastructure plan — line items only attempt to cover the listed resources rather than the whole segment. Mutually exclusive with `renewal_commitment_ids` (a plan can be scoped by resources OR scoped by renewing commitments, not both). Usually omitted; supply only when the user has explicitly named the resources to cover. Templates do not accept this field — supplying it on a template create/update is rejected.","items":{},"nullable":true},"renewal_commitment_ids":{"type":"array","default":null,"description":"Optional list of expiring commitment ids the plan is renewing. When non-empty, the plan is a renewal: coverage is built from the source commitments' historical usage, and each generated line item carries a `renewal_commitment_id` linking back to the source it proposes to replace. Mutually exclusive with `resource_ids`. On a renewal plan PUT this re-targets which commitments are being renewed (recalc); on a non-renewal plan PUT, sending this is rejected (use the dedicated POST /commitment-plans/renewals to create a renewal). Read-back unchanged from a GET so the configuration round-trips through PUT.","items":{"type":"string","format":"uuid"},"nullable":true}},"required":["contract_specs"],"additionalProperties":false},"ConfigurationContractSpec":{"type":"object","properties":{"commitment_type":{"type":"string","description":"Commitment type identifier — e.g. 'aws/savingsplan/Compute', 'aws/AmazonEC2', 'aws/AmazonRDS'. Values are provider-prefixed; fetch the exact list from GET /commitment-types and pass through verbatim. Rejected with 422 if the identifier is unknown across all providers; the validator does not enforce that the type belongs to the request's `provider` (a mismatched-but-real type will pass schema validation and produce a plan with no line items)."},"contract_term":{"description":"Commitment term (e.g. 'thirty_day_gris', 'one_year_gris', 'one_year', 'three_year'). Validated against the catalog entry for the supplied commitment_type — invalid (type, term) pairs are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront'). Validated against the catalog entry for the supplied (commitment_type, contract_term) pair — invalid triples are rejected with 422. Validation is cross-provider (see `commitment_type`).","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":["commitment_type","contract_term","payment_option"],"additionalProperties":false},"HypotheticalLineItem":{"type":"object","properties":{"line_item_id":{"type":"string","format":"uuid","description":"Line item ID."},"actual_term":{"description":"The contract term this line item actually contributes to the rollup at. Equals the target term when an exact match exists; otherwise the longest available term <= target with the same payment option, or the line item's current term as a last resort.","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month",null],"nullable":true},"actual_payment_option":{"description":"Payment option of the candidate this line item contributes. Equals the target payment option except when actual_term_reason='no_alternative' (falls back to current, which may have a different payment option).","type":"string","enum":["no_upfront","partial_upfront","all_upfront",null],"nullable":true},"actual_term_reason":{"type":"string","enum":["exact_match","fallback_closest_shorter","no_alternative"],"description":"Why this line item landed at actual_term. exact_match = target available; fallback_closest_shorter = used the longest available term <= target with same payment option; no_alternative = nothing qualified, kept at current."}},"required":["actual_payment_option","actual_term","actual_term_reason","line_item_id"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false},"UpdateLineItemsArgs":{"type":"object","properties":{"target_contract_term":{"default":null,"description":"Server-side resolution mode. Set to a target contract term and the server resolves the per-line-item update set using the same fallback rule the comparison endpoint projects: exact match on (term, payment) where available, else closest shorter term with the same payment option (GRI preferred within tier). Mutually exclusive with explicit per-line-item updates — pass one OR the other, not both. Preferred over enumerating updates manually because the server can't silently omit entries from a list it builds itself.","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month",null],"nullable":true},"target_payment_option":{"default":"no_upfront","description":"Target payment option for resolution mode. Defaults to no_upfront — most users are uncomfortable with cash at signing, so this matches the default framing for plan comparisons. Ignored when `target_contract_term` is null.","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]},"target_line_item_ids":{"type":"array","default":null,"description":"Optional subset of line items to update under resolution mode. If omitted, applies to all selected line items in the plan. Ignored when `target_contract_term` is null.","items":{"type":"string","format":"uuid"},"nullable":true},"updates":{"type":"array","default":null,"minItems":1,"description":"List of per-line-item updates to apply atomically. Required unless `target_contract_term` is set (resolution mode). Each entry's `line_item_id` must be on the parent plan.","items":{"$ref":"#/components/schemas/LineItemUpdateEntry"},"nullable":true}},"additionalProperties":false},"LineItemUpdateEntry":{"type":"object","properties":{"line_item_id":{"type":"string","format":"uuid","description":"ID of the line item to update."},"is_selected":{"type":"boolean","description":"Include this line item in the plan's top-level financials and apply it when the plan is purchased."},"account_id":{"type":"string","description":"Cloud account ID this commitment is scoped to.","nullable":true},"offer_id":{"type":"string","format":"uuid","description":"Swap this line item's offer. Pair with `lease_menu_item_id` and `selected_amount` from the same comparison entry."},"lease_menu_item_id":{"type":"string","format":"uuid","description":"Lease attached to the chosen offer. Must come from the same comparison entry as `offer_id`. NULL VS OMITTED MATTERS: explicitly passing `null` clears the existing lease (converting a leased Archera-guaranteed commitment into a native one); omitting the field leaves the existing lease in place. To switch a leased GRI line item to a native offer, you MUST pass `null` here — otherwise the old lease stays attached and the line item's effective `contract_term` (derived from the lease's lockin hours) won't change.","nullable":true},"selected_amount":{"type":"number","description":"Commitment amount for the offer — unit count for RIs / unit-based CUDs, dollar-basis for Savings Plans / spend-based CUDs."}},"required":["line_item_id"],"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## List the commitments being renewed by a renewal plan

> Returns the expiring commitments that a renewal plan is proposed to replace — identity, dates, guarantee info, and contract term. Ordered by \`end\_date\` ascending (earliest-expiring first) so the caller surfaces the most-urgent renewals first.\
> \
> Rejected with 400 if the plan is not a renewal plan — for non-renewal plans use /line-items or /covered-resources instead.\
> \
> To filter to the commitments tied to a subset of line items, pass \`line\_item\_ids\`. To go the other direction (line items proposed as replacements for a given source commitment), use the \`renewal\_commitment\_ids\` filter on /line-items.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/renewal-commitments":{"get":{"parameters":[{"in":"query","name":"line_item_ids","description":"Optional list of line-item ids to scope to. When supplied, returns only the source commitments whose renewing line items are in this set.","schema":{"type":"array","default":null,"items":{"type":"string","format":"uuid"},"nullable":true},"required":false,"explode":true,"style":"form"},{"in":"query","name":"page","schema":{"type":"integer","default":1,"minimum":1},"required":false},{"in":"query","name":"page_size","schema":{"type":"integer","default":50,"minimum":1,"maximum":200},"required":false}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Commitment"}}}},"headers":{"X-Pagination":{"$ref":"#/components/headers/PAGINATION"}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"List the commitments being renewed by a renewal plan","description":"Returns the expiring commitments that a renewal plan is proposed to replace — identity, dates, guarantee info, and contract term. Ordered by `end_date` ascending (earliest-expiring first) so the caller surfaces the most-urgent renewals first.\n\nRejected with 400 if the plan is not a renewal plan — for non-renewal plans use /line-items or /covered-resources instead.\n\nTo filter to the commitments tied to a subset of line items, pass `line_item_ids`. To go the other direction (line items proposed as replacements for a given source commitment), use the `renewal_commitment_ids` filter on /line-items."}}},"components":{"schemas":{"Commitment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique commitment identifier"},"provider_reservation_id":{"type":"string","description":"Cloud provider's ID for this commitment (e.g. AWS reservation ID)"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"display_name":{"type":"string","description":"Human-readable commitment name"},"type":{"type":"string","description":"Commitment type (e.g. 'Compute', 'EC2Instance', 'RDS')"},"status":{"description":"Commitment status (e.g. 'active', 'expired', 'queued')","type":"string","enum":["active","locked","new","reselling","unlocked","unknown","cancelled","expired","recently_expired","resold","removed"]},"is_active":{"type":"boolean","description":"Whether the commitment is currently active"},"is_archera_guaranteed":{"type":"boolean","description":"Whether this is an Archera Guaranteed Commitment"},"account_id":{"type":"string","description":"Cloud account ID this commitment is in","nullable":true},"billing_account_id":{"type":"string","description":"Billing/management account ID","nullable":true},"start_date":{"type":"string","format":"date-time","description":"When the commitment started","nullable":true},"end_date":{"type":"string","format":"date-time","description":"When the commitment expires","nullable":true},"duration_seconds":{"type":"integer","description":"Total commitment duration in seconds","nullable":true},"guarantee_start":{"type":"string","format":"date-time","description":"When the Archera guarantee period started","nullable":true},"guarantee_lockin_date":{"type":"string","format":"date-time","description":"When the Archera guarantee lock-in period ends","nullable":true},"guarantee_method":{"readOnly":true,"description":"How the Archera guarantee is delivered. 'rebate': Archera rebates the cost of the unused commitment directly to the user (as cash or credit toward Archera premiums). 'release': Archera takes over the commitment along with remaining payment obligations. Null for non-guaranteed commitments."},"region":{"type":"string","description":"Cloud region (e.g. 'us-east-1')","nullable":true},"instance_type":{"type":"string","description":"Instance type (e.g. 'm5.xlarge')","nullable":true},"instance_family":{"type":"string","description":"Instance family (e.g. 'm5')","nullable":true},"plan_type":{"type":"string","description":"Plan type (e.g. 'Compute', 'EC2Instance')","nullable":true},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront')","type":"string","enum":["no_upfront","partial_upfront","all_upfront",null],"nullable":true},"offering_class":{"description":"Offering class (e.g. 'standard', 'convertible')","type":"string","enum":["standard","convertible",null],"nullable":true},"is_flexible":{"type":"boolean","description":"Whether the commitment has instance size flexibility","nullable":true},"instance_count":{"type":"integer","description":"Number of instances covered","nullable":true},"contract_term":{"description":"Contract term (e.g. 'thirty_day_gris', 'one_year')","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month",null],"nullable":true}},"required":["id","provider"],"additionalProperties":false},"PaginationMetadata":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of items."},"total_pages":{"type":"integer","description":"Total number of pages."},"first_page":{"type":"integer","description":"First available page number."},"last_page":{"type":"integer","description":"Last available page number."},"page":{"type":"integer","description":"Current page number."},"previous_page":{"type":"integer","description":"Previous page number."},"next_page":{"type":"integer","description":"Next page number."}},"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"headers":{"PAGINATION":{"description":"Pagination metadata","schema":{"$ref":"#/components/schemas/PaginationMetadata"}}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Compare commitment offers across a plan's line items

> Returns per-line-item offer alternatives plus plan-wide rollups for each (contract\_term, payment\_option) hypothetical. Designed to answer 'what would the plan look like at 3-year' in a single call: hypothetical\_totals carries the rolled-up financials and delta\_vs\_current, with per-line-item resolution exposed for transparency. Each line item lands at the target term when available, else the longest available term <= target with the same payment option (GRI preferred within tier), else its current term. Defaults: line\_item\_ids=all selected, contract\_terms=all distinct in candidates, payment\_options=\[no\_upfront].

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/comparison":{"get":{"parameters":[{"in":"query","name":"line_item_ids","description":"Optional subset of line items to compare. If omitted, defaults to all selected line items in the plan.","schema":{"type":"array","default":null,"items":{"type":"string","format":"uuid"},"nullable":true},"required":false,"explode":true,"style":"form"},{"in":"query","name":"contract_terms","description":"Optional list of target terms to roll up. If omitted, the response includes a hypothetical for every distinct contract_term that appears in any line item's candidates after the payment-option filter.","schema":{"type":"array","default":null,"items":{"type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month"]},"nullable":true},"required":false,"explode":true,"style":"form"},{"in":"query","name":"payment_options","description":"Payment options to include. Defaults to no_upfront only — most users are uncomfortable with cash at signing, so this matches the default framing for plan comparisons. Pass partial_upfront / all_upfront explicitly to surface those.","schema":{"type":"array","items":{"type":"string","enum":["no_upfront","partial_upfront","all_upfront"]}},"required":false,"explode":true,"style":"form"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LineItemOfferComparisonResponse"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not Found"},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"Compare commitment offers across a plan's line items","description":"Returns per-line-item offer alternatives plus plan-wide rollups for each (contract_term, payment_option) hypothetical. Designed to answer 'what would the plan look like at 3-year' in a single call: hypothetical_totals carries the rolled-up financials and delta_vs_current, with per-line-item resolution exposed for transparency. Each line item lands at the target term when available, else the longest available term <= target with the same payment option (GRI preferred within tier), else its current term. Defaults: line_item_ids=all selected, contract_terms=all distinct in candidates, payment_options=[no_upfront]."}}},"components":{"schemas":{"LineItemOfferComparisonResponse":{"type":"object","properties":{"current_totals":{"description":"Plan-wide totals for the line items currently in scope (defaults to all selected, narrowed by line_item_ids if provided). Use this as the baseline when interpreting hypothetical deltas.","allOf":[{"$ref":"#/components/schemas/LineItemOfferComparisonTotals"}]},"hypothetical_totals":{"type":"array","description":"One entry per (contract_term, payment_option) combination requested (or per distinct term present in candidates if contract_terms was omitted). Each entry's totals + delta_vs_current answer 'what's the plan-wide impact of this term?' in one place — no client-side summing across line items required.","items":{"$ref":"#/components/schemas/HypotheticalTotal"}},"data":{"type":"array","description":"Per-line-item detail. Use when the user wants to drill into 'why does RDS not have a 3-year candidate' or to assemble an update payload.","items":{"$ref":"#/components/schemas/LineItemOfferComparisonRow"}}},"required":["current_totals","data","hypothetical_totals"],"additionalProperties":false},"LineItemOfferComparisonTotals":{"type":"object","properties":{"commitment_financials_monthly_rate":{"description":"730-hour monthly rate financials summed across the line items in scope. Same shape as on plans / line items.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"commitment_upfront_cost":{"type":"number","description":"Sum of one-time upfront dollars at signing across the line items in scope. NOT a rate — do not sum with monthly-rate fields."}},"required":["commitment_financials_monthly_rate","commitment_upfront_cost"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"HypotheticalTotal":{"type":"object","properties":{"contract_term":{"description":"Target contract term for this hypothetical.","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month",null],"nullable":true},"payment_option":{"description":"Target payment option for this hypothetical.","type":"string","enum":["no_upfront","partial_upfront","all_upfront"]},"commitment_financials_monthly_rate":{"description":"Rolled-up monthly-rate financials assuming each line item adopts its candidate per the fallback rule. Same shape as on plans / line items.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"commitment_upfront_cost":{"type":"number","description":"Sum of one-time upfront dollars across the line items under this hypothetical. NOT a rate."},"delta_vs_current":{"description":"Axis-by-axis difference vs current_totals. The headline 'should I do this' answer is delta_vs_current.monthly_net_savings.","allOf":[{"$ref":"#/components/schemas/HypotheticalDelta"}]},"line_items":{"type":"array","description":"Per-line-item resolution for this hypothetical. Use to call out fallbacks ('14 of 20 line items would land at 3-year; 5 would fall back to 1-year GRI; 1 has no shorter alternative and stays at current').","items":{"$ref":"#/components/schemas/HypotheticalLineItem"}}},"required":["commitment_financials_monthly_rate","commitment_upfront_cost","contract_term","delta_vs_current","line_items","payment_option"],"additionalProperties":false},"HypotheticalDelta":{"type":"object","properties":{"monthly_net_savings":{"type":"number","description":"Hypothetical's monthly net savings minus current_totals'. Positive means switching saves more than the plan does today."},"monthly_commitment_cost":{"type":"number","description":"Hypothetical's monthly commitment cost minus current_totals'. Positive means more dollars committed monthly."},"upfront_cost":{"type":"number","description":"Hypothetical's one-time upfront cost minus current_totals'. NOT a rate."}},"required":["monthly_commitment_cost","monthly_net_savings","upfront_cost"],"additionalProperties":false},"HypotheticalLineItem":{"type":"object","properties":{"line_item_id":{"type":"string","format":"uuid","description":"Line item ID."},"actual_term":{"description":"The contract term this line item actually contributes to the rollup at. Equals the target term when an exact match exists; otherwise the longest available term <= target with the same payment option, or the line item's current term as a last resort.","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month",null],"nullable":true},"actual_payment_option":{"description":"Payment option of the candidate this line item contributes. Equals the target payment option except when actual_term_reason='no_alternative' (falls back to current, which may have a different payment option).","type":"string","enum":["no_upfront","partial_upfront","all_upfront",null],"nullable":true},"actual_term_reason":{"type":"string","enum":["exact_match","fallback_closest_shorter","no_alternative"],"description":"Why this line item landed at actual_term. exact_match = target available; fallback_closest_shorter = used the longest available term <= target with same payment option; no_alternative = nothing qualified, kept at current."}},"required":["actual_payment_option","actual_term","actual_term_reason","line_item_id"],"additionalProperties":false},"LineItemOfferComparisonRow":{"type":"object","properties":{"line_item_id":{"type":"string","format":"uuid","description":"Line item ID."},"current":{"description":"The line item's current offer + lease, in the same shape as OfferComparisonEntrySchema. Its delta_vs_current is all zeros.","allOf":[{"$ref":"#/components/schemas/OfferComparisonEntry"}]},"candidates":{"type":"array","description":"Alternative (offer, lease) pairs for this line item, filtered to the requested contract_terms and payment_options. Each entry carries its own contract_term and payment_option (on offer); fields offer_id, lease_menu_item_id, and selected_amount can be copied verbatim into POST /commitment-plans/{plan_id}/line-items/update (in the `updates` list) to swap the line item to that candidate.","items":{"$ref":"#/components/schemas/OfferComparisonEntry"}}},"required":["candidates","current","line_item_id"],"additionalProperties":false},"OfferComparisonEntry":{"type":"object","properties":{"is_current":{"type":"boolean","description":"True if this entry matches the line item's current offer + lease. Exactly one entry per response has this set; its `delta_vs_current` values are all zero."},"offer_id":{"type":"string","format":"uuid","description":"Pass to PUT as `offer_id` to switch the line item to this offer."},"offer":{"description":"Full offer details (type, region, instance, payment_option, etc).","allOf":[{"$ref":"#/components/schemas/CommitmentOffer"}]},"lease_menu_item_id":{"type":"string","format":"uuid","description":"Lease attached to this candidate, or null for none. Pass to PUT as `lease_menu_item_id`.","nullable":true},"selected_amount":{"type":"number","description":"Commitment amount this candidate would be sized to — unit count for RIs / unit-based CUDs, dollar-per-hour rate for Savings Plans / spend-based CUDs. Pass to PUT as `selected_amount`; the server routes it to the right underlying column based on offer type."},"contract_term":{"description":"Effective commitment term — derived from the lease lockin hours when `lease_menu_item_id` is set (e.g. '1_year_gris'), else from the offer's own duration (e.g. 'one_year', 'three_year'). This is the real lock-in period, not the offer's raw duration — a Compute Savings Plan offer with a 3-year duration paired with a 1-year lease yields `one_year_gris`, not `three_year`. Prefer this field over `offer.duration_seconds` when describing term length.","type":"string","enum":["one_year_gris","thirty_day_gris","two_month_gris","three_month_gris","four_month_gris","five_month_gris","six_month_gris","seven_month_gris","eight_month_gris","nine_month_gris","ten_month_gris","eleven_month_gris","twelve_month_gris","thirteen_month_gris","fourteen_month_gris","fifteen_month_gris","sixteen_month_gris","seventeen_month_gris","eighteen_month_gris","nineteen_month_gris","twenty_month_gris","twenty_one_month_gris","twenty_two_month_gris","twenty_three_month_gris","twenty_four_month_gris","twenty_five_month_gris","twenty_six_month_gris","twenty_seven_month_gris","twenty_eight_month_gris","twenty_nine_month_gris","thirty_month_gris","thirty_one_month_gris","thirty_two_month_gris","thirty_three_month_gris","thirty_four_month_gris","thirty_five_month_gris","one_year","two_year","three_year","five_year","zero_day","thirty_day","two_month","three_month","four_month","five_month","six_month","seven_month","eight_month","nine_month","ten_month","eleven_month","thirteen_month","fourteen_month","fifteen_month","sixteen_month","seventeen_month","eighteen_month","nineteen_month","twenty_month","twenty_one_month","twenty_two_month","twenty_three_month","twenty_five_month","twenty_six_month","twenty_seven_month","twenty_eight_month","twenty_nine_month","thirty_month","thirty_one_month","thirty_two_month","thirty_three_month","thirty_four_month","thirty_five_month",null],"nullable":true},"discount_rate":{"type":"number","description":"Discount rate vs on-demand (0-1) for this candidate."},"breakeven_days":{"type":"number","description":"Days until this candidate pays for itself. Null if breakeven is undefined (no net savings + no amortized cost).","nullable":true},"commitment_upfront_cost":{"type":"number","description":"One-time dollars required at signing for this candidate. NOT a rate — do not sum with monthly-rate fields."},"commitment_financials_monthly_rate":{"description":"Projected economics as 730-hour monthly rates, same shape as on line items and plans.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"delta_vs_current":{"description":"Axis-by-axis difference vs the current offer. All zeros on the `is_current=true` entry.","allOf":[{"$ref":"#/components/schemas/OfferComparisonDelta"}]}},"required":["breakeven_days","commitment_financials_monthly_rate","commitment_upfront_cost","contract_term","delta_vs_current","discount_rate","is_current","lease_menu_item_id","offer","offer_id","selected_amount"],"additionalProperties":false},"CommitmentOffer":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Offer identifier"},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"type":{"type":"string","description":"Commitment type (e.g. 'ri', 'savings_plan', 'cud')"},"region":{"type":"string","description":"Cloud region (e.g. 'us-east-1')","nullable":true},"duration_seconds":{"type":"integer","description":"Total commitment duration in seconds"},"instance_type":{"type":"string","description":"Instance type (e.g. 'm5.xlarge'), null for Savings Plans","nullable":true},"instance_family":{"type":"string","description":"Instance family (e.g. 'm5'), null for some commitment types","nullable":true},"offering_class":{"description":"Offering class (e.g. 'standard', 'convertible')","type":"string","enum":["standard","convertible",null],"nullable":true},"payment_option":{"description":"Payment option (e.g. 'no_upfront', 'partial_upfront', 'all_upfront')","type":"string","enum":["no_upfront","partial_upfront","all_upfront",null],"nullable":true},"plan_type":{"type":"string","description":"Plan type (e.g. 'Compute', 'EC2Instance')","nullable":true},"product_description":{"type":"string","description":"Product description (e.g. 'Linux/UNIX')","nullable":true},"display_name":{"type":"string","description":"Human-readable offer name","nullable":true},"is_flexible":{"type":"boolean","description":"Whether the commitment has instance size flexibility","nullable":true}},"additionalProperties":false},"OfferComparisonDelta":{"type":"object","properties":{"monthly_net_savings":{"type":"number","description":"Candidate's monthly net savings minus the current line item's."},"upfront_cost":{"type":"number","description":"Candidate's one-time upfront cost minus the current line item's. NOT a rate. Negative is less cash required at signing."},"discount_rate":{"type":"number","description":"Candidate's discount rate minus the current line item's (0-1 basis)."},"breakeven_days":{"type":"number","description":"Candidate's breakeven_days minus the current line item's. Null if either side has no finite breakeven.","nullable":true}},"required":["discount_rate","monthly_net_savings","upfront_cost"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## List filterable covered-resource attributes for a plan

> Returns the fields that can be used in the \`filter\` parameter of /commitment-plans/\<plan\_id>/covered-resources, scoped to the resources the plan actually covers.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/covered-resources/attributes":{"get":{"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BaseAttribute"}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"summary":"List filterable covered-resource attributes for a plan","tags":["Commitment Plans (Beta)"],"description":"Returns the fields that can be used in the `filter` parameter of /commitment-plans/<plan_id>/covered-resources, scoped to the resources the plan actually covers."}}},"components":{"schemas":{"BaseAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["boolean","integer","float","date","datetime","time","currency","percent","string","enum","uuid","tags"]}},"required":["field","name","type"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Get valid values for a filterable covered-resource attribute

> Returns the distinct values for a given field, restricted to the resources the plan covers (and further narrowed by any search/filter passed). Use to discover valid filter values without paginating through the covered-resources list.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/covered-resources/attributes/{field}":{"get":{"parameters":[{"in":"query","name":"line_item_ids","description":"Filter to matches from specific line items","schema":{"type":"array","default":null,"items":{"type":"string","format":"uuid"},"nullable":true},"required":false,"explode":true,"style":"form"},{"in":"query","name":"only_selected_line_items","description":"Only include matches from selected line items (default true)","schema":{"type":"boolean","default":true},"required":false},{"in":"query","name":"search","description":"Free-text ILIKE search across the resource SKU's identity and classification fields (resource id, name, account ids, service, region, instance_type, etc.). Mirrors the search lane on /resources/skus.","schema":{"type":"string","default":null,"nullable":true},"required":false},{"in":"query","name":"filter","description":"JSON filter object — same {field, op, value} tree accepted by /resources/skus. Filterable on the resource SKU side: identity, tags (`has` with nested key/value filters), SKU classification, and the trailing-30-day spend/usage aggregates: `total_cost`, `ondemand_cost`, `gross_savings` (TOTAL summed over the trailing 30 days, NOT a monthly rate — same basis as /resources/skus), `coverage` (fraction of usage covered by ALL existing commitments — current actuals, NOT this plan's projected coverage; that's the response's per-match `projected_coverage`), and `uptime` (fraction). All warehouse aggregates here are actuals across existing commitments, NOT plan-scoped projections. Call /covered-resources/attributes for the full filterable surface.","schema":{"type":"object","default":null,"additionalProperties":{},"nullable":true},"required":false},{"in":"query","name":"order_by","description":"Field to order results by. Defaults to monthly_net_savings. All numeric axes are 730-hour monthly rates on the per-match plan economics, net of the Archera premium where applicable (NOT the resource's warehouse trailing-30-day actuals — those are filterable but not orderable here, on purpose, to keep sort and response framing on the same monthly basis).","schema":{"type":"string","default":"monthly_net_savings","enum":["id","projected_coverage","monthly_net_savings","monthly_before_cost","monthly_after_cost","monthly_after_ondemand_cost"]},"required":false},{"in":"query","name":"desc","description":"Sort descending (default true)","schema":{"type":"boolean","default":true},"required":false}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Attribute"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"summary":"Get valid values for a filterable covered-resource attribute","tags":["Commitment Plans (Beta)"],"description":"Returns the distinct values for a given field, restricted to the resources the plan covers (and further narrowed by any search/filter passed). Use to discover valid filter values without paginating through the covered-resources list."}}},"components":{"schemas":{"Attribute":{"oneOf":[{"$ref":"#/components/schemas/BooleanAttribute"},{"$ref":"#/components/schemas/UUIDAttribute"},{"$ref":"#/components/schemas/StringAttribute"},{"$ref":"#/components/schemas/IntegerAttribute"},{"$ref":"#/components/schemas/FloatAttribute"},{"$ref":"#/components/schemas/CurrencyAttribute"},{"$ref":"#/components/schemas/PercentAttribute"},{"$ref":"#/components/schemas/DateTimeAttribute"},{"$ref":"#/components/schemas/DateAttribute"},{"$ref":"#/components/schemas/TimeAttribute"},{"$ref":"#/components/schemas/EnumAttribute"},{"$ref":"#/components/schemas/TagsAttribute"}],"discriminator":{"propertyName":"type","mapping":{"boolean":"#/components/schemas/BooleanAttribute","uuid":"#/components/schemas/UUIDAttribute","string":"#/components/schemas/StringAttribute","integer":"#/components/schemas/IntegerAttribute","float":"#/components/schemas/FloatAttribute","currency":"#/components/schemas/CurrencyAttribute","percent":"#/components/schemas/PercentAttribute","datetime":"#/components/schemas/DateTimeAttribute","date":"#/components/schemas/DateAttribute","time":"#/components/schemas/TimeAttribute","enum":"#/components/schemas/EnumAttribute","tags":"#/components/schemas/TagsAttribute"}}},"BooleanAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["boolean"],"readOnly":true},"filters":{"type":"array","items":{"$ref":"#/components/schemas/Filter"}}},"required":["field","name","type"],"additionalProperties":false},"Filter":{"type":"object","properties":{"field":{"type":"string"},"value":{"type":"string"},"op":{"type":"string","enum":["=","!=",">",">=","<","<=","in","has","contains"]}},"required":["field","op","value"],"additionalProperties":false},"UUIDAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["uuid"],"readOnly":true}},"required":["field","name","type"],"additionalProperties":false},"StringAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["string"],"readOnly":true},"filters":{"type":"array","items":{"$ref":"#/components/schemas/Filter"}}},"required":["field","name","type"],"additionalProperties":false},"IntegerAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["integer"],"readOnly":true}},"required":["field","name","type"],"additionalProperties":false},"FloatAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["float"],"readOnly":true}},"required":["field","name","type"],"additionalProperties":false},"CurrencyAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["currency"],"readOnly":true}},"required":["field","name","type"],"additionalProperties":false},"PercentAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["percent"],"readOnly":true}},"required":["field","name","type"],"additionalProperties":false},"DateTimeAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["datetime"],"readOnly":true}},"required":["field","name","type"],"additionalProperties":false},"DateAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["date"],"readOnly":true}},"required":["field","name","type"],"additionalProperties":false},"TimeAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["time"],"readOnly":true}},"required":["field","name","type"],"additionalProperties":false},"EnumAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["enum"],"readOnly":true},"filters":{"type":"array","items":{"$ref":"#/components/schemas/Filter"}}},"required":["field","name","type"],"additionalProperties":false},"TagsAttribute":{"type":"object","properties":{"name":{"type":"string"},"field":{"type":"string"},"type":{"type":"string","enum":["tags"],"readOnly":true},"tags":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["field","name","type"],"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Aggregated covered-resources summary for a commitment plan

> Returns the resources a commitment plan covers, aggregated by (service, account, region, resource\_type). Each row is one group: rolled-up costs, savings, mean coverage, and resource count. Sorted by net savings descending. For per-resource detail, use the paginated /covered-resources endpoint.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/covered-resources/summary":{"get":{"parameters":[{"in":"query","name":"line_item_ids","description":"Filter to matches from specific line items","schema":{"type":"array","default":null,"items":{"type":"string","format":"uuid"},"nullable":true},"required":false,"explode":true,"style":"form"},{"in":"query","name":"only_selected_line_items","description":"Only include matches from selected line items (default true)","schema":{"type":"boolean","default":true},"required":false}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ResourceMatchSummary"}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"Aggregated covered-resources summary for a commitment plan","description":"Returns the resources a commitment plan covers, aggregated by (service, account, region, resource_type). Each row is one group: rolled-up costs, savings, mean coverage, and resource count. Sorted by net savings descending. For per-resource detail, use the paginated /covered-resources endpoint."}}},"components":{"schemas":{"ResourceMatchSummary":{"type":"object","properties":{"service":{"type":"string","description":"Cloud service name (e.g. 'AmazonEC2', 'AmazonRDS')","nullable":true},"account_id":{"type":"string","description":"Cloud account ID","nullable":true},"region":{"type":"string","description":"Cloud region (e.g. 'us-east-1')","nullable":true},"resource_type":{"type":"string","description":"Resource type within this group — instance family for compute (e.g. 'm5'), usage type for other services (e.g. 'Fargate-GB-Hours', 'Lambda-GB-Second'), or SKU name as fallback","nullable":true},"resource_count":{"type":"integer","description":"Number of resources in this group"},"projected_coverage":{"type":"number","description":"Mean projected coverage across resources in this group (0-1) — the fraction of each resource's usage THIS plan would cover, averaged. Post-plan / projected: distinct from `resource.coverage` (the trailing-30-day actual coverage from existing commitments). For per-resource projected coverage, use the paginated /covered-resources endpoint."},"commitment_financials_monthly_rate":{"description":"Plan economics scoped to this resource group, as 730-hour monthly rates. cloud_provider_cost has `{total}` only — per-group aggregates don't have the recurring/amortized_upfront split. commitment_savings has no rebate field on plans.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]}},"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```

## Paginated covered resources for a commitment plan

> Returns one row per resource the plan covers, with the plan's economics scoped to that resource (coverage, monthly savings, before/after cost) and full ResourceSKU detail. Supports search, structured filter, sort, and cursor pagination — same surface idiom as /resources/skus, but scoped to the plan's matched resources. Use /covered-resources/summary for the aggregated breakdown.

```json
{"openapi":"3.0.2","info":{"title":"Archera.ai Beta API","version":"v1.0.0"},"tags":[{"name":"Commitment Plans (Beta)","description":"Agent-friendly commitment plan endpoints"}],"paths":{"/beta/v1/org/{org_id}/commitment-plans/{plan_id}/covered-resources":{"get":{"parameters":[{"in":"query","name":"line_item_ids","description":"Filter to matches from specific line items","schema":{"type":"array","default":null,"items":{"type":"string","format":"uuid"},"nullable":true},"required":false,"explode":true,"style":"form"},{"in":"query","name":"only_selected_line_items","description":"Only include matches from selected line items (default true)","schema":{"type":"boolean","default":true},"required":false},{"in":"query","name":"search","description":"Free-text ILIKE search across the resource SKU's identity and classification fields (resource id, name, account ids, service, region, instance_type, etc.). Mirrors the search lane on /resources/skus.","schema":{"type":"string","default":null,"nullable":true},"required":false},{"in":"query","name":"filter","description":"JSON filter object — same {field, op, value} tree accepted by /resources/skus. Filterable on the resource SKU side: identity, tags (`has` with nested key/value filters), SKU classification, and the trailing-30-day spend/usage aggregates: `total_cost`, `ondemand_cost`, `gross_savings` (TOTAL summed over the trailing 30 days, NOT a monthly rate — same basis as /resources/skus), `coverage` (fraction of usage covered by ALL existing commitments — current actuals, NOT this plan's projected coverage; that's the response's per-match `projected_coverage`), and `uptime` (fraction). All warehouse aggregates here are actuals across existing commitments, NOT plan-scoped projections. Call /covered-resources/attributes for the full filterable surface.","schema":{"type":"object","default":null,"additionalProperties":{},"nullable":true},"required":false},{"in":"query","name":"order_by","description":"Field to order results by. Defaults to monthly_net_savings. All numeric axes are 730-hour monthly rates on the per-match plan economics, net of the Archera premium where applicable (NOT the resource's warehouse trailing-30-day actuals — those are filterable but not orderable here, on purpose, to keep sort and response framing on the same monthly basis).","schema":{"type":"string","default":"monthly_net_savings","enum":["id","projected_coverage","monthly_net_savings","monthly_before_cost","monthly_after_cost","monthly_after_ondemand_cost"]},"required":false},{"in":"query","name":"desc","description":"Sort descending (default true)","schema":{"type":"boolean","default":true},"required":false},{"in":"query","name":"page","schema":{"type":"integer","default":1,"minimum":1},"required":false},{"in":"query","name":"page_size","schema":{"type":"integer","default":20,"minimum":1,"maximum":100},"required":false}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ResourceMatchDetail"}}}},"headers":{"X-Pagination":{"$ref":"#/components/headers/PAGINATION"}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"405":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"422":{"$ref":"#/components/responses/UNPROCESSABLE_CONTENT"},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"default":{"$ref":"#/components/responses/DEFAULT_ERROR"}},"tags":["Commitment Plans (Beta)"],"summary":"Paginated covered resources for a commitment plan","description":"Returns one row per resource the plan covers, with the plan's economics scoped to that resource (coverage, monthly savings, before/after cost) and full ResourceSKU detail. Supports search, structured filter, sort, and cursor pagination — same surface idiom as /resources/skus, but scoped to the plan's matched resources. Use /covered-resources/summary for the aggregated breakdown."}}},"components":{"schemas":{"ResourceMatchDetail":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Match identifier — stable per (plan, line item, resource) tuple. For the resource's own id, see `resource.id`."},"line_item_id":{"type":"string","format":"uuid","description":"Parent line item ID"},"projected_coverage":{"type":"number","description":"Fraction of this resource's usage THIS plan would cover (0-1). Post-plan / projected — distinct from `resource.coverage`, which is the trailing-30-day actual coverage from existing commitments (the BEFORE picture). For the rolled-up mean across a group, see the /covered-resources/summary endpoint."},"commitment_financials_monthly_rate":{"description":"Plan economics scoped to this resource, as 730-hour monthly rates. cloud_provider_cost has `{total}` only — per-match data doesn't have the recurring/amortized_upfront split. commitment_savings has no rebate field on plans.","allOf":[{"$ref":"#/components/schemas/CommitmentFinancialsNoRebate"}]},"resource":{"description":"Detailed resource information including provider, service, region, instance type, account, and other infrastructure details","anyOf":[{"$ref":"#/components/schemas/ResourceSKU"},{"type":"object","nullable":true}]}},"required":["resource"],"additionalProperties":false},"CommitmentFinancialsNoRebate":{"type":"object","properties":{"commitment_cost":{"$ref":"#/components/schemas/CommitmentCost"},"commitment_savings":{"$ref":"#/components/schemas/CommitmentSavings_Exclude_Rebate"},"covered_ondemand_cost":{"type":"number","description":"On-demand cost of usage covered by commitments — baseline for savings. NOT a cost paid by the user. Equals commitment_cost.breakdown.cloud_provider_cost.total + commitment_savings.gross."}},"additionalProperties":false},"CommitmentCost":{"type":"object","properties":{"total":{"type":"number","description":"Total paid (cloud_provider_cost.total + archera_premium). Headline 'cost'."},"breakdown":{"$ref":"#/components/schemas/CommitmentCostBreakdown"}},"additionalProperties":false},"CommitmentCostBreakdown":{"type":"object","properties":{"cloud_provider_cost":{"$ref":"#/components/schemas/CloudProviderCost"},"archera_premium":{"type":"number","description":"Archera premium — paid to Archera, equal to a portion of the savings Archera generates for this commitment (fee_rate * gross savings, only charged when gross > 0). Already included in commitment_cost.total (don't add on top). Because premium is only a fraction of gross, whenever archera_premium > 0 the commitment is net-positive after the fee. Native (non-Archera) commitments have premium = 0 and offer no such guarantee; an underutilized guaranteed commitment pre-lockin can also show net < 0 (the rebate that covers this kicks in post-lockin)."}},"additionalProperties":false},"CloudProviderCost":{"type":"object","properties":{"total":{"type":"number","description":"Amortized cost paid to the cloud provider. Sums with archera_premium to reach cost.total."},"breakdown":{"description":"Optional. Additive payment-cadence decomposition of total (recurring + amortized_upfront). Present only when purchase-term structure is known (individual commitment or plan).","allOf":[{"$ref":"#/components/schemas/CloudProviderCostBreakdown"}]}},"additionalProperties":false},"CloudProviderCostBreakdown":{"type":"object","properties":{"recurring":{"type":"number","description":"Recurring monthly payment to the cloud provider."},"amortized_upfront":{"type":"number","description":"Monthly share of the upfront payment, amortized over the term."}},"additionalProperties":false},"CommitmentSavings_Exclude_Rebate":{"type":"object","properties":{"net":{"type":"number","description":"Net savings after Archera premium, including any rebate. Actual bill reduction. Headline 'savings'."},"gross":{"type":"number","description":"Savings before Archera premium. Equals covered_ondemand_cost - commitment_cost.breakdown.cloud_provider_cost.total."}},"additionalProperties":false},"ResourceSKU":{"type":"object","properties":{"id":{"type":"string","description":"Composite ResourceSKU id — `<resource_id>|<catalog_sku_org_id>|<catalog_sku_id>`. Pass directly to `/resources/skus/<id>` for detail; do not parse it client-side."},"resource_id":{"type":"string","format":"uuid","description":"Underlying Resource id. Stable across SKU/time variants of the same resource — multiple ResourceSKU rows can share a `resource_id` when the same resource ran with different SKUs over its lifetime."},"catalog_sku_id":{"type":"string","format":"uuid","description":"Join key into `/catalog/skus/<id>` for the public SKU record."},"catalog_sku_org_id":{"type":"string","description":"Org id that owns the catalog SKU — public-catalog SKUs use the public org id; custom-priced SKUs use the customer's org id."},"provider":{"description":"Cloud provider (aws, azure, gcp)","type":"string","enum":["aws","azure","gcp","kubernetes","unknown"]},"provider_resource_id":{"type":"string","description":"Provider's id for the resource (AWS ARN, Azure resource ID, GCP resource name). This is the canonical identifier the user sees in the cloud console."},"provider_sku_id":{"type":"string","description":"Provider's own SKU identifier","nullable":true},"name":{"type":"string","description":"Resource name (Resource.name) — the user-applied label, e.g. 'prod-db-1'. Distinct from `sku_name`, which is the catalog SKU's display name.","nullable":true},"sku_name":{"type":"string","description":"Catalog SKU display name (e.g. 'Amazon EC2 Instance', 'Amazon Aurora PostgreSQL Cluster'). Useful as a fallback label when `instance_type_family` and `usage_type` are both null. Distinct from `name` (the resource's user-applied label).","nullable":true},"integration_id":{"type":"string","description":"Integration this resource belongs to"},"billing_account_id":{"type":"string","description":"Provider billing/management account id","nullable":true},"sub_account_id":{"type":"string","description":"Provider account id that owns/created the resource","nullable":true},"resource_group":{"type":"string","nullable":true},"is_spot":{"type":"boolean","nullable":true},"availability_zone":{"type":"string","nullable":true},"service":{"type":"string","description":"Full service name (e.g. 'Amazon Elastic Compute Cloud - Compute')","nullable":true},"provider_service":{"type":"string","description":"Provider service code (e.g. 'AmazonEC2')","nullable":true},"family":{"type":"string","description":"Product family (e.g. 'Compute Instance')","nullable":true},"region_code":{"type":"string","description":"Region code (e.g. 'us-east-1')","nullable":true},"full_region_name":{"type":"string","description":"Full region name (e.g. 'US East (N. Virginia)')","nullable":true},"instance_type":{"type":"string","nullable":true},"instance_type_family":{"type":"string","nullable":true},"usage_type":{"type":"string","description":"Provider billing usage type (e.g. 'BoxUsage:m5.large'). The canonical join key against AWS Cost Explorer / billing line items.","nullable":true},"operation":{"type":"string","description":"Provider billing operation code (e.g. 'RunInstances:0002')","nullable":true},"operating_system":{"type":"string","nullable":true},"tenancy":{"type":"string","nullable":true},"database_engine":{"type":"string","nullable":true},"database_edition":{"type":"string","nullable":true},"cache_engine":{"type":"string","nullable":true},"is_multi_az":{"type":"boolean","nullable":true},"is_current_generation":{"type":"boolean","nullable":true},"license_model":{"type":"string","nullable":true},"pre_installed_sw":{"type":"string","nullable":true},"processor_architecture":{"type":"string","nullable":true},"is_reservable":{"type":"boolean","description":"Whether the SKU this resource is running has at least one reserved-term offering. Reservability is a property of the SKU, not the resource.","nullable":true},"is_byol":{"type":"boolean","description":"Whether the SKU is a Bring-Your-Own-License variant. Currently set for AWS RDS BYOL only; false elsewhere.","nullable":true},"is_flexible":{"type":"boolean","description":"Whether the SKU is eligible for instance-size flexibility under reserved offerings (provider+service-specific rules — see `is_flexible` on the ResourceSKU model).","nullable":true},"is_serverless":{"type":"boolean","description":"Whether the SKU represents serverless usage.","nullable":true},"vcpu":{"type":"number","nullable":true},"memory":{"type":"number","description":"Memory in bytes (not GB). Divide by 2**30 for GiB / 1e9 for GB if presenting to the user.","nullable":true},"ondemand_usage_unit":{"type":"string","nullable":true},"ondemand_usage_price":{"type":"number","description":"On-demand unit price in `price_currency`. List price from the catalog — this is NOT the user's actual spend for this resource (see ResourceSKUWithMetricsSchema's `total_cost` or /cost-explorer for that).","nullable":true},"price_currency":{"type":"string","nullable":true},"usage_start":{"type":"string","format":"date-time","description":"Start of the period during which the resource was observed running this SKU. A resource that switched SKUs (e.g. instance-type resize) will have multiple ResourceSKU rows with disjoint `[usage_start, usage_end]` windows."},"usage_end":{"type":"string","format":"date-time","description":"End of the period during which the resource was observed running this SKU. Within ~2 days of now generally indicates the resource is currently active with this SKU."},"tags":{"type":"object","description":"Merged provider + user tags (user tags take precedence). Empty when the resource has no tags. Use the `untagged` filter to find resources with no tags at all.","additionalProperties":{"type":"string"},"nullable":true}},"additionalProperties":false},"PaginationMetadata":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of items."},"total_pages":{"type":"integer","description":"Total number of pages."},"first_page":{"type":"integer","description":"First available page number."},"last_page":{"type":"integer","description":"Last available page number."},"page":{"type":"integer","description":"Current page number."},"previous_page":{"type":"integer","description":"Previous page number."},"next_page":{"type":"integer","description":"Next page number."}},"additionalProperties":false},"ApiErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"detail":{"nullable":true},"code":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"timestamp":{"type":"string"},"type":{"type":"string"}},"required":["message","timestamp","type"]},"Error":{"type":"object","properties":{"code":{"type":"integer","description":"Error code"},"status":{"type":"string","description":"Error name"},"message":{"type":"string","description":"Error message"},"errors":{"type":"object","description":"Errors","additionalProperties":{}}},"additionalProperties":false}},"headers":{"PAGINATION":{"description":"Pagination metadata","schema":{"$ref":"#/components/schemas/PaginationMetadata"}}},"responses":{"UNPROCESSABLE_CONTENT":{"description":"Unprocessable Content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DEFAULT_ERROR":{"description":"Default error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.archera.ai/api-reference/beta-api/commitment-plans-beta.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
