{
  "openapi": "3.1.0",
  "info": {
    "title": "Holofin API",
    "version": "1.1",
    "description": "Send financial documents through a workflow that classifies, segments, extracts and screens them for fraud, then read the structured result.",
    "contact": {
      "name": "Holofin",
      "url": "https://app.holofin.ai/docs/api/v1.1/"
    }
  },
  "servers": [
    {
      "url": "https://app.holofin.ai"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "A workspace-scoped key from your developer settings."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "example": "INVALID_CASE_ID"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        }
      },
      "WorkflowRun": {
        "type": "object",
        "properties": {
          "run_id": {
            "type": "string",
            "description": "The run's ID."
          },
          "workflow_id": {
            "type": "string",
            "description": "The workflow that ran."
          },
          "workflow_name": {
            "type": "string",
            "description": "The workflow's display name."
          },
          "document_id": {
            "type": "string",
            "description": "The uploaded file."
          },
          "document_name": {
            "type": "string"
          },
          "extraction_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The extraction's ID (`wea_...`), null until the extraction node has run. The same value as `extraction_id` in the Partner SSO token and the extraction JSON export."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "completed",
              "failed",
              "cancelled",
              "paused"
            ],
            "description": "`pending` until it starts, `running`, `paused` at a human review node, then `completed`, `failed` or `cancelled`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "The `metadata` sent on creation, returned as is."
          },
          "document_pdf_url": {
            "type": "string",
            "format": "uri",
            "description": "The [run document PDF](#get-workflow-run-pdf) endpoint. Needs the `X-API-Key` header."
          },
          "progress": {
            "type": "object",
            "additionalProperties": true,
            "description": "`current_step`, `total_steps` and `percentage`."
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ]
          },
          "classification_result": {
            "type": [
              "object",
              "null"
            ],
            "description": "`class`, `confidence` and `reasoning`. Null without a classifier node."
          },
          "segmentation_result": {
            "type": [
              "object",
              "null"
            ],
            "description": "`sections`, one entry per document found (`section_id`, `pages`, `partition_key`), and `pages`, the same split page by page. Null without a segmenter node."
          },
          "extraction_result": {
            "type": [
              "object",
              "null"
            ],
            "description": "`document_parts`, one entry per document found, each with its `data`, `checks`, `validation_status` and a `pdf_url` (the [part PDF](#get-part-pdf)). `duplicated_pages` lists pages left out as duplicates. Fills in as each extractor finishes. See [Schema part types](https://app.holofin.ai/docs/api/v1.1/schema-part-types/)."
          },
          "fraud_analysis_result": {
            "type": [
              "object",
              "null"
            ],
            "description": "`risk_level`, `risk_score`, `risk_factors` and `trust_factors`. Each factor's `sources` says where its evidence comes from: `forensic`, `template`, `content` or `seal`. `status` is `skipped`, with a `skip_reason`, when the organization's fraud filters left the document out. Null without a fraud node. See [Fraud analysis](https://app.holofin.ai/docs/api/v1.1/fraud-analysis/)."
          },
          "case_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The dossier the document is filed under, if any."
          },
          "no_route_matched": {
            "type": "boolean",
            "description": "True when the run ended without extraction because no route handles the document's type. The run did not fail: add a route for the type, or send the document to another workflow."
          },
          "unmatched_classifications": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "The types that had no route, when `no_route_matched` is true."
          },
          "error": {
            "type": [
              "object",
              "null"
            ],
            "description": "On a failed run, `code` (`NODE_EXECUTION_FAILED` or `WORKFLOW_FAILED`) and `message`, plus `node_id` and `node_type` for a node failure."
          }
        },
        "required": [
          "run_id",
          "workflow_id",
          "status"
        ]
      },
      "WorkflowRunSummary": {
        "type": "object",
        "properties": {
          "run_id": {
            "type": "string"
          },
          "workflow_id": {
            "type": "string"
          },
          "workflow_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "document_id": {
            "type": "string"
          },
          "document_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "extraction_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The extraction's ID (`wea_...`), null until the extraction node has run. The same value as `extraction_id` in the Partner SSO token and the extraction JSON export."
          },
          "case_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The dossier the document is filed under. A document in several dossiers reports the earliest."
          },
          "status": {
            "type": "string",
            "enum": [
              "completed",
              "failed",
              "cancelled"
            ]
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ]
          },
          "validation_status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "OK",
              "WARNING",
              "ERROR",
              null
            ],
            "description": "The combined verdict of the extraction checks; null without extraction. The per-check detail is on the run."
          }
        },
        "required": [
          "run_id",
          "workflow_id",
          "status"
        ]
      }
    }
  },
  "tags": [
    {
      "name": "Workflow runs",
      "description": "Send documents and read results."
    },
    {
      "name": "Dossiers",
      "description": "Group documents and field values under a case."
    },
    {
      "name": "Webhooks",
      "description": "Manage the endpoints Holofin posts events to."
    },
    {
      "name": "Organizations",
      "description": "Super-partner child organization management."
    },
    {
      "name": "Organization",
      "description": "Consumption and processing metrics."
    }
  ],
  "paths": {
    "/api/v1.1/workflow-runs/": {
      "get": {
        "operationId": "listWorkflowRuns",
        "x-docs-anchor": "list-workflow-runs",
        "x-docs-page": "/docs/api/v1.1/workflow-runs/",
        "summary": "List workflow runs",
        "description": "Runs that have finished (`completed`, `failed` or `cancelled`), newest first. Items carry no extraction data: fetch a run by ID for it.",
        "tags": [
          "Workflow runs"
        ],
        "parameters": [
          {
            "name": "workflow_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "wf_abc123xyz",
            "description": "Only this workflow's runs."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "completed",
                "failed",
                "cancelled"
              ]
            }
          },
          {
            "name": "case_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Only runs whose document is in this dossier."
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100,
              "minimum": 1
            },
            "description": "Page size, clamped to 1-100.",
            "example": 20
          },
          {
            "name": "next_token",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque cursor from the previous page. Omit for the first page."
          }
        ],
        "x-errors": [
          {
            "code": "INVALID_FILTER",
            "description": "`created_after` or `created_before` is not ISO 8601."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "runs": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WorkflowRunSummary"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "description": "`page_size`, `has_next`, and `next_token` while `has_next` is true. Pass `next_token` back for the next page.",
                      "properties": {
                        "page_size": {
                          "type": "integer"
                        },
                        "has_next": {
                          "type": "boolean"
                        },
                        "next_token": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "page_size",
                        "has_next"
                      ]
                    }
                  },
                  "required": [
                    "runs",
                    "pagination"
                  ]
                },
                "example": {
                  "runs": [
                    {
                      "run_id": "wr_abc123xyz789",
                      "workflow_id": "wf_abc123xyz",
                      "workflow_name": "Bank Statement Processing",
                      "document_id": "doc_def456uvw",
                      "extraction_id": "wea_abc123xyz789",
                      "case_id": "L-2026-0417",
                      "document_name": "statement_january_2024.pdf",
                      "status": "completed",
                      "created_at": "2024-01-15T10:30:00Z",
                      "completed_at": "2024-01-15T10:30:15Z",
                      "duration_ms": 14000,
                      "validation_status": "OK"
                    }
                  ],
                  "pagination": {
                    "page_size": 20,
                    "has_next": true,
                    "next_token": "MjAyNC0wMS0xNVQxMDozMDoxNVp8d3JfYWJj"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "INVALID_FILTER",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createWorkflowRun",
        "x-docs-anchor": "create-workflow-run",
        "x-docs-page": "/docs/api/v1.1/workflow-runs/",
        "summary": "Create a workflow run",
        "description": "Sends one document through a workflow. Returns at once with the run in `pending`; follow it with [webhooks](https://app.holofin.ai/docs/api/v1.1/webhooks/) or by polling the run. A call refused with a 4xx creates no run and uses no credits.",
        "tags": [
          "Workflow runs"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workflow_id": {
                    "type": "string",
                    "description": "The workflow to run."
                  },
                  "document_b64": {
                    "type": "string",
                    "description": "The file, base64-encoded: a PDF, an office document (`.xlsx`, `.xls`, `.docx`, `.pptx`) or one image (PNG, JPG, TIFF). Images become a PDF. Send this or `document_pages_b64`."
                  },
                  "document_pages_b64": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Base64 images merged, in order, into one PDF."
                  },
                  "document_name": {
                    "type": "string",
                    "default": "document",
                    "description": "The extension is set from the file's real type."
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Your own keys, returned on the run and in every webhook."
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Send this run's webhook events to this URL only, instead of your configured endpoints. Signed with your endpoints' secret, or unsigned (with a warning) when you have none."
                  },
                  "case_id": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "The dossier this document joins. Create it first with [`POST /cases/`](https://app.holofin.ai/docs/api/v1.1/cases/); a run never opens one."
                  },
                  "party_refs": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 255
                    },
                    "minItems": 1,
                    "uniqueItems": true,
                    "description": "The participants the document belongs to, by `party_ref`. Several declare a jointly held document. Needs `case_id`. See [Sending documents](https://app.holofin.ai/docs/api/v1.1/cases/#documents)."
                  }
                },
                "required": [
                  "workflow_id"
                ]
              },
              "example": {
                "workflow_id": "wf_abc123xyz",
                "document_b64": "JVBERi0xLjQKJeLjz9MKNCAwIG9i...",
                "document_name": "invoice-2024-001.pdf",
                "metadata": {
                  "client_reference": "invoice-2024-001"
                }
              }
            }
          }
        },
        "x-errors": [
          {
            "code": "MISSING_WORKFLOW_ID"
          },
          {
            "code": "MISSING_DOCUMENT"
          },
          {
            "code": "CONFLICTING_INPUT"
          },
          {
            "code": "INVALID_DOCUMENT"
          },
          {
            "code": "PAGE_LIMIT_EXCEEDED"
          },
          {
            "code": "INVALID_WEBHOOK_URL"
          },
          {
            "code": "UNSUPPORTED_FIELD",
            "description": "The body carries a dossier key (`case_fields`, `party_fields`, `config_id`, `party_ref`, `role`, `party_type`). Send it to `POST /cases/`."
          },
          {
            "code": "APPLICATIONS_DISABLED",
            "description": "`case_id` was sent but Dossiers are not enabled."
          },
          {
            "code": "INVALID_CASE_ID"
          },
          {
            "code": "UNKNOWN_CASE_ID"
          },
          {
            "code": "PARTY_WITHOUT_CASE"
          },
          {
            "code": "INVALID_PARTY_REF"
          },
          {
            "code": "UNKNOWN_PARTY_REF"
          },
          {
            "code": "INSUFFICIENT_CREDITS"
          },
          {
            "code": "NO_ACTIVE_SUBSCRIPTION"
          },
          {
            "code": "PLAN_NOT_PAID"
          },
          {
            "code": "WORKFLOW_NOT_FOUND"
          },
          {
            "code": "SANDBOX_LIMIT_EXCEEDED"
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowRun"
                },
                "example": {
                  "run_id": "wr_abc123xyz789",
                  "workflow_id": "wf_abc123xyz",
                  "workflow_name": "Invoice Processing",
                  "document_id": "doc_def456uvw",
                  "extraction_id": null,
                  "document_name": "invoice-2024-001.pdf",
                  "status": "pending",
                  "created_at": "2024-01-15T10:30:00Z",
                  "metadata": {
                    "client_reference": "invoice-2024-001"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "MISSING_WORKFLOW_ID, MISSING_DOCUMENT, CONFLICTING_INPUT, INVALID_DOCUMENT, PAGE_LIMIT_EXCEEDED, INVALID_WEBHOOK_URL, UNSUPPORTED_FIELD, APPLICATIONS_DISABLED, INVALID_CASE_ID, UNKNOWN_CASE_ID, PARTY_WITHOUT_CASE, INVALID_PARTY_REF, UNKNOWN_PARTY_REF",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "INSUFFICIENT_CREDITS, NO_ACTIVE_SUBSCRIPTION, PLAN_NOT_PAID",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "WORKFLOW_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-response-fields": false
      }
    },
    "/api/v1.1/workflow-runs/{run_id}": {
      "get": {
        "operationId": "getWorkflowRun",
        "x-docs-anchor": "get-workflow-run",
        "x-docs-page": "/docs/api/v1.1/workflow-runs/",
        "summary": "Get a workflow run",
        "description": "The run's status and results. Results fill in while it runs: `extraction_result` gains a part as each extractor finishes.",
        "tags": [
          "Workflow runs"
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "wr_abc123xyz789",
            "description": "The run's ID, from the create call."
          }
        ],
        "x-errors": [
          {
            "code": "RUN_NOT_FOUND"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowRun"
                },
                "example": {
                  "run_id": "wr_abc123xyz789",
                  "workflow_id": "wf_abc123xyz",
                  "workflow_name": "Bank Statement Processing",
                  "document_id": "doc_def456uvw",
                  "extraction_id": "wea_abc123xyz789",
                  "document_name": "statement_january_2024.pdf",
                  "document_pdf_url": "https://app.holofin.ai/api/v1.1/workflow-runs/wr_abc123xyz789/pdf",
                  "status": "completed",
                  "progress": {
                    "current_step": 4,
                    "total_steps": 4,
                    "percentage": 100
                  },
                  "started_at": "2024-01-15T10:30:01Z",
                  "completed_at": "2024-01-15T10:30:15Z",
                  "duration_ms": 14000,
                  "classification_result": {
                    "class": "bank_statement",
                    "confidence": 0.98,
                    "reasoning": "Bank logo, account number and a transaction list."
                  },
                  "segmentation_result": {
                    "sections": [
                      {
                        "section_id": "bank_statement",
                        "pages": [
                          1,
                          2
                        ],
                        "partition_key": "FR7630004020360001026054720"
                      }
                    ],
                    "pages": [
                      {
                        "page": 1,
                        "section": "bank_statement",
                        "partition": "FR7630004020360001026054720"
                      },
                      {
                        "page": 2,
                        "section": "bank_statement",
                        "partition": "FR7630004020360001026054720"
                      }
                    ]
                  },
                  "extraction_result": {
                    "document_parts": [
                      {
                        "part_type": "bank-statement",
                        "key": "segment_1",
                        "label": "FR7630004020360001026054720",
                        "validation_status": "OK",
                        "validation_codes": [],
                        "checks": [
                          {
                            "type": "extraction",
                            "code": "BALANCE_EQUATION",
                            "label": "Balance equation",
                            "status": "passed",
                            "severity": "error"
                          }
                        ],
                        "pages": [
                          1,
                          2
                        ],
                        "pdf_url": "https://app.holofin.ai/api/v1.1/workflow-runs/wr_abc123xyz789/parts/segment_1/pdf",
                        "data": {
                          "bank_name": "BNP Paribas",
                          "currency": "EUR",
                          "account_number": "FR7630004020360001026054720",
                          "client_name": "ACME Corporation SARL",
                          "start_balance": 2450.75,
                          "end_balance": 5825.25,
                          "start_date": "2024-01-01",
                          "end_date": "2024-01-31",
                          "transactions": [
                            {
                              "transaction_date": "2024-01-02",
                              "description": "VIREMENT SALAIRE",
                              "amount": 3500.0,
                              "page": 1,
                              "row": 1
                            }
                          ]
                        }
                      }
                    ]
                  },
                  "fraud_analysis_result": {
                    "status": "completed",
                    "risk_level": "warning",
                    "risk_score": 42,
                    "risk_factors": [
                      {
                        "id": "suspicious_timestamp",
                        "label": "Suspicious Timestamp",
                        "severity": "medium",
                        "details": "Unusual gap between creation and modification times.",
                        "sources": [
                          "forensic"
                        ]
                      }
                    ],
                    "trust_factors": []
                  },
                  "case_id": null,
                  "no_route_matched": false,
                  "unmatched_classifications": null,
                  "error": null,
                  "metadata": {
                    "client_reference": "statement-2024-001"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "RUN_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/workflow-runs/{run_id}/pdf": {
      "get": {
        "operationId": "getWorkflowRunPdf",
        "x-docs-anchor": "get-workflow-run-pdf",
        "x-docs-page": "/docs/api/v1.1/workflow-runs/",
        "x-download": "document.pdf",
        "summary": "Download the run's document",
        "description": "The file sent on creation, available as soon as the run exists. This is the run's `document_pdf_url`. Redirects (302) to a signed link valid for about 10 minutes; any client that follows redirects receives the PDF. With `format=json`, returns the link instead.",
        "tags": [
          "Workflow runs"
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "wr_abc123xyz789",
            "description": "The run's ID, from the create call."
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json"
              ]
            },
            "description": "`json` returns the signed link in a JSON body instead of redirecting."
          }
        ],
        "x-errors": [
          {
            "code": "RUN_NOT_FOUND"
          },
          {
            "code": "DOCUMENT_FILE_UNAVAILABLE"
          },
          {
            "code": "UNSUPPORTED_DOCUMENT_TYPE"
          },
          {
            "code": "PDF_RESOLUTION_FAILED"
          }
        ],
        "responses": {
          "200": {
            "description": "With format=json",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "format": "uri",
                      "description": "Anyone with the link can download the file until it expires."
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "url": "https://storage.holofin.ai/documents/doc_def456uvw.pdf?signature=...",
                  "expires_at": "2026-08-01T10:40:00Z"
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "302": {
            "description": "Redirect to the signed link."
          },
          "404": {
            "description": "RUN_NOT_FOUND, DOCUMENT_FILE_UNAVAILABLE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "UNSUPPORTED_DOCUMENT_TYPE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "PDF_RESOLUTION_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/workflow-runs/{run_id}/parts/{part_key}/pdf": {
      "get": {
        "operationId": "getWorkflowRunPartPdf",
        "x-docs-anchor": "get-part-pdf",
        "x-docs-page": "/docs/api/v1.1/workflow-runs/",
        "x-download": "segment_1.pdf",
        "summary": "Download a document part",
        "description": "The pages of one part as a single PDF, non-contiguous pages included. Each entry of `document_parts` carries this URL as `pdf_url`. Same redirect and `format=json` behaviour as the run's document.",
        "tags": [
          "Workflow runs"
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "wr_abc123xyz789",
            "description": "The run's ID, from the create call."
          },
          {
            "name": "part_key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "segment_1",
            "description": "The part's `key` in `document_parts`."
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json"
              ]
            },
            "description": "`json` returns the signed link in a JSON body instead of redirecting."
          }
        ],
        "x-errors": [
          {
            "code": "RUN_NOT_FOUND"
          },
          {
            "code": "PART_NOT_FOUND"
          },
          {
            "code": "DOCUMENT_FILE_UNAVAILABLE"
          },
          {
            "code": "RUN_NOT_TERMINAL",
            "description": "Extraction has not finished, so the parts do not exist yet."
          },
          {
            "code": "UNSUPPORTED_DOCUMENT_TYPE"
          },
          {
            "code": "PDF_RESOLUTION_FAILED"
          }
        ],
        "responses": {
          "200": {
            "description": "With format=json",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "format": "uri",
                      "description": "Anyone with the link can download the file until it expires."
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "url": "https://storage.holofin.ai/documents/doc_def456uvw_segment_1.pdf?signature=...",
                  "expires_at": "2026-08-01T10:40:00Z"
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "302": {
            "description": "Redirect to the signed link."
          },
          "404": {
            "description": "RUN_NOT_FOUND, PART_NOT_FOUND, DOCUMENT_FILE_UNAVAILABLE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "RUN_NOT_TERMINAL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "UNSUPPORTED_DOCUMENT_TYPE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "PDF_RESOLUTION_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/workflow-runs/{run_id}/node-runs/": {
      "get": {
        "operationId": "listNodeRuns",
        "x-docs-anchor": "list-node-runs",
        "x-docs-page": "/docs/api/v1.1/workflow-runs/",
        "summary": "List a run's node executions",
        "description": "Each node's configuration, status and output. Extractor output is not here: read it from the run. Start and end nodes are left out.",
        "tags": [
          "Workflow runs"
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "wr_abc123xyz789",
            "description": "The run's ID, from the create call."
          }
        ],
        "x-errors": [
          {
            "code": "RUN_NOT_FOUND"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "run_id": {
                      "type": "string"
                    },
                    "node_runs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "node_type": {
                            "type": "string",
                            "description": "`classifier`, `segmenter`, `extractor`, `humanReview`, `router`..."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "ready",
                              "running",
                              "paused",
                              "completed",
                              "failed",
                              "skipped"
                            ]
                          },
                          "started_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "completed_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "duration_ms": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "agent_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The agent the node used."
                          },
                          "is_global_agent": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "True for a Holofin agent, false for your own."
                          },
                          "config": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "The node's configuration; the shape depends on `node_type`."
                          },
                          "results": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "The node's output; the shape depends on `node_type`."
                          }
                        }
                      }
                    },
                    "total_count": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "run_id": "wr_abc123xyz789",
                  "node_runs": [
                    {
                      "node_type": "classifier",
                      "status": "completed",
                      "started_at": "2024-01-15T10:30:01Z",
                      "completed_at": "2024-01-15T10:30:04Z",
                      "duration_ms": 3120,
                      "agent_id": "ca_EACHWbXq3cRtPvGQ",
                      "is_global_agent": false,
                      "config": {
                        "classifier_name": "Financial documents",
                        "classes": [
                          {
                            "name": "bank_statement",
                            "description": "..."
                          }
                        ]
                      },
                      "results": {
                        "class": "bank_statement",
                        "confidence": 0.98,
                        "reasoning": "Bank logo, account number, transactions."
                      }
                    }
                  ],
                  "total_count": 1
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "RUN_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/workflow-runs/{run_id}/cancel": {
      "post": {
        "operationId": "cancelWorkflowRun",
        "x-docs-anchor": "cancel-workflow-run",
        "x-docs-page": "/docs/api/v1.1/workflow-runs/",
        "summary": "Cancel a workflow run",
        "description": "Stops a `pending` or `running` run before its next node starts. A node already running finishes first.",
        "tags": [
          "Workflow runs"
        ],
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "wr_abc123xyz789",
            "description": "The run's ID, from the create call."
          }
        ],
        "x-errors": [
          {
            "code": "RUN_NOT_FOUND"
          },
          {
            "code": "CANNOT_CANCEL"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "run_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "cancelled"
                      ]
                    },
                    "cancelled_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "run_id": "wr_abc123xyz789",
                  "status": "cancelled",
                  "cancelled_at": "2024-01-15T10:30:05Z"
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "RUN_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "CANNOT_CANCEL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/cases": {
      "get": {
        "operationId": "listCases",
        "x-docs-anchor": "list",
        "x-docs-page": "/docs/api/v1.1/cases/",
        "summary": "List dossiers",
        "description": "One row per dossier with a `case_id`, whatever its state, with the status columns only. Requirements, documents and rule verdicts come from the dossier itself.",
        "tags": [
          "Dossiers"
        ],
        "parameters": [
          {
            "name": "case_status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "decision",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "coherence",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "ok",
                "ko",
                "warning",
                "review",
                "none"
              ]
            }
          },
          {
            "name": "updated_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "updated_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100,
              "minimum": 1
            },
            "description": "Page size, clamped to 1-100."
          },
          {
            "name": "next_token",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque cursor from the previous page. Omit for the first page."
          }
        ],
        "x-errors": [
          {
            "code": "APPLICATIONS_DISABLED"
          },
          {
            "code": "UNKNOWN_PARAMETER"
          },
          {
            "code": "INVALID_FILTER"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "APPLICATIONS_DISABLED, UNKNOWN_PARAMETER, INVALID_FILTER",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "upsertCase",
        "x-docs-anchor": "create-or-update",
        "x-docs-page": "/docs/api/v1.1/cases/",
        "x-errors": [
          {
            "code": "INVALID_JSON"
          },
          {
            "code": "UNSUPPORTED_FIELD"
          },
          {
            "code": "APPLICATIONS_DISABLED"
          },
          {
            "code": "INVALID_CASE_ID"
          },
          {
            "code": "MISSING_CONFIG_ID"
          },
          {
            "code": "UNKNOWN_CONFIG"
          },
          {
            "code": "UNKNOWN_ROLE"
          },
          {
            "code": "INVALID_PARTY_TYPE"
          },
          {
            "code": "INVALID_PARTY_REF"
          },
          {
            "code": "INVALID_INPUT_FIELD"
          },
          {
            "code": "UNKNOWN_INPUT_FIELD"
          },
          {
            "code": "FIELDS_WITHOUT_PARTY"
          },
          {
            "code": "CONFIG_CONFLICT"
          },
          {
            "code": "METHOD_NOT_ALLOWED"
          }
        ],
        "summary": "Create or update a dossier",
        "description": "Merge semantics: only the keys you send are touched, an explicit null clears one, and re-sending the same values changes nothing. Documents are attached through workflow runs, not here. Creating a dossier requires config_id, the case configuration it runs under.",
        "tags": [
          "Dossiers"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "case_id": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Omit and Holofin issues one, returned in the response."
                  },
                  "config_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The case configuration the dossier runs under, from GET /case-configs/. Required when this call creates the dossier (MISSING_CONFIG_ID otherwise), optional afterwards and refused (CONFIG_CONFLICT) if it names another one than the dossier already runs under."
                  },
                  "case_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Values for the fields the configuration declares, as `{key: value}`. A key naming a declared participant holds that participant's object. Omit it when there is nothing to send."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload; nothing was written.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "405": {
            "description": "METHOD_NOT_ALLOWED",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "CONFIG_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/cases/{case_id}": {
      "get": {
        "operationId": "getCase",
        "x-docs-anchor": "read",
        "x-docs-page": "/docs/api/v1.1/cases/",
        "x-errors": [
          {
            "code": "NOT_FOUND",
            "description": "No dossier with this `case_id`."
          }
        ],
        "summary": "Read a dossier's status, requirements and gaps",
        "tags": [
          "Dossiers"
        ],
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "No such dossier in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/cases/{case_id}/activities": {
      "get": {
        "operationId": "listCaseActivities",
        "x-docs-anchor": "activities",
        "x-docs-page": "/docs/api/v1.1/cases/",
        "x-errors": [
          {
            "code": "UNKNOWN_PARAMETER"
          },
          {
            "code": "INVALID_FILTER"
          },
          {
            "code": "NOT_FOUND",
            "description": "No dossier with this `case_id`."
          }
        ],
        "summary": "Read a dossier's change trail",
        "description": "Every recorded change on the dossier, newest first: values edited, extracted values corrected by a reviewer, ownership changes, documents and participants added, decisions, comments and every case_status transition. Same envelope on every entry; `type` is the contract.",
        "tags": [
          "Dossiers"
        ],
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated activity types to keep: field.changed, party.created, document.added, extraction.corrected, owner.changed, decision.taken, decision.reopened, comment.added, status.changed."
          },
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only entries stamped at or after this instant (inclusive)."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100,
              "minimum": 1
            },
            "description": "Page size, clamped to 1-100."
          },
          {
            "name": "next_token",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque cursor from the previous page. Omit for the first page."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Unknown parameter, unknown type, bad instant or cursor.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such dossier in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/case-configs": {
      "get": {
        "operationId": "listCaseConfigs",
        "x-docs-anchor": "list",
        "x-docs-page": "/docs/api/v1.1/case-configs/",
        "x-errors": [
          {
            "code": "APPLICATIONS_DISABLED"
          },
          {
            "code": "UNKNOWN_PARAMETER"
          }
        ],
        "summary": "List the organization's dossier configurations",
        "description": "Read-only catalogue. Each `config_id` is what you send to create a dossier under that configurationand selects nothing through the API.",
        "tags": [
          "Dossiers"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "configs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "config_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "config_id",
                          "name"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The Dossiers feature is not enabled, or an unsupported query parameter was sent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/case-configs/{config_id}": {
      "get": {
        "operationId": "getCaseConfig",
        "x-docs-anchor": "detail",
        "x-docs-page": "/docs/api/v1.1/case-configs/",
        "x-errors": [
          {
            "code": "APPLICATIONS_DISABLED"
          },
          {
            "code": "UNKNOWN_PARAMETER"
          },
          {
            "code": "NOT_FOUND",
            "description": "No case configuration with this ID."
          }
        ],
        "summary": "One configuration's full contract",
        "description": "The configuration as the template of the dossier it produces: the same nesting GET /cases/{case_id} answers, each row being the dossier's row minus its current state. `fields` keyed by field key (dossier-level), `requirements` at dossier level, `participants` keyed by participant key each with the `fields` and `requirements` its parties carry, one flat `rules` list with the same `code` a verdict carries, and `payload_schema` \u2014 the JSON Schema of the POST /cases/ body. Every key is always present; `required_if`, `activation.condition`, `rule` and `description` read null unless rule details are enabled.",
        "tags": [
          "Dossiers"
        ],
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "config_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "fields": {
                      "type": "object",
                      "description": "Dossier-level fields, keyed by the key `case_fields` takes.",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "label": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "text",
                              "number",
                              "boolean",
                              "date",
                              "enum",
                              "siren",
                              "address",
                              "iso_country"
                            ]
                          },
                          "required": {
                            "type": "boolean"
                          },
                          "conditional": {
                            "type": "boolean"
                          },
                          "required_if": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The condition as written; null unless rule details are enabled."
                          },
                          "choices": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "items": {
                              "type": "string"
                            },
                            "description": "The allowed values of an enum field, null for other types."
                          }
                        },
                        "required": [
                          "label",
                          "type",
                          "required",
                          "conditional",
                          "required_if",
                          "choices"
                        ]
                      }
                    },
                    "requirements": {
                      "type": "array",
                      "description": "Dossier-level requirements; a participant's are listed under it.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "accepted_categories": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "min": {
                            "type": "integer"
                          },
                          "max": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "null = no cap."
                          },
                          "conditional": {
                            "type": "boolean"
                          },
                          "activation": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "null on a plain requirement.",
                            "properties": {
                              "condition": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The condition as written; null unless rule details are enabled."
                              }
                            },
                            "required": [
                              "condition"
                            ]
                          },
                          "shareable": {
                            "type": "boolean"
                          },
                          "presence_only": {
                            "type": "boolean"
                          },
                          "group": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "key",
                          "label",
                          "description",
                          "accepted_categories",
                          "min",
                          "max",
                          "conditional",
                          "activation",
                          "shareable",
                          "presence_only",
                          "group"
                        ]
                      }
                    },
                    "participants": {
                      "type": "object",
                      "description": "Keyed by participant key.",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "label": {
                            "type": "string"
                          },
                          "min": {
                            "type": "integer"
                          },
                          "max": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "fields": {
                            "type": "object",
                            "additionalProperties": {
                              "type": "object",
                              "properties": {
                                "label": {
                                  "type": "string"
                                },
                                "type": {
                                  "type": "string",
                                  "enum": [
                                    "text",
                                    "number",
                                    "boolean",
                                    "date",
                                    "enum",
                                    "siren",
                                    "address",
                                    "iso_country"
                                  ]
                                },
                                "required": {
                                  "type": "boolean"
                                },
                                "conditional": {
                                  "type": "boolean"
                                },
                                "required_if": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "The condition as written; null unless rule details are enabled."
                                },
                                "choices": {
                                  "type": [
                                    "array",
                                    "null"
                                  ],
                                  "items": {
                                    "type": "string"
                                  },
                                  "description": "The allowed values of an enum field, null for other types."
                                }
                              },
                              "required": [
                                "label",
                                "type",
                                "required",
                                "conditional",
                                "required_if",
                                "choices"
                              ]
                            }
                          },
                          "requirements": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "label": {
                                  "type": "string"
                                },
                                "description": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "accepted_categories": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "min": {
                                  "type": "integer"
                                },
                                "max": {
                                  "type": [
                                    "integer",
                                    "null"
                                  ],
                                  "description": "null = no cap."
                                },
                                "conditional": {
                                  "type": "boolean"
                                },
                                "activation": {
                                  "type": [
                                    "object",
                                    "null"
                                  ],
                                  "description": "null on a plain requirement.",
                                  "properties": {
                                    "condition": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "The condition as written; null unless rule details are enabled."
                                    }
                                  },
                                  "required": [
                                    "condition"
                                  ]
                                },
                                "shareable": {
                                  "type": "boolean"
                                },
                                "presence_only": {
                                  "type": "boolean"
                                },
                                "group": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                }
                              },
                              "required": [
                                "key",
                                "label",
                                "description",
                                "accepted_categories",
                                "min",
                                "max",
                                "conditional",
                                "activation",
                                "shareable",
                                "presence_only",
                                "group"
                              ]
                            }
                          }
                        },
                        "required": [
                          "label",
                          "min",
                          "max",
                          "fields",
                          "requirements"
                        ]
                      }
                    },
                    "rules": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "description": "Stable identifier, the one the dossier's verdict carries."
                          },
                          "label": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "validity",
                              "consistency"
                            ]
                          },
                          "severity": {
                            "type": "string",
                            "enum": [
                              "blocking",
                              "warning"
                            ]
                          },
                          "depends_on": {
                            "type": "array",
                            "description": "What the check reads; a validity check names the requirement it judges first.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "enum": [
                                    "requirement",
                                    "participant",
                                    "dossier"
                                  ]
                                },
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "type",
                                "key"
                              ]
                            }
                          },
                          "agent_review": {
                            "type": "boolean"
                          },
                          "rule": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "code",
                          "label",
                          "kind",
                          "severity",
                          "depends_on",
                          "agent_review",
                          "rule",
                          "description"
                        ]
                      }
                    },
                    "payload_schema": {
                      "type": "object",
                      "description": "JSON Schema (2020-12) of the POST /cases/ request body."
                    }
                  },
                  "required": [
                    "config_id",
                    "name",
                    "fields",
                    "requirements",
                    "participants",
                    "rules",
                    "payload_schema"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The Dossiers feature is not enabled, or an unsupported query parameter was sent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such configuration in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "x-docs-anchor": "management-api",
        "x-docs-page": "/docs/api/v1.1/webhooks/",
        "summary": "List webhook endpoints",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createWebhook",
        "x-docs-anchor": "create-webhook",
        "x-docs-page": "/docs/api/v1.1/webhooks/",
        "x-errors": [
          {
            "code": "INVALID_JSON"
          },
          {
            "code": "MISSING_URL"
          },
          {
            "code": "INVALID_URL"
          },
          {
            "code": "INVALID_NAME"
          },
          {
            "code": "INVALID_EVENTS"
          },
          {
            "code": "WEBHOOK_LIMIT_REACHED"
          }
        ],
        "summary": "Register a webhook endpoint",
        "description": "The signing secret is returned once, on creation only.",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "name": {
                    "type": "string",
                    "default": "API webhook"
                  },
                  "description": {
                    "type": "string"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "workflow-run.completed",
                        "workflow-run.failed",
                        "workflow-run.paused",
                        "workflow-run.confirmed",
                        "workflow-run.republished",
                        "node-run.completed",
                        "node-run.failed",
                        "case.updated",
                        "case.completed"
                      ]
                    }
                  }
                },
                "required": [
                  "url"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The endpoint was registered.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "INVALID_JSON, MISSING_URL, INVALID_URL, INVALID_NAME, INVALID_EVENTS",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "WEBHOOK_LIMIT_REACHED",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/webhooks/{webhook_id}": {
      "get": {
        "operationId": "getWebhook",
        "x-docs-anchor": "management-api",
        "x-docs-page": "/docs/api/v1.1/webhooks/",
        "x-errors": [
          {
            "code": "NOT_FOUND",
            "description": "No webhook endpoint with this ID."
          }
        ],
        "summary": "Get a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateWebhook",
        "x-docs-anchor": "update-webhook",
        "x-docs-page": "/docs/api/v1.1/webhooks/",
        "x-errors": [
          {
            "code": "INVALID_JSON"
          },
          {
            "code": "MISSING_URL"
          },
          {
            "code": "INVALID_URL"
          },
          {
            "code": "INVALID_NAME"
          },
          {
            "code": "INVALID_EVENTS"
          },
          {
            "code": "INVALID_STATUS"
          },
          {
            "code": "NOT_FOUND",
            "description": "No webhook endpoint with this ID."
          }
        ],
        "summary": "Update a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "INVALID_JSON, MISSING_URL, INVALID_URL, INVALID_NAME, INVALID_EVENTS, INVALID_STATUS",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhook",
        "x-docs-anchor": "management-api",
        "x-docs-page": "/docs/api/v1.1/webhooks/",
        "x-errors": [
          {
            "code": "NOT_FOUND",
            "description": "No webhook endpoint with this ID."
          }
        ],
        "summary": "Delete a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "webhook_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/organizations": {
      "get": {
        "operationId": "listOrganizations",
        "x-docs-anchor": "list",
        "x-docs-page": "/docs/api/v1.1/sub-organizations/",
        "x-errors": [
          {
            "code": "NOT_ALLOWED"
          }
        ],
        "summary": "List child organizations",
        "description": "Super partners only.",
        "tags": [
          "Organizations"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createOrganization",
        "x-docs-anchor": "create",
        "x-docs-page": "/docs/api/v1.1/sub-organizations/",
        "x-errors": [
          {
            "code": "NOT_ALLOWED"
          },
          {
            "code": "INVALID_JSON"
          },
          {
            "code": "INVALID_NAME"
          },
          {
            "code": "INVALID_EXTERNAL_REF"
          },
          {
            "code": "INVALID_CLONE_WORKFLOWS"
          },
          {
            "code": "LIMIT_REACHED"
          }
        ],
        "summary": "Create a child organization",
        "tags": [
          "Organizations"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "external_ref": {
                    "type": "string"
                  },
                  "clone_workflows": {
                    "type": "boolean",
                    "default": true
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The organization was created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "INVALID_JSON, INVALID_NAME, INVALID_EXTERNAL_REF, INVALID_CLONE_WORKFLOWS",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "LIMIT_REACHED",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/organizations/{org_id}": {
      "get": {
        "operationId": "getOrganization",
        "x-docs-anchor": "get",
        "x-docs-page": "/docs/api/v1.1/sub-organizations/",
        "x-errors": [
          {
            "code": "NOT_ALLOWED"
          },
          {
            "code": "NOT_FOUND",
            "description": "No child organization with this ID."
          }
        ],
        "summary": "Get a child organization",
        "tags": [
          "Organizations"
        ],
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateOrganization",
        "x-docs-anchor": "update",
        "x-docs-page": "/docs/api/v1.1/sub-organizations/",
        "x-errors": [
          {
            "code": "NOT_ALLOWED"
          },
          {
            "code": "INVALID_JSON"
          },
          {
            "code": "INVALID_NAME"
          },
          {
            "code": "INVALID_STATUS"
          },
          {
            "code": "NOT_FOUND",
            "description": "No child organization with this ID."
          }
        ],
        "summary": "Update a child organization",
        "tags": [
          "Organizations"
        ],
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "INVALID_JSON, INVALID_NAME, INVALID_STATUS",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "INVALID_CASE_ID"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/usage": {
      "get": {
        "operationId": "getUsage",
        "x-docs-anchor": "get-usage-stats",
        "x-docs-page": "/docs/api/v1.1/usage/",
        "summary": "Get usage",
        "description": "Credits consumed over the last 30 days and since the start of the month. Extraction costs 1 credit per page, classification 1 per document, segmentation 1 per operation. Counts update as work completes.",
        "tags": [
          "Organization"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "last_30_days": {
                      "type": "object",
                      "description": "`total`, `extraction`, `classification` and `segmentation` credits."
                    },
                    "since_month_start": {
                      "type": "object",
                      "description": "The same breakdown since the 1st, 00:00 UTC."
                    },
                    "period_start": {
                      "type": "string",
                      "format": "date-time",
                      "description": "The 1st of the month, 00:00 UTC."
                    },
                    "period_end": {
                      "type": "string",
                      "format": "date-time",
                      "description": "When the figures were computed."
                    },
                    "organization": {
                      "type": "string"
                    },
                    "current_plan": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "description": "`type` (`SANDBOX`, `PAY_PER_PAGE`, `STARTER`, `PRO`, `ENTERPRISE`), `name` and `included_credits`. Null without an active plan."
                    },
                    "sandbox": {
                      "type": "object",
                      "description": "Sandbox organizations only: `credits_limit`, `credits_used`, `credits_remaining` and `usage_percentage` (0 to 100). The limit applies at once."
                    }
                  }
                },
                "example": {
                  "last_30_days": {
                    "total": 2534,
                    "extraction": 2456,
                    "classification": 45,
                    "segmentation": 33
                  },
                  "since_month_start": {
                    "total": 948,
                    "extraction": 892,
                    "classification": 32,
                    "segmentation": 24
                  },
                  "period_start": "2025-10-01T00:00:00+00:00",
                  "period_end": "2025-10-15T14:32:45.123456+00:00",
                  "organization": "Acme Corp",
                  "current_plan": {
                    "type": "PRO",
                    "name": "Pro",
                    "included_credits": 100000
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/metrics": {
      "get": {
        "operationId": "getMetrics",
        "x-docs-anchor": "get-metrics",
        "x-docs-page": "/docs/api/v1.1/metrics/",
        "summary": "Get all metrics",
        "description": "Volumes and throughput for one window, in one call: the one to use for a scheduled BI pull. The `volumes` and `throughput` objects hold the fields of the two endpoints below.",
        "tags": [
          "Organization"
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO 8601 date or datetime. Default: 30 days ago.",
            "example": "2026-01-01"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO 8601 date or datetime. Default: now."
          },
          {
            "name": "granularity",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "default": "day"
            },
            "description": "The size of each `series` bucket.",
            "example": "month"
          },
          {
            "name": "include",
            "in": "query",
            "description": "`volumes`, `throughput`, or both comma-separated.",
            "schema": {
              "type": "string",
              "default": "volumes,throughput"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "organization": {
                      "type": "string"
                    },
                    "period_start": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "period_end": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "granularity": {
                      "type": "string"
                    },
                    "volumes": {
                      "type": "object",
                      "description": "As [volume metrics](#get-volumes)."
                    },
                    "throughput": {
                      "type": "object",
                      "description": "As [throughput metrics](#get-throughput)."
                    }
                  }
                },
                "example": {
                  "organization": "Acme Corp",
                  "period_start": "2026-01-01T00:00:00+00:00",
                  "period_end": "2026-09-01T08:14:22.481930+00:00",
                  "granularity": "month",
                  "volumes": {
                    "totals": {
                      "documents": 70,
                      "pages": 678
                    },
                    "by_type": [
                      {
                        "document_category": "relev\u00e9_bancaire",
                        "documents": 57,
                        "pages": 536
                      }
                    ],
                    "by_type_families": [
                      {
                        "family": "bank_statement",
                        "label": "Bank statement",
                        "documents": 58,
                        "pages": 537
                      }
                    ],
                    "series": [
                      {
                        "period": "2026-07-01",
                        "documents": 12,
                        "pages": 140
                      }
                    ]
                  },
                  "throughput": {
                    "totals": {
                      "processed": 64,
                      "completed": 60,
                      "failed": 1
                    },
                    "success_rate": 0.9836,
                    "avg_duration_ms": 41250,
                    "by_channel": [
                      {
                        "channel": "api",
                        "runs": 46
                      }
                    ],
                    "by_status": [
                      {
                        "status": "completed",
                        "runs": 60
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/health": {
      "get": {
        "operationId": "getServiceHealth",
        "x-docs-anchor": "get-health",
        "x-docs-page": "/docs/api/v1.1/health/",
        "summary": "Get service health",
        "description": "Whether Holofin can accept and process work right now. No API key, never rate limited. Answers **200** when `operational` or `degraded`, **503** on `outage`: alert on the status code.",
        "tags": [
          "Organization"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Operational or degraded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "operational",
                        "degraded",
                        "outage"
                      ]
                    },
                    "services": {
                      "type": "object",
                      "properties": {
                        "api": {
                          "type": "string"
                        },
                        "document_intake": {
                          "type": "string"
                        },
                        "processing": {
                          "type": "string"
                        },
                        "webhooks": {
                          "type": "string"
                        }
                      }
                    },
                    "time": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "status": "operational",
                  "services": {
                    "api": "operational",
                    "document_intake": "operational",
                    "processing": "operational",
                    "webhooks": "operational"
                  },
                  "time": "2026-09-01T08:14:22.481930+00:00"
                }
              }
            }
          },
          "503": {
            "description": "Outage: Holofin cannot accept or process work.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "operational",
                        "degraded",
                        "outage"
                      ]
                    },
                    "services": {
                      "type": "object",
                      "properties": {
                        "api": {
                          "type": "string"
                        },
                        "document_intake": {
                          "type": "string"
                        },
                        "processing": {
                          "type": "string"
                        },
                        "webhooks": {
                          "type": "string"
                        }
                      }
                    },
                    "time": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/metrics/volumes": {
      "get": {
        "operationId": "getVolumeMetrics",
        "x-docs-anchor": "get-volumes",
        "x-docs-page": "/docs/api/v1.1/metrics/",
        "summary": "Get volume metrics",
        "description": "Documents and pages processed, by type and over time.",
        "tags": [
          "Organization"
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO 8601 date or datetime. Default: 30 days ago.",
            "example": "2026-01-01"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO 8601 date or datetime. Default: now."
          },
          {
            "name": "granularity",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "default": "day"
            },
            "description": "The size of each `series` bucket.",
            "example": "month"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "organization": {
                      "type": "string"
                    },
                    "period_start": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "period_end": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "granularity": {
                      "type": "string"
                    },
                    "totals": {
                      "type": "object",
                      "description": "`documents` and `pages`."
                    },
                    "by_type": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      },
                      "description": "Per raw classifier code (`document_category`, `documents`, `pages`). Stable keys for data pipelines."
                    },
                    "by_type_families": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      },
                      "description": "Codes folded into business families (`family`, `label`, `documents`, `pages`), as on the in-product dashboard."
                    },
                    "series": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      },
                      "description": "One bucket per period: `period`, `documents`, `pages`."
                    }
                  }
                },
                "example": {
                  "organization": "Acme Corp",
                  "period_start": "2025-01-01T00:00:00+00:00",
                  "period_end": "2026-07-19T14:32:45.123456+00:00",
                  "granularity": "month",
                  "totals": {
                    "documents": 70,
                    "pages": 678
                  },
                  "by_type": [
                    {
                      "document_category": "relev\u00e9_bancaire",
                      "documents": 57,
                      "pages": 536
                    },
                    {
                      "document_category": null,
                      "documents": 5,
                      "pages": 29
                    }
                  ],
                  "by_type_families": [
                    {
                      "family": "bank_statement",
                      "label": "Bank statement",
                      "documents": 58,
                      "pages": 537
                    },
                    {
                      "family": "__unclassified__",
                      "label": "Unclassified",
                      "documents": 5,
                      "pages": 29
                    }
                  ],
                  "series": [
                    {
                      "period": "2026-07-01",
                      "documents": 12,
                      "pages": 140
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1.1/metrics/throughput": {
      "get": {
        "operationId": "getThroughputMetrics",
        "x-docs-anchor": "get-throughput",
        "x-docs-page": "/docs/api/v1.1/metrics/",
        "summary": "Get throughput metrics",
        "description": "Workflow runs by outcome and by ingestion channel, with success rate and average processing time.",
        "tags": [
          "Organization"
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO 8601 date or datetime. Default: 30 days ago.",
            "example": "2026-01-01"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "ISO 8601 date or datetime. Default: now."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "organization": {
                      "type": "string"
                    },
                    "period_start": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "period_end": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "totals": {
                      "type": "object",
                      "description": "`processed` (every run), `completed`, `failed`."
                    },
                    "success_rate": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "Completed over completed plus failed; runs still in flight are left out. Null when nothing has finished."
                    },
                    "avg_duration_ms": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "by_channel": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      },
                      "description": "`channel` and `runs`."
                    },
                    "by_status": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      },
                      "description": "`status` and `runs`."
                    }
                  }
                },
                "example": {
                  "organization": "Acme Corp",
                  "period_start": "2025-01-01T00:00:00+00:00",
                  "period_end": "2026-07-19T14:32:45.123456+00:00",
                  "totals": {
                    "processed": 64,
                    "completed": 60,
                    "failed": 1
                  },
                  "success_rate": 0.9836,
                  "avg_duration_ms": 1258816,
                  "by_channel": [
                    {
                      "channel": "webhook",
                      "runs": 46
                    },
                    {
                      "channel": "manual",
                      "runs": 18
                    }
                  ],
                  "by_status": [
                    {
                      "status": "completed",
                      "runs": 60
                    },
                    {
                      "status": "running",
                      "runs": 3
                    },
                    {
                      "status": "failed",
                      "runs": 1
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Invalid, inactive or expired key, or the caller's IP is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Over 100 requests per minute for this key (plain error, with a Retry-After header), or over the sandbox credit allowance (coded error).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "INVALID_CASE_ID"
                            },
                            "message": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "message"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
}