Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Confighub Demote API
version: 0.1.0
contact:
name: ConfigHub Support
url: https://confighub.com/
email: hello@confighub.com
license:
name: N/A
url: https://confighub.com/TBD
termsOfService: TBD
description: 'Operations tagged Demote across 2 of this provider''s published API definitions: openapi.json, confighub-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://hub.confighub.com/api
description: production
security:
- bearerAuth: []
tags:
- name: Demote
paths:
/demote:
post:
tags:
- Demote
summary: Undo an aborted ChangeOrder in the Spaces it reached
description: Restores each Unit the ChangeOrder's start Tag marks to the Revision it was at before the change, in every Space the ChangeOrder reached, or those WhereSpace, SpaceFilterID and TargetStage select. The ChangeOrder must have an AbortedReason. A Unit already restored is passed over, and a Unit the ChangeOrder carried nothing for is marked without a Revision being made. Revisions made after the change that restoring drops are reported. Demoting again changes nothing.
operationId: Demote
parameters:
- name: dry_run
in: query
description: Plan the demotion and return the same response without writing anything.
required: false
schema:
type: boolean
- name: include
in: query
description: 'Comma-separated parts of the result to return in addition to the actions: Mutations for what each restore changed, or on a dry run would change, as entries of its MutationSources, and Diff for the same change path by path with the values on both sides. Context, with Diff, adds to each Diff the unchanged paths around the changes: every unchanged child of each map or array that holds a change, up to the resource, as ChangeType None.
Supported values: Mutations, Diff, Context.'
required: false
schema:
pattern: ^\s*(Mutations|Diff|Context)\s*(?:,\s*(?:Mutations|Diff|Context)\s*)*$
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/DemoteRequest'
responses:
default:
description: Unexpected error.
content:
application/json:
schema:
$ref: '#/components/schemas/StandardErrorResponse'
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/DemoteResult'
'207':
description: 'Multi-Status: some Unit writes failed, each carrying its own error'
content:
application/json:
schema:
$ref: '#/components/schemas/DemoteResult'
'400':
description: Demote request is invalid (Bad Request).
content:
application/json:
schema:
$ref: '#/components/schemas/StandardErrorResponse'
'401':
description: Unauthorized access.
content:
application/json:
schema:
$ref: '#/components/schemas/StandardErrorResponse'
'403':
description: Forbidden access.
content:
application/json:
schema:
$ref: '#/components/schemas/StandardErrorResponse'
'404':
description: Demote not found.
content:
application/json:
schema:
$ref: '#/components/schemas/StandardErrorResponse'
'409':
description: Demote data conflict. Data has changed since last read.
content:
application/json:
schema:
$ref: '#/components/schemas/StandardErrorResponse'
'412':
description: The plan differs from ExpectedPlan. Nothing was written.
content:
application/json:
schema:
$ref: '#/components/schemas/StandardErrorResponse'
'500':
description: Something went wrong while processing Demote.
content:
application/json:
schema:
$ref: '#/components/schemas/StandardErrorResponse'
servers:
- url: https://hub.confighub.com/api
description: production
components:
schemas:
ArrayElementAliasMap:
type: object
additionalProperties:
type: object
additionalProperties:
type: string
DemoteResult:
type: object
properties:
ChangeOrderID:
type: string
format: uuid
example: 248df4b7-aa70-47b8-a036-33ac447e668d
x-go-type-skip-optional-pointer: true
x-omitzero: true
DryRun:
type: boolean
description: True when nothing was written.
x-go-type-skip-optional-pointer: true
Plan:
type: string
description: Digest of the planned actions. Send it as ExpectedPlan to apply exactly this plan.
x-go-type-skip-optional-pointer: true
Spaces:
type: array
items:
$ref: '#/components/schemas/DemoteSpaceResult'
description: Downstream Spaces first.
x-go-type-skip-optional-pointer: true
MutationInfo:
type: object
properties:
Index:
type: integer
description: Function index or sequence number corresponding to the change
format: int64
x-go-type-skip-optional-pointer: true
MutationType:
allOf:
- $ref: '#/components/schemas/MutationType'
description: 'Type of mutation performed on the associated configuration element: Add, Update, Replace, Delete, or None, if no change'
Patch:
type: string
description: Line-level patch for multi-line string updates, in unified diff format. When present on an Update, PatchMutations applies this to the target value instead of replacing with Value. Falls back to Value if the patch cannot be applied cleanly.
x-go-type-skip-optional-pointer: true
Protected:
type: boolean
description: True if this is a local override a merge must not overwrite; false if the value came from elsewhere and may be overwritten
x-go-type-skip-optional-pointer: true
Value:
type: string
description: Removed configuration data if MutationType is Delete and otherwise the new data
x-go-type-skip-optional-pointer: true
ConfigDiff:
type: object
properties:
Resources:
type:
- array
- 'null'
items:
$ref: '#/components/schemas/ResourceDiff'
description: One entry per resource that differs, in the To configuration's order; resources only on the From side follow where they were
x-go-type-skip-optional-pointer: true
ArrayOrderMap:
type: object
additionalProperties:
type: array
items:
type: string
ErrorItem:
type: object
properties:
Description:
type: string
description: A clear explanation of what went wrong
x-go-type-skip-optional-pointer: true
Item:
type: string
description: The name of the field, resource, or entity that the error relates to
x-go-type-skip-optional-pointer: true
ResponseError:
type: object
properties:
Details:
type: array
items:
type: string
description: Additional context messages
x-go-type-skip-optional-pointer: true
ErrorMetadata:
allOf:
- $ref: '#/components/schemas/ErrorMetadata'
description: Structured error details like field violations
Message:
type: string
description: The primary error message
x-go-type-skip-optional-pointer: true
Status:
type: integer
description: HTTP status code
x-go-type-skip-optional-pointer: true
Type:
type: string
description: 'The category of the error, as a code: UserInput, Validation, Data, Authentication, Permission, NotFound, Conflict, AlreadyExists, Unprocessable, Locked, PreconditionFailed, TooManyRequests, Unexpected, GatewayTimeout, or ServiceUnavailable'
x-go-type-skip-optional-pointer: true
StandardErrorResponse:
type: object
properties:
Error:
allOf:
- $ref: '#/components/schemas/ResponseError'
description: 'The error: its message, category (Type), HTTP status, details, and structured items.'
message:
type: string
description: 'The error as one string: its message, with any details, items, and individual errors appended. Kept for clients written before Error; new clients read Error.'
x-go-type-skip-optional-pointer: true
description: 'The body of an error response: the error as data (Error), and as one string (message) for clients written before Error.'
ResourceInfo:
type: object
properties:
ResourceCategory:
type: string
description: Category of configuration element represented in the configuration data; Kubernetes resources are of category Resource, and application configuration files are of category AppConfig
x-go-type-skip-optional-pointer: true
ResourceName:
type: string
description: Name of a resource in the system under management represented in the configuration data; Kubernetes resources are represented in the form <metadata.namespace>/<metadata.name>; not all ToolchainTypes necessarily use '/' as a separator between any scope(s) and name or other client-chosen ID
x-go-type-skip-optional-pointer: true
ResourceNameStableCore:
type: string
description: Name of a resource in the system under management represented in the configuration data with generated prefixes and suffixes stripped; empty if nothing to strip
x-go-type-skip-optional-pointer: true
ResourceNameWithoutScope:
type: string
description: Name of a resource in the system under management represented in the configuration data, without any uniquifying scope, such as Namespace, Project, Account, Region, etc.; Kubernetes resources are represented in the form <metadata.name>
x-go-type-skip-optional-pointer: true
ResourceType:
type: string
description: Type of a resource in the system under management represented in the configuration data; Kubernetes resources are represented in the form <apiVersion>/<kind> (aka group-version-kind)
x-go-type-skip-optional-pointer: true
ErrorMetadata:
type: object
properties:
EntityID:
type: string
description: Optional ID of the entity this error relates to
x-go-type-skip-optional-pointer: true
EntitySlug:
type: string
description: Optional slug of the entity this error relates to
x-go-type-skip-optional-pointer: true
EntityType:
type: string
description: Optional type of the entity this error relates to
x-go-type-skip-optional-pointer: true
Items:
type: array
items:
$ref: '#/components/schemas/ErrorItem'
description: Collection of error details
x-go-type-skip-optional-pointer: true
DemoteRequest:
required:
- ChangeOrderID
type: object
properties:
ChangeDescription:
type: string
description: Recorded on each restored Revision. Defaults to naming the ChangeOrder undone.
x-go-type-skip-optional-pointer: true
ChangeOrderID:
type: string
description: The ChangeOrder to undo. It must have an AbortedReason. Which Units are restored is the Units its start Tag marks.
format: uuid
example: 248df4b7-aa70-47b8-a036-33ac447e668d
x-go-type-skip-optional-pointer: true
x-omitzero: true
ChangeSetID:
type: string
description: An existing open ChangeSet to record every write in.
format: uuid
example: 248df4b7-aa70-47b8-a036-33ac447e668d
ExpectedPlan:
type: string
description: The Plan a previous dry run returned. If the plan now differs, nothing is written and the request fails with 412.
x-go-type-skip-optional-pointer: true
SpaceFilterID:
type: string
description: A Filter over Spaces narrowing the Spaces to demote.
format: uuid
example: 248df4b7-aa70-47b8-a036-33ac447e668d
TargetStage:
type: string
description: A Stage of the ChangeOrder's ChangeWorkflow whose Spaces to demote.
x-go-type-skip-optional-pointer: true
WhereSpace:
type: string
description: A where expression narrowing the Spaces to demote. Without any selector, every Space the ChangeOrder marked is demoted.
x-go-type-skip-optional-pointer: true
MutationType:
enum:
- Add
- Delete
- Update
- Replace
- None
type: string
PathSegment:
required:
- FromIndex
- ToIndex
type: object
properties:
Field:
type: string
description: The map key, for a map segment
x-go-type-skip-optional-pointer: true
FromIndex:
type: integer
description: The element's index on the From side; -1 for a map key or an element absent there
x-go-type-skip-optional-pointer: true
MergeKeys:
type: array
items:
$ref: '#/components/schemas/MergeKeyValue'
description: The merge keys that identify the element, for an element of a merge-keyed array
x-go-type-skip-optional-pointer: true
ToIndex:
type: integer
description: The element's index on the To side; -1 for a map key or an element absent there
x-go-type-skip-optional-pointer: true
ResourceDiff:
type: object
properties:
Attribution:
allOf:
- $ref: '#/components/schemas/MutationInfo'
description: For an Add, the To side's MutationSources entry for the resource, which says what added it; returned when include names Attribution
ChangeType:
allOf:
- $ref: '#/components/schemas/MutationType'
description: Add, Delete, Update, or None when the resource is unchanged
Changes:
type: array
items:
$ref: '#/components/schemas/PathChange'
description: Changes within the resource, for an Update, in document order
x-go-type-skip-optional-pointer: true
FromValue:
type: string
description: The whole resource, for a Delete
x-go-type-skip-optional-pointer: true
PreviousResource:
allOf:
- $ref: '#/components/schemas/ResourceInfo'
description: The resource on the From side, when it was matched across a rename
Resource:
allOf:
- $ref: '#/components/schemas/ResourceInfo'
description: Identifies the resource on the To side, or on the From side if it was deleted
ToValue:
type: string
description: The whole resource, for an Add
x-go-type-skip-optional-pointer: true
MutationMap:
type: object
additionalProperties:
$ref: '#/components/schemas/MutationInfo'
PathChange:
type: object
properties:
Attribution:
allOf:
- $ref: '#/components/schemas/MutationInfo'
description: The To side's MutationSources entry for this path, which says what set the new value; returned when include names Attribution
ChangeType:
type: string
description: Add, Delete, Update, Replace, Reorder, or Rename; or None for an unchanged path returned as context
x-go-type-skip-optional-pointer: true
Comment:
type: string
description: 'Head, Line, or Foot when the change is to a comment on the node at the path rather than to its value: the comment above the node, at the end of its line, or below it. The path of a comment on a whole resource is empty'
x-go-type-skip-optional-pointer: true
DisplayPath:
type: string
description: The path in configuration path syntax, as --path arguments and where filters take it, with each unkeyed array element named by its index
x-go-type-skip-optional-pointer: true
FromDataType:
type: string
description: 'How to read FromValue: string, int, or bool for a scalar, YAML for a map or array, and empty for a scalar of another type, such as a float or null, or when the From side has no value'
x-go-type-skip-optional-pointer: true
FromValue:
type: string
description: 'The value on the From side: a scalar''s text, or a YAML block for a map or array'
x-go-type-skip-optional-pointer: true
Patch:
type: string
description: A unified line diff, for multi-line string values
x-go-type-skip-optional-pointer: true
Path:
type: string
description: The path as MutationSources and patch functions record it
x-go-type-skip-optional-pointer: true
Segments:
type:
- array
- 'null'
items:
$ref: '#/components/schemas/PathSegment'
description: The path split into its segments, for rendering without parsing the path syntax
x-go-type-skip-optional-pointer: true
ToDataType:
type: string
description: 'How to read ToValue: string, int, or bool for a scalar, YAML for a map or array, and empty for a scalar of another type, such as a float or null, or when the To side has no value'
x-go-type-skip-optional-pointer: true
ToValue:
type: string
description: 'The value on the To side: a scalar''s text, or a YAML block for a map or array. For an unchanged path, the value on both sides'
x-go-type-skip-optional-pointer: true
ResourceMutationList:
type: array
items:
$ref: '#/components/schemas/ResourceMutation'
MergeKeyValue:
type: object
properties:
Key:
type: string
x-go-type-skip-optional-pointer: true
Value:
type: string
x-go-type-skip-optional-pointer: true
ResourceMutation:
type: object
properties:
Aliases:
type: object
additionalProperties:
type: object
description: Names (with scopes, if any) used in current and prior revisions of this resource
x-go-type-skip-optional-pointer: true
AliasesWithoutScopes:
type: object
additionalProperties:
type: object
description: Names without scopes used in current and prior revisions of this resource
x-go-type-skip-optional-pointer: true
ArrayElementAliases:
allOf:
- $ref: '#/components/schemas/ArrayElementAliasMap'
description: 'For merge-keyed arrays in which an element was renamed (its merge-key value changed): the array parent path mapped to a previous-merge-key -> new-merge-key map. PatchMutations rewrites the matched element''s merge-key field accordingly so child paths and ArrayOrders entries resolve under the new key.'
ArrayOrders:
allOf:
- $ref: '#/components/schemas/ArrayOrderMap'
description: 'For merge-keyed arrays whose element set or order changed in this mutation: the desired sequence of merge-key values in source order, keyed by the array''s parent path. PatchMutations applies this as a reorder pass after path mutations so positional associative arrays (e.g., Kubernetes initContainers, env, ports) preserve source-side ordering rather than landing append-on-clash.'
PathMutationMap:
allOf:
- $ref: '#/components/schemas/MutationMap'
description: Path-level mutation information; more deeply nested paths override values represented at higher levels
Resource:
allOf:
- $ref: '#/components/schemas/ResourceInfo'
description: Identifiers of the resource to which the mutations correspond
ResourceMutationInfo:
allOf:
- $ref: '#/components/schemas/MutationInfo'
description: Resource-level mutation information, such as for Add, Delete, or Replace
DemoteSpaceResult:
type: object
properties:
Action:
type: string
description: Demote, Unchanged, Skipped, or Failed.
x-go-type-skip-optional-pointer: true
Error:
$ref: '#/components/schemas/ResponseError'
Reason:
type: string
description: 'For Skipped: NotMarked, when the change order marks no Unit of the Space.'
x-go-type-skip-optional-pointer: true
SpaceID:
type: string
format: uuid
example: 248df4b7-aa70-47b8-a036-33ac447e668d
x-go-type-skip-optional-pointer: true
x-omitzero: true
SpaceSlug:
type: string
x-go-type-skip-optional-pointer: true
Stage:
type: string
x-go-type-skip-optional-pointer: true
Units:
type: array
items:
$ref: '#/components/schemas/DemoteUnitResult'
description: The Units the ChangeOrder's start Tag marks in the Space.
x-go-type-skip-optional-pointer: true
DemoteUnitResult:
type: object
properties:
Action:
type: string
description: Restore, Mark, or Unchanged.
x-go-type-skip-optional-pointer: true
Diff:
allOf:
- $ref: '#/components/schemas/ConfigDiff'
description: The same change path by path, with the values on both sides. Returned when include names Diff.
DropsFromRevisionNum:
type: integer
description: The first Revision after the change that restoring drops, when the head had moved past where the change arrived.
format: int64
x-go-type-skip-optional-pointer: true
DropsToRevisionNum:
type: integer
description: The last Revision that restoring drops.
format: int64
x-go-type-skip-optional-pointer: true
EndRevisionNum:
type: integer
description: The Revision the change arrived at.
format: int64
x-go-type-skip-optional-pointer: true
Error:
$ref: '#/components/schemas/ResponseError'
Mutations:
allOf:
- $ref: '#/components/schemas/ResourceMutationList'
description: What the restore changed, or on a dry run would change. Returned when include names Mutations.
PreviousHeadMutationNum:
type: integer
format: int64
x-go-type-skip-optional-pointer: true
PreviousHeadRevisionNum:
type: integer
format: int64
x-go-type-skip-optional-pointer: true
Reason:
type: string
description: 'For Unchanged: AlreadyRestored.'
x-go-type-skip-optional-pointer: true
Slug:
type: string
x-go-type-skip-optional-pointer: true
StartRevisionNum:
type: integer
description: The Revision the change started from, which the Unit is restored to.
format: int64
x-go-type-skip-optional-pointer: true
UnitID:
type: string
format: uuid
example: 248df4b7-aa70-47b8-a036-33ac447e668d
x-go-type-skip-optional-pointer: true
x-omitzero: true
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: Bearer authentication
x-refined-from:
- openapi.json
- confighub-openapi.json