Changes
Propose a change for review
Propose a change to an authorized event and get back a reviewable plan: a title, a labeled before and after for every field that moves, what applying it would affect, and reviewUrl, the full link where a person approves it. Use this for any change no dedicated tool covers (speakers and panelists, FAQ, links, pages, schedule items, lottery settings, runner requirements, registration questions, add-ons, volunteer roles, automations and more): find the procedure path with capability discovery and pass that procedure's own input. For a whole registration ruleset described in prose, ehq_registration_rules_propose files one plan for every section instead. Nothing is saved by this call. Show the user the before and after values; once they want it made, call ehq_changes_apply with the planId. If apply returns APPROVAL_REQUIRED and the user explicitly approves the reviewed plan here, inspect it and use ehq_changes_approve when this personal OAuth connection has changes:approve. Otherwise use its reviewUrl. Send an Idempotency-Key header.
Method
POST
Path
/v1/changes/prepare
Required scope
changes:proposeRequest
curl -X POST "https://api.endurancehq.app/v1/changes/prepare" \
-H "Authorization: Bearer $EHQ_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON body schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"path": {
"type": "string",
"minLength": 1,
"maxLength": 300,
"description": "Procedure path of the change to propose, for example raceDay.createScheduleItem or speakers.update. Use capability discovery to find the exact path."
},
"input": {
"description": "The change's own input, validated against that procedure's schema before any plan is written.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"eventId": {
"description": "Which event this change belongs to. Always pass it when the input addresses a record by id (a speaker, schedule item or FAQ): without it the plan has no before-and-after and always waits for review. Access is still decided by the user's own permissions.",
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"required": [
"path"
],
"additionalProperties": false
}Response
Success status: 201
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"planId": {
"type": "string"
},
"title": {
"type": "string"
},
"summary": {
"type": "string"
},
"risk": {
"type": "string",
"enum": [
"low",
"medium",
"high"
]
},
"fidelity": {
"type": "string",
"enum": [
"kind_module",
"raw_input"
]
},
"diff": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": [
"string",
"null"
]
},
"label": {
"type": "string"
},
"before": {},
"after": {},
"beforeText": {
"type": [
"string",
"null"
]
},
"afterText": {
"type": [
"string",
"null"
]
}
},
"required": [
"field",
"label",
"before",
"after",
"beforeText",
"afterText"
],
"additionalProperties": false
}
},
"effects": {
"type": "array",
"items": {
"type": "string"
}
},
"reviewHref": {
"type": "string"
},
"reviewUrl": {
"type": "string"
},
"expiresAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"planId",
"title",
"summary",
"risk",
"fidelity",
"diff",
"effects",
"reviewHref",
"reviewUrl",
"expiresAt"
],
"additionalProperties": false
}
},
"required": [
"data"
],
"additionalProperties": false
}Other surfaces
CLI: ehq changes propose <procedure_path> --input <json> [--event <event_id>]
MCP tool: ehq_changes_propose