{
  "openapi": "3.0.3",
  "info": {
    "title": "Flowplane API",
    "description": "Flowplane workflow orchestration control plane API",
    "version": "1.0.0"
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT or API Key"
      }
    },
    "schemas": {}
  },
  "paths": {
    "/health": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/webhooks/clerk": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/webhooks/stripe": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/surfaces/email/act": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/surfaces/slack/interactivity": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/surfaces/slack/events": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/surfaces/discord/interactions": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/surfaces/docusign/connect": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/discord/callback": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/slack/callback": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/worker/register": {
      "post": {
        "summary": "Register (upsert) a workflow definition",
        "tags": [
          "Worker"
        ],
        "description": "SDK/worker self-registration. Idempotent upsert keyed by workflow id for the API key’s org.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "name": {
                    "type": "string"
                  },
                  "version": {
                    "type": "integer",
                    "exclusiveMinimum": true,
                    "minimum": 0,
                    "default": 1
                  },
                  "engine": {
                    "type": "string",
                    "enum": [
                      "bundled",
                      "inngest",
                      "temporal",
                      "trigger"
                    ],
                    "default": "inngest"
                  },
                  "steps": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "minLength": 1
                        },
                        "dependsOn": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "retryPolicy": {
                          "type": "object",
                          "properties": {
                            "maxAttempts": {
                              "type": "integer",
                              "exclusiveMinimum": true,
                              "minimum": 0
                            },
                            "backoff": {
                              "type": "string",
                              "enum": [
                                "fixed",
                                "exponential"
                              ]
                            },
                            "initialDelayMs": {
                              "type": "integer",
                              "exclusiveMinimum": true,
                              "minimum": 0
                            }
                          },
                          "required": [
                            "maxAttempts",
                            "backoff",
                            "initialDelayMs"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "id",
                  "steps"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/worker/decisions": {
      "post": {
        "summary": "Open a HITL decision (decision-first model)",
        "tags": [
          "Worker"
        ],
        "description": "Called by an engine adapter (e.g. flowplane.awaitApproval) to request a human decision for an external-engine run. The policy gate may resolve \"not required\", in which case approvalNeeded=false and no decision is created.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "engine": {
                    "type": "string",
                    "enum": [
                      "bundled",
                      "inngest",
                      "temporal",
                      "trigger",
                      "mcp",
                      "api"
                    ],
                    "default": "inngest"
                  },
                  "externalRunId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "stepRef": {
                    "type": "string",
                    "minLength": 1
                  },
                  "workflowRef": {
                    "type": "string"
                  },
                  "assigneeEmail": {
                    "type": "string",
                    "format": "email"
                  },
                  "policy": {
                    "type": "string"
                  },
                  "required": {
                    "type": "boolean"
                  },
                  "context": {
                    "type": "object",
                    "properties": {
                      "title": {
                        "type": "string",
                        "maxLength": 200,
                        "nullable": true
                      },
                      "prompt": {
                        "type": "string",
                        "maxLength": 4000,
                        "nullable": true
                      },
                      "aiReasoning": {
                        "type": "string",
                        "maxLength": 8000,
                        "nullable": true
                      },
                      "blocks": {
                        "type": "array",
                        "items": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "text"
                                  ]
                                },
                                "title": {
                                  "type": "string"
                                },
                                "text": {
                                  "type": "string",
                                  "maxLength": 8000
                                }
                              },
                              "required": [
                                "kind",
                                "text"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "fields"
                                  ]
                                },
                                "title": {
                                  "type": "string"
                                },
                                "fields": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "label": {
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": "string",
                                        "maxLength": 2000
                                      }
                                    },
                                    "required": [
                                      "label",
                                      "value"
                                    ],
                                    "additionalProperties": false
                                  }
                                }
                              },
                              "required": [
                                "kind",
                                "fields"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "tool_call"
                                  ]
                                },
                                "title": {
                                  "type": "string"
                                },
                                "tool": {
                                  "type": "string"
                                },
                                "args": {
                                  "type": "object",
                                  "additionalProperties": {}
                                }
                              },
                              "required": [
                                "kind",
                                "tool",
                                "args"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "diff"
                                  ]
                                },
                                "title": {
                                  "type": "string"
                                },
                                "before": {
                                  "type": "string",
                                  "maxLength": 8000
                                },
                                "after": {
                                  "type": "string",
                                  "maxLength": 8000
                                }
                              },
                              "required": [
                                "kind",
                                "before",
                                "after"
                              ],
                              "additionalProperties": false
                            },
                            {
                              "type": "object",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "ai_output"
                                  ]
                                },
                                "title": {
                                  "type": "string"
                                },
                                "model": {
                                  "type": "string"
                                },
                                "prompt": {
                                  "type": "string",
                                  "maxLength": 8000
                                },
                                "output": {
                                  "type": "string",
                                  "maxLength": 8000
                                },
                                "costUsd": {
                                  "type": "number"
                                },
                                "tokens": {
                                  "type": "number"
                                }
                              },
                              "required": [
                                "kind",
                                "output"
                              ],
                              "additionalProperties": false
                            }
                          ]
                        }
                      },
                      "payload": {
                        "type": "object",
                        "additionalProperties": {},
                        "nullable": true
                      },
                      "sourceUrl": {
                        "type": "string",
                        "nullable": true
                      },
                      "extra": {
                        "type": "object",
                        "additionalProperties": {}
                      }
                    },
                    "additionalProperties": false
                  },
                  "proposedOutput": {
                    "type": "object",
                    "properties": {
                      "title": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "format": {
                        "type": "string",
                        "enum": [
                          "text",
                          "markdown"
                        ]
                      },
                      "content": {
                        "type": "string",
                        "maxLength": 50000
                      }
                    },
                    "required": [
                      "content"
                    ],
                    "additionalProperties": false
                  },
                  "responseSpec": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "approval"
                            ]
                          }
                        },
                        "required": [
                          "type"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "select"
                            ]
                          },
                          "options": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 100
                                },
                                "label": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "description": {
                                  "type": "string",
                                  "maxLength": 500
                                }
                              },
                              "required": [
                                "id",
                                "label"
                              ],
                              "additionalProperties": false
                            },
                            "minItems": 2,
                            "maxItems": 20
                          },
                          "min": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "max": {
                            "type": "integer",
                            "exclusiveMinimum": true,
                            "minimum": 0
                          }
                        },
                        "required": [
                          "type",
                          "options"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "text"
                            ]
                          },
                          "multiline": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "type"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  },
                  "docusign": {
                    "type": "object",
                    "properties": {
                      "envelopeId": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      "accountId": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "documentUrl": {
                        "type": "string",
                        "format": "uri",
                        "maxLength": 2000
                      }
                    },
                    "required": [
                      "envelopeId"
                    ],
                    "additionalProperties": false
                  },
                  "timeoutSec": {
                    "type": "integer",
                    "exclusiveMinimum": true,
                    "minimum": 0
                  },
                  "exclusive": {
                    "type": "boolean"
                  },
                  "factsHash": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{64}$"
                  }
                },
                "required": [
                  "externalRunId",
                  "stepRef"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "approvalNeeded": {
                      "type": "boolean"
                    },
                    "decisionId": {
                      "type": "string"
                    },
                    "reason": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "approvalNeeded"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "201": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "approvalNeeded": {
                      "type": "boolean"
                    },
                    "decisionId": {
                      "type": "string"
                    },
                    "reason": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "approvalNeeded"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "used": {
                      "type": "number"
                    },
                    "limit": {
                      "type": "number"
                    },
                    "policy": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "402": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "used": {
                      "type": "number"
                    },
                    "limit": {
                      "type": "number"
                    },
                    "policy": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "422": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "used": {
                      "type": "number"
                    },
                    "limit": {
                      "type": "number"
                    },
                    "policy": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List decisions (API-key scope): the agent's inbox",
        "tags": [
          "Worker"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "APPROVED",
                "REJECTED",
                "EXPIRED",
                "CANCELLED"
              ]
            },
            "in": "query",
            "name": "status",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": true,
              "minimum": 0,
              "maximum": 200
            },
            "in": "query",
            "name": "limit",
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/worker/decisions/{id}": {
      "get": {
        "summary": "Get a decision status (API-key scope): poll a park-and-resume verdict",
        "tags": [
          "Worker"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/worker/decisions/{id}/verify": {
      "get": {
        "summary": "Verify an approval before acting on it (API-key scope)",
        "tags": [
          "Worker"
        ],
        "description": "Read-only check that a decision authorizes an action right now: APPROVED, facts hash matches, optional workflow/step match, and not already consumed. Always returns 200 with valid and, when invalid, a reason: not_found, not_approved, facts_mismatch, workflow_mismatch, step_mismatch, or consumed. Use consume to spend the approval.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "in": "query",
            "name": "factsHash",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "workflowRef",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "stepRef",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/worker/decisions/{id}/consume": {
      "post": {
        "summary": "Consume an approval: authorize exactly one action (API-key scope)",
        "tags": [
          "Worker"
        ],
        "description": "Atomically marks an APPROVED decision as spent by one action. Succeeds once per decision; a retry with the same consumer key returns consumed=true with alreadyConsumed=true, while a different consumer is refused with reason consumed. Refused with the same reasons as verify when the approval does not authorize the action.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "factsHash": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{64}$"
                  },
                  "workflowRef": {
                    "type": "string"
                  },
                  "stepRef": {
                    "type": "string"
                  },
                  "consumer": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  }
                },
                "required": [
                  "consumer"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/worker/decisions/{id}/cancel": {
      "post": {
        "summary": "Cancel a pending decision (API-key scope)",
        "tags": [
          "Worker"
        ],
        "description": "Withdraw a decision the agent no longer needs. Only PENDING decisions cancel; an already-resolved one returns cancelled=false with its current status.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "not": {}
                  },
                  {
                    "type": "object",
                    "properties": {
                      "note": {
                        "type": "string"
                      }
                    },
                    "additionalProperties": false,
                    "nullable": true
                  }
                ]
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/worker/policies/check": {
      "post": {
        "summary": "Check that policy keys exist and can reach quorum (API-key scope)",
        "tags": [
          "Worker"
        ],
        "description": "Preflight for CI. For each key: ok, missing, or unsatisfiable (with the reason and any approvers who still need verifying). ok is true only if every key is ok.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "keys": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 200
                    },
                    "minItems": 1,
                    "maxItems": 100
                  }
                },
                "required": [
                  "keys"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/worker/policies": {
      "post": {
        "summary": "Upsert a named approval policy",
        "tags": [
          "Worker"
        ],
        "description": "Declare an org-scoped approval policy as code: who approves (assignee, approver group, quorum) and the surface. Idempotent upsert keyed by (org, key); key is the immutable slug decisions reference, name and description are editable labels. A body with only name is read as key = name.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000,
                    "nullable": true
                  },
                  "defaults": {
                    "type": "object",
                    "properties": {
                      "assigneeEmail": {
                        "type": "string",
                        "format": "email"
                      },
                      "route": {
                        "type": "object",
                        "properties": {
                          "channels": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "email",
                                "slack",
                                "discord",
                                "phone",
                                "sms",
                                "webhook"
                              ]
                            },
                            "minItems": 1
                          },
                          "strategy": {
                            "type": "string",
                            "enum": [
                              "fanout",
                              "escalate"
                            ]
                          },
                          "escalateAfterSec": {
                            "type": "integer",
                            "exclusiveMinimum": true,
                            "minimum": 0
                          }
                        },
                        "required": [
                          "channels"
                        ],
                        "additionalProperties": false
                      },
                      "surface": {
                        "type": "string",
                        "enum": [
                          "inbox",
                          "slack",
                          "discord",
                          "docusign",
                          "email",
                          "api"
                        ]
                      },
                      "approvers": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "format": "email"
                        }
                      },
                      "approvalsRequired": {
                        "type": "integer",
                        "exclusiveMinimum": true,
                        "minimum": 0
                      },
                      "rejectionsRequired": {
                        "type": "integer",
                        "exclusiveMinimum": true,
                        "minimum": 0
                      }
                    },
                    "additionalProperties": false,
                    "default": {}
                  },
                  "key": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "pattern": "^[a-z0-9]+(?:[-_.][a-z0-9]+)*$"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/runs/": {
      "post": {
        "summary": "Trigger a workflow run",
        "tags": [
          "Runs"
        ],
        "description": "Fire the external engine event for a registered workflow. Ratifia seeds no run/step rows; the engine owns execution and Ratifia tracks the decisions requested on the run.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workflowId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "input": {
                    "type": "object",
                    "additionalProperties": {}
                  },
                  "idempotencyKey": {
                    "type": "string"
                  },
                  "timeoutSec": {
                    "type": "integer",
                    "exclusiveMinimum": true,
                    "minimum": 0
                  }
                },
                "required": [
                  "workflowId"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/workflows/": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/workflows/{id}": {
      "get": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/api-keys/": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/api-keys/{id}": {
      "delete": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/api-keys/{id}/rotate": {
      "post": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/audit/": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/settings/retention": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "patch": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/settings/llm": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "put": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/settings/docusign": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "put": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/discord": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/discord/channels": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/discord/channel": {
      "put": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/discord/test": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/slack": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/slack/deliberation": {
      "put": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/slack/deliberation/test": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/slack/channels": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/slack/channel": {
      "put": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/integrations/slack/test": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/usage/": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/usage/current": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/approvers/": {
      "post": {
        "summary": "Register an approver",
        "tags": [
          "Approvers"
        ],
        "description": "Admin-initiated registration. Creates a person with declared channels/methods; email/inbox are auto-verified, the rest land pending until the approver self-verifies. Idempotent per (org, email).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "clerkUserId": {
                    "type": "string"
                  },
                  "channels": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "channel": {
                          "type": "string",
                          "enum": [
                            "email",
                            "slack",
                            "discord",
                            "phone",
                            "sms",
                            "webhook"
                          ]
                        },
                        "endpoint": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "channel"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "methods": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "surface": {
                          "type": "string",
                          "enum": [
                            "inbox",
                            "slack",
                            "discord",
                            "docusign",
                            "email",
                            "api"
                          ]
                        },
                        "resolvedRef": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "surface"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "email"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "get": {
        "summary": "List approvers",
        "tags": [
          "Approvers"
        ],
        "description": "All approver identities for the org, with channel + method verification state.",
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/approvers/{id}": {
      "get": {
        "summary": "Get an approver",
        "tags": [
          "Approvers"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/approvers/{id}/verify": {
      "post": {
        "summary": "Verify an approver capability",
        "tags": [
          "Approvers"
        ],
        "description": "Self-serve completion: mark a declared channel or surface verified (or failed), persisting the proven endpoint/ref. Real per-channel proof (OTP, Slack lookup, DocuSign mapping) plugs in here.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "channel": {
                    "type": "string",
                    "enum": [
                      "email",
                      "slack",
                      "discord",
                      "phone",
                      "sms",
                      "webhook"
                    ]
                  },
                  "surface": {
                    "type": "string",
                    "enum": [
                      "inbox",
                      "slack",
                      "discord",
                      "docusign",
                      "email",
                      "api"
                    ]
                  },
                  "endpoint": {
                    "type": "string"
                  },
                  "resolvedRef": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "verified",
                      "failed"
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/approvers/{id}/disable": {
      "post": {
        "summary": "Disable an approver",
        "tags": [
          "Approvers"
        ],
        "description": "Soft-disable. The approver stops binding any surface and is never routed a decision. Policies naming them still resolve, but report as unsatisfiable, returned in `warnings`. Reversible via /enable. Idempotent.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/approvers/{id}/enable": {
      "post": {
        "summary": "Re-enable a disabled approver",
        "tags": [
          "Approvers"
        ],
        "description": "Clears the disable. Registration deliberately does not do this, because bringing someone back is an explicit act. Idempotent.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/policies/": {
      "get": {
        "summary": "List approval policies",
        "tags": [
          "Policies"
        ],
        "description": "All approval policies for the org, each with its usage: pending decisions under it and when it was last used (FN-256).",
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "post": {
        "summary": "Create (or upsert) an approval policy",
        "tags": [
          "Policies"
        ],
        "description": "Create an org-scoped approval policy: who approves (approver group + quorum) and the surface the verdict is recorded on. Idempotent upsert keyed by (org, key). key is the immutable slug code references; name and description are editable labels. A body with only name is read as key = name. Rejects unsatisfiable policies with 422.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000,
                    "nullable": true
                  },
                  "defaults": {
                    "type": "object",
                    "properties": {
                      "assigneeEmail": {
                        "type": "string",
                        "format": "email"
                      },
                      "route": {
                        "type": "object",
                        "properties": {
                          "channels": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "email",
                                "slack",
                                "discord",
                                "phone",
                                "sms",
                                "webhook"
                              ]
                            },
                            "minItems": 1
                          },
                          "strategy": {
                            "type": "string",
                            "enum": [
                              "fanout",
                              "escalate"
                            ]
                          },
                          "escalateAfterSec": {
                            "type": "integer",
                            "exclusiveMinimum": true,
                            "minimum": 0
                          }
                        },
                        "required": [
                          "channels"
                        ],
                        "additionalProperties": false
                      },
                      "surface": {
                        "type": "string",
                        "enum": [
                          "inbox",
                          "slack",
                          "discord",
                          "docusign",
                          "email",
                          "api"
                        ]
                      },
                      "approvers": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "format": "email"
                        }
                      },
                      "approvalsRequired": {
                        "type": "integer",
                        "exclusiveMinimum": true,
                        "minimum": 0
                      },
                      "rejectionsRequired": {
                        "type": "integer",
                        "exclusiveMinimum": true,
                        "minimum": 0
                      }
                    },
                    "additionalProperties": false,
                    "default": {}
                  },
                  "key": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "pattern": "^[a-z0-9]+(?:[-_.][a-z0-9]+)*$"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/policies/{key}": {
      "get": {
        "summary": "Get an approval policy by key",
        "tags": [
          "Policies"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "in": "path",
            "name": "key",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "put": {
        "summary": "Update an approval policy",
        "tags": [
          "Policies"
        ],
        "description": "Replace an existing policy’s defaults, and optionally its name and description. The key never changes: to use a different key, create a new policy. 404 if it does not exist. Rejects unsatisfiable policies with 422.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000,
                    "nullable": true
                  },
                  "defaults": {
                    "type": "object",
                    "properties": {
                      "assigneeEmail": {
                        "type": "string",
                        "format": "email"
                      },
                      "route": {
                        "type": "object",
                        "properties": {
                          "channels": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "email",
                                "slack",
                                "discord",
                                "phone",
                                "sms",
                                "webhook"
                              ]
                            },
                            "minItems": 1
                          },
                          "strategy": {
                            "type": "string",
                            "enum": [
                              "fanout",
                              "escalate"
                            ]
                          },
                          "escalateAfterSec": {
                            "type": "integer",
                            "exclusiveMinimum": true,
                            "minimum": 0
                          }
                        },
                        "required": [
                          "channels"
                        ],
                        "additionalProperties": false
                      },
                      "surface": {
                        "type": "string",
                        "enum": [
                          "inbox",
                          "slack",
                          "discord",
                          "docusign",
                          "email",
                          "api"
                        ]
                      },
                      "approvers": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "format": "email"
                        }
                      },
                      "approvalsRequired": {
                        "type": "integer",
                        "exclusiveMinimum": true,
                        "minimum": 0
                      },
                      "rejectionsRequired": {
                        "type": "integer",
                        "exclusiveMinimum": true,
                        "minimum": 0
                      }
                    },
                    "additionalProperties": false,
                    "default": {}
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "in": "path",
            "name": "key",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "delete": {
        "summary": "Delete an approval policy",
        "tags": [
          "Policies"
        ],
        "description": "Refused with 409 policy_in_use while the policy has pending decisions or was used in the last 30 days, because code likely still references its key and would start failing with unknown_policy. Pass force=true to delete anyway; the override is audited.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            },
            "in": "query",
            "name": "force",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "in": "path",
            "name": "key",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/contact-methods/": {
      "get": {
        "summary": "Get my contact methods",
        "tags": [
          "Notifications"
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "put": {
        "summary": "Update my contact methods",
        "tags": [
          "Notifications"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "nullable": true
                  },
                  "sms": {
                    "type": "string",
                    "nullable": true
                  },
                  "slack": {
                    "type": "string",
                    "nullable": true
                  },
                  "pushEnabled": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/push-devices/": {
      "post": {
        "summary": "Register this device for push",
        "tags": [
          "Notifications"
        ],
        "description": "Idempotent on (user, token), so it is safe to call on every launch. The client should do exactly that, because push tokens rotate on reinstall and restore. Re-registering a revoked device reactivates it.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "platform": {
                    "type": "string",
                    "enum": [
                      "ios",
                      "android"
                    ]
                  },
                  "deviceName": {
                    "type": "string",
                    "maxLength": 120,
                    "nullable": true
                  }
                },
                "required": [
                  "token",
                  "platform"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "get": {
        "summary": "List my registered devices",
        "tags": [
          "Notifications"
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/push-devices/{id}": {
      "delete": {
        "summary": "Revoke one of my devices",
        "tags": [
          "Notifications"
        ],
        "description": "Soft-revoke. Call on sign-out, otherwise the next person to sign in on that handset keeps receiving the previous user’s notifications.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/directory/actor": {
      "get": {
        "summary": "Resolve an internal actor id to a display label",
        "tags": [
          "Directory"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "query",
            "name": "ref",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/billing/": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/billing/checkout": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/billing/portal": {
      "post": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/roles/": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "post": {
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 300
                  },
                  "permissions": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "billing:read",
                        "billing:write",
                        "policies:read",
                        "policies:write",
                        "approvers:write",
                        "decisions:read",
                        "decisions:decide",
                        "apikeys:manage",
                        "settings:write",
                        "members:manage",
                        "roles:manage",
                        "audit:read",
                        "usage:read"
                      ]
                    }
                  }
                },
                "required": [
                  "name",
                  "permissions"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/roles/{id}": {
      "put": {
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 300
                  },
                  "permissions": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "billing:read",
                        "billing:write",
                        "policies:read",
                        "policies:write",
                        "approvers:write",
                        "decisions:read",
                        "decisions:decide",
                        "apikeys:manage",
                        "settings:write",
                        "members:manage",
                        "roles:manage",
                        "audit:read",
                        "usage:read"
                      ]
                    }
                  }
                },
                "required": [
                  "name",
                  "permissions"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "delete": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/members/": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/members/{userId}/roles": {
      "post": {
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "roleRef": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  }
                },
                "required": [
                  "roleRef"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "userId",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/members/{userId}/roles/{roleRef}": {
      "delete": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "userId",
            "required": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "roleRef",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/members/{userId}/deactivate": {
      "post": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "userId",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/members/{userId}/reactivate": {
      "post": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "userId",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/members/invitations": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "post": {
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 320
                  }
                },
                "required": [
                  "email"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/members/invitations/{invitationId}/revoke": {
      "post": {
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "in": "path",
            "name": "invitationId",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/members/invitations/{invitationId}/resend": {
      "post": {
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "in": "path",
            "name": "invitationId",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/me/permissions": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/me/organizations": {
      "get": {
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/decisions/": {
      "get": {
        "summary": "List decisions (reviewer inbox)",
        "tags": [
          "Decisions"
        ],
        "description": "List decisions for the org, newest first. Filter by status and assignee email for the reviewer inbox.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "APPROVED",
                "REJECTED",
                "EXPIRED",
                "CANCELLED"
              ]
            },
            "in": "query",
            "name": "status",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "format": "email"
            },
            "in": "query",
            "name": "assignee",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "workflowRef",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "in": "query",
            "name": "limit",
            "required": false
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "in": "query",
            "name": "offset",
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/decisions/workflows": {
      "get": {
        "summary": "Distinct workflows for the inbox filter",
        "tags": [
          "Decisions"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "email"
            },
            "in": "query",
            "name": "assignee",
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/decisions/{id}": {
      "get": {
        "summary": "Get a decision with its quorum tally",
        "tags": [
          "Decisions"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/decisions/{id}/evidence": {
      "post": {
        "summary": "Attach immutable evidence to a decision",
        "tags": [
          "Decisions"
        ],
        "description": "Append material the decision is being made ON — a Slack thread, an email, a policy doc. Append-only: evidence is never edited or deleted, and can only be attached while the decision is PENDING. Once it resolves the set is sealed, so what you see is exactly what the approver could see. Re-attaching identical content is a no-op.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "slack_thread",
                      "email",
                      "document",
                      "link",
                      "note"
                    ]
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "sourceSystem": {
                    "type": "string",
                    "maxLength": 60
                  },
                  "sourceUrl": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2000
                  },
                  "sourceRef": {
                    "type": "object",
                    "additionalProperties": {}
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 262144
                  },
                  "bodyFormat": {
                    "type": "string",
                    "enum": [
                      "text",
                      "markdown"
                    ],
                    "default": "text"
                  },
                  "payload": {
                    "type": "object",
                    "additionalProperties": {}
                  },
                  "capturedAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                },
                "required": [
                  "kind"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      },
      "get": {
        "summary": "List a decision’s evidence, oldest first",
        "tags": [
          "Decisions"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/decisions/{id}/output": {
      "put": {
        "summary": "Save the reviewer’s refined draft (conversational refinement)",
        "tags": [
          "Decisions"
        ],
        "description": "Persist an edited version of a refinable decision’s proposed output. On approve, the engine resumes with the refined draft (refinedOutput ?? proposedOutput). Only allowed while the decision is PENDING and carries a proposedOutput.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "text",
                      "markdown"
                    ]
                  },
                  "content": {
                    "type": "string",
                    "maxLength": 50000
                  }
                },
                "required": [
                  "content"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/decisions/{id}/refine": {
      "post": {
        "summary": "Refine the draft with the org’s own model (BYO)",
        "tags": [
          "Decisions"
        ],
        "description": "Apply the reviewer’s feedback to the current draft using the org’s configured LLM (Settings → Refine with AI). Returns the revised draft and appends the turn to the refinement log. Does not commit: the reviewer saves via PUT /output, then approves.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "feedback": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4000
                  }
                },
                "required": [
                  "feedback"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/decisions/{id}/decide": {
      "post": {
        "summary": "Approve or reject a decision",
        "tags": [
          "Decisions"
        ],
        "description": "Record a vote. Under quorum the decision resolves only when the approval/rejection threshold is met; reject-wins by default. On resolution Ratifia fires the engine resume event.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "approve",
                      "reject"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "responseValue": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "approval"
                            ]
                          },
                          "decision": {
                            "type": "string",
                            "enum": [
                              "approve",
                              "reject"
                            ]
                          }
                        },
                        "required": [
                          "type",
                          "decision"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "select"
                            ]
                          },
                          "selected": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "maxItems": 20
                          }
                        },
                        "required": [
                          "type",
                          "selected"
                        ],
                        "additionalProperties": false
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "text"
                            ]
                          },
                          "text": {
                            "type": "string",
                            "maxLength": 50000
                          }
                        },
                        "required": [
                          "type",
                          "text"
                        ],
                        "additionalProperties": false
                      }
                    ]
                  }
                },
                "required": [
                  "decision"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "http://localhost:3001"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ]
}
