{
  "openapi": "3.1.0",
  "info": {
    "title": "Sorzio Platform API",
    "version": "1.0.0",
    "description": "Evidence-backed data operations API: verbatim-quoted claims, content-addressed snapshots, customer schemas, immutable versioned flows, calibrated quality, identity-safe matching, isolated sub-workspaces, and subject erasure."
  },
  "servers": [
    {
      "url": "https://www.sorzio.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "BearerApiKey": []
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sz_live_<48hex>",
        "description": "Workspace or platform_parent API key passed as Authorization: Bearer sz_live_..."
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object"
              }
            }
          }
        }
      },
      "Claim": {
        "type": "object",
        "required": [
          "id",
          "job_id",
          "row_key",
          "subject_ref",
          "field",
          "value",
          "evidence_quote",
          "source",
          "method",
          "flow_version",
          "verification",
          "acceptance_status",
          "retrieved_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "job_id": {
            "type": "string",
            "format": "uuid"
          },
          "row_key": {
            "type": "string"
          },
          "subject_ref": {
            "type": "string",
            "description": "Customer entity key or NEW:<temp> proposal."
          },
          "field": {
            "type": "string"
          },
          "value": {},
          "evidence_quote": {
            "type": "string",
            "maxLength": 2000
          },
          "source": {
            "type": "object",
            "required": [
              "kind",
              "ref",
              "snapshot"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "url",
                  "document",
                  "row_column",
                  "connector"
                ]
              },
              "ref": {
                "type": "string"
              },
              "snapshot": {
                "type": "object",
                "required": [
                  "hash",
                  "url",
                  "byte_length"
                ],
                "properties": {
                  "hash": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  },
                  "byte_length": {
                    "type": "integer"
                  }
                }
              }
            }
          },
          "method": {
            "type": "string",
            "enum": [
              "provider",
              "model",
              "rule"
            ]
          },
          "model": {
            "type": [
              "string",
              "null"
            ]
          },
          "temperature": {
            "type": [
              "number",
              "null"
            ]
          },
          "prompt_version": {
            "type": [
              "string",
              "null"
            ]
          },
          "flow_version": {
            "type": "integer"
          },
          "verification": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "supported",
                  "unsupported",
                  "unverified"
                ]
              },
              "verifier_model": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "rationale": {
                "type": "string"
              },
              "checked_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            }
          },
          "acceptance_status": {
            "type": "string",
            "enum": [
              "auto_accepted",
              "needs_review",
              "rejected"
            ]
          },
          "retrieved_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CandidateEntity": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "domain": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "linkedin_url": {
            "type": "string"
          },
          "company": {
            "type": "string"
          }
        }
      }
    }
  },
  "paths": {
    "/v1/openapi.json": {
      "get": {
        "summary": "Fetch OpenAPI 3.1 specification",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI document"
          }
        }
      }
    },
    "/v1/workspaces": {
      "get": {
        "summary": "List caller workspace and provisioned sub-workspaces",
        "responses": {
          "200": {
            "description": "Workspaces list"
          }
        }
      },
      "post": {
        "summary": "Provision an isolated client sub-workspace",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "slug",
                  "name"
                ],
                "properties": {
                  "slug": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "org_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "identity_mode": {
                    "type": "string",
                    "enum": [
                      "customer_owned",
                      "sorzio_managed"
                    ]
                  },
                  "retention_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3650
                  },
                  "row_limit_monthly": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1
                  },
                  "spend_limit_cents": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 0
                  },
                  "refused_data_classes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Provisioned sub-workspace, API key, and webhook secret"
          },
          "403": {
            "description": "Forbidden"
          }
        }
      }
    },
    "/v1/workspaces/{w}": {
      "get": {
        "summary": "Get workspace settings and usage metering summary",
        "parameters": [
          {
            "name": "w",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace and usage counters"
          }
        }
      },
      "patch": {
        "summary": "Update per-workspace retention, limits, identity mode, or refused data classes",
        "parameters": [
          {
            "name": "w",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated workspace"
          }
        }
      }
    },
    "/v1/workspaces/{w}/keys": {
      "get": {
        "summary": "List workspace API key metadata",
        "parameters": [
          {
            "name": "w",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "API keys metadata"
          }
        }
      },
      "post": {
        "summary": "Mint an isolated API key for a workspace",
        "parameters": [
          {
            "name": "w",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created API key secret"
          }
        }
      }
    },
    "/v1/workspaces/{w}/keys/{keyId}": {
      "delete": {
        "summary": "Revoke a workspace API key immediately",
        "parameters": [
          {
            "name": "w",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked API key metadata"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/v1/workspaces/{w}/webhook-secret/rotate": {
      "post": {
        "summary": "Rotate the HMAC-SHA256 webhook signing secret for a workspace",
        "parameters": [
          {
            "name": "w",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rotated webhook secret"
          }
        }
      }
    },
    "/v1/workspaces/{w}/usage": {
      "get": {
        "summary": "Get UTC-month and lifetime row, claim, and billed-cents metering for a workspace",
        "parameters": [
          {
            "name": "w",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace usage metering summary"
          }
        }
      }
    },
    "/v1/workspaces/{w}/audit-logs": {
      "get": {
        "summary": "List workspace audit trail of published versions, runs, and erasure receipts",
        "parameters": [
          {
            "name": "w",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Audit log entries"
          }
        }
      }
    },
    "/v1/workspaces/{w}/subjects/{key}": {
      "delete": {
        "summary": "Erase all inputs, snapshots, claims, matches, and logs for a subject",
        "parameters": [
          {
            "name": "w",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion confirmation id and deleted store counts"
          }
        }
      }
    },
    "/v1/schemas": {
      "get": {
        "summary": "List workspace output schemas",
        "responses": {
          "200": {
            "description": "Schemas"
          }
        }
      },
      "post": {
        "summary": "Define or update a workspace output schema and controlled vocabularies",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "schema_key"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Saved schema"
          }
        }
      }
    },
    "/v1/schemas/templates": {
      "get": {
        "summary": "List starter output schema templates",
        "responses": {
          "200": {
            "description": "Starter templates"
          }
        }
      }
    },
    "/v1/flows/{id}/versions": {
      "get": {
        "summary": "List immutable versions published for a flow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Flow versions"
          }
        }
      }
    },
    "/v1/flows/{id}/versions/{v}": {
      "get": {
        "summary": "Get an immutable flow version definition and content hash",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "v",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Flow version"
          },
          "404": {
            "description": "Not found"
          }
        }
      },
      "put": {
        "summary": "Publish an immutable flow version with changelog and SHA-256 content hash",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "v",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "definition"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent match"
          },
          "201": {
            "description": "Published"
          },
          "409": {
            "description": "Refused: version_immutable"
          }
        }
      }
    },
    "/v1/flows/{id}/gold-sets": {
      "get": {
        "summary": "List labelled gold sets uploaded for a flow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Gold sets"
          }
        }
      },
      "post": {
        "summary": "Upload labelled gold-set examples for flow evaluation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "examples"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Uploaded gold set"
          }
        }
      }
    },
    "/v1/flows/{id}/auto-accept-policy": {
      "put": {
        "summary": "Configure calibrated per-field auto-accept precision, Wilson lower bound, and minimum label thresholds",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Updated auto-accept policy"
          }
        }
      }
    },
    "/v1/flows/{id}/versions/{v}/evals": {
      "post": {
        "summary": "Run an evaluation computing per-field precision, recall, Wilson 95% intervals, and run-to-run agreement",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "v",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "gold_set_id"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Completed evaluation run"
          }
        }
      }
    },
    "/v1/flows/{id}/versions/{v}/bakeoffs": {
      "post": {
        "summary": "Run a multi-model bake-off across >= 2 models and pick per-field winners",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "v",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "gold_set_id"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Completed model bake-off"
          }
        }
      }
    },
    "/v1/flows/{id}/versions/{v}/quality": {
      "get": {
        "summary": "Get calibrated quality metrics, Wilson 95% intervals, run-to-run agreement, bake-off winners, and auto-accept policy",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "v",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Quality summary"
          }
        }
      }
    },
    "/v1/jobs": {
      "post": {
        "summary": "Submit an idempotent extraction job for flow@version (sync <= 10 rows, async > 10 rows)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "flow",
                  "idempotency_key",
                  "rows"
                ],
                "properties": {
                  "flow": {
                    "type": "string"
                  },
                  "idempotency_key": {
                    "type": "string"
                  },
                  "rows": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "mode": {
                        "type": "string",
                        "enum": [
                          "auto",
                          "sync",
                          "async"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay"
          },
          "201": {
            "description": "Completed synchronous job"
          },
          "202": {
            "description": "Queued asynchronous job"
          },
          "402": {
            "description": "Insufficient balance or workspace spend limit exceeded"
          },
          "429": {
            "description": "Limit exceeded"
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "summary": "Get job status, counts, per-row errors, job-level connector errors, and quality summary",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job details"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/v1/jobs/{id}/cancel": {
      "post": {
        "summary": "Cancel a queued or running job and settle only completed rows",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancelled or terminal job state"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/v1/jobs/{id}/results": {
      "get": {
        "summary": "Get cursor-paginated evidence-backed claims (or format=flat rows)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "claims",
                "flat"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated claims"
          }
        }
      }
    },
    "/v1/snapshots/{hash}": {
      "get": {
        "summary": "Fetch exact workspace-scoped source text snapshot by SHA-256 hash",
        "parameters": [
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Snapshot text and metadata"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/v1/match": {
      "post": {
        "summary": "Run identity-safe candidate matching in customer_owned or sorzio_managed mode",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "rows"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Identity match decisions and NEW: proposals"
          }
        }
      }
    }
  },
  "webhooks": {
    "jobCompleted": {
      "post": {
        "summary": "Signed job.completed webhook (Sorzio-Signature: t=<unix>,v1=<hmac_sha256(timestamp + '.' + body)>, 300s replay window)",
        "responses": {
          "200": {
            "description": "Webhook acknowledged"
          }
        }
      }
    }
  }
}
