{
  "openapi": "3.1.0",
  "info": {
    "title": "rows.page API",
    "version": "1.0.0",
    "description": "Push rows from curl, code or agents; explore them in the browser; see what changed between pushes. Anonymous pushes work without an account and return an owner link with a dataset token (rpt_...). All /api/v1 responses allow any origin (CORS *, no credentials). MCP lives at https://rows.page/mcp."
  },
  "servers": [
    {
      "url": "https://rows.page"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key (rpk_...), dataset token (rpt_...) or Firebase ID token"
      },
      "datasetToken": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Rows-Token",
        "description": "Dataset token (rpt_...), e.g. next to a Firebase bearer when keeping a dataset"
      }
    },
    "schemas": {
      "ApiError": {
        "type": "object",
        "required": ["error", "message"],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "bad_format",
              "too_large",
              "upgrade_required",
              "rate_limited",
              "not_found",
              "gone",
              "unauthorized",
              "forbidden",
              "invalid_request",
              "upstream_error",
              "internal"
            ]
          },
          "message": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "hint": {
            "type": "string"
          },
          "reason": {
            "type": "string",
            "enum": ["keep_limit", "private", "locked_version", "file_size", "multipart"]
          },
          "plan_needed": {
            "type": "string",
            "enum": ["pro", "max"]
          },
          "upgrade_url": {
            "type": "string"
          },
          "retry_after": {
            "type": "integer"
          }
        }
      },
      "Column": {
        "type": "object",
        "required": ["name", "type"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Dot path for nested fields"
          },
          "type": {
            "type": "string"
          }
        }
      },
      "PushResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "version": {
            "type": "integer"
          },
          "url": {
            "type": "string"
          },
          "owner_url": {
            "type": ["string", "null"],
            "description": "url#t=<token>; only on creation. Treat like a password."
          },
          "token": {
            "type": ["string", "null"],
            "description": "Dataset token; only on creation"
          },
          "format": {
            "type": "string"
          },
          "bytes": {
            "type": "integer"
          },
          "rows": {
            "type": ["integer", "null"]
          },
          "rows_exact": {
            "type": "boolean"
          },
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Column"
            }
          },
          "expires_at": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "unchanged": {
            "type": "boolean"
          },
          "changes": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "properties": {
                  "previous_version": {
                    "type": "integer"
                  },
                  "rows_delta": {
                    "type": ["integer", "null"]
                  },
                  "columns_added": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "columns_removed": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "diff_url": {
                    "type": "string"
                  }
                }
              }
            ]
          },
          "keep": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "properties": {
                  "required": {
                    "type": "boolean"
                  },
                  "url": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              }
            ]
          },
          "limits": {
            "type": "object",
            "properties": {
              "plan": {
                "type": "string"
              },
              "max_file_bytes": {
                "type": "integer"
              },
              "datasets_used": {
                "type": ["integer", "null"]
              },
              "datasets_limit": {
                "type": ["integer", "null"]
              }
            }
          }
        }
      },
      "DatasetMeta": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "title": {
            "type": ["string", "null"]
          },
          "summary": {
            "type": ["string", "null"]
          },
          "visibility": {
            "type": "string",
            "enum": ["public", "private"]
          },
          "id_column": {
            "type": ["string", "null"]
          },
          "latest_version": {
            "type": "integer"
          },
          "source_url": {
            "type": ["string", "null"]
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "expires_at": {
            "type": ["string", "null"]
          },
          "owned": {
            "type": "boolean"
          },
          "key": {
            "type": ["string", "null"]
          }
        }
      },
      "Finding": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "version": {
            "type": ["integer", "null"]
          },
          "title": {
            "type": "string"
          },
          "note": {
            "type": ["string", "null"]
          },
          "view": {
            "type": "object",
            "properties": {
              "q": {
                "type": "string"
              },
              "sort": {
                "type": "string"
              },
              "cols": {
                "type": "string"
              },
              "sql": {
                "type": "string"
              }
            }
          },
          "row_count": {
            "type": ["integer", "null"]
          },
          "position": {
            "type": "integer"
          },
          "created_via": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        }
      },
      "FindingInput": {
        "type": "object",
        "required": ["title"],
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 200
          },
          "note": {
            "type": ["string", "null"],
            "maxLength": 4000
          },
          "q": {
            "type": "string",
            "description": "rows.page query language, e.g. country:NL price:>20"
          },
          "sort": {
            "type": "string",
            "description": "e.g. -price,name"
          },
          "cols": {
            "type": "string",
            "description": "e.g. id,price"
          },
          "sql": {
            "type": "string",
            "description": "SQL against the table data"
          },
          "version": {
            "type": ["integer", "null"]
          },
          "row_count": {
            "type": ["integer", "null"]
          }
        }
      },
      "DatasetResponse": {
        "type": "object",
        "properties": {
          "dataset": {
            "$ref": "#/components/schemas/DatasetMeta"
          },
          "version": {
            "type": "object",
            "description": "Requested (or latest) version with data_url, raw_url, locked, purged"
          },
          "versions": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Newest first"
          },
          "findings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Finding"
            }
          },
          "preview": {
            "type": ["object", "null"],
            "properties": {
              "columns": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Column"
                }
              },
              "rows": {
                "type": "array",
                "items": {
                  "type": "array"
                }
              },
              "truncated": {
                "type": "boolean"
              },
              "json_path": {
                "type": ["string", "null"]
              }
            }
          },
          "viewer": {
            "type": "object",
            "properties": {
              "is_owner": {
                "type": "boolean"
              },
              "plan": {
                "type": ["string", "null"]
              }
            }
          }
        }
      },
      "ApiKeyInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "label": {
            "type": ["string", "null"]
          },
          "created_at": {
            "type": "string"
          },
          "last_used_at": {
            "type": ["string", "null"]
          }
        }
      }
    }
  },
  "paths": {
    "/{name}": {
      "put": {
        "summary": "Push from curl",
        "operationId": "putPush",
        "description": "curl -T data.csv https://rows.page. PUT /<id>[/<name>] pushes a new version. Parameters also work as X-Rows-* headers (X-Rows-Title, X-Rows-Id-Column, ...). Plain-text answer unless Accept: application/json or ?json=1. Chunked bodies (curl -T -) are fine.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "File name, dataset id, or -"
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["csv", "tsv", "json", "jsonl", "ndjson", "parquet"]
            },
            "description": "Decides the parse; otherwise the file extension, then Content-Type, then content sniffing"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "File name, e.g. orders.csv"
          },
          {
            "name": "title",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Dataset title (max 200)"
          },
          {
            "name": "summary",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "What this is and what to look at (max 4000)"
          },
          {
            "name": "key",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._-]{1,100}$"
            },
            "description": "Upsert one named dataset per account (API key required)"
          },
          {
            "name": "id_column",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Column identifying a row across versions, for changed-row diffs"
          },
          {
            "name": "dataset",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Push a new version of this dataset (needs its token or the owning account)"
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Where the data came from"
          },
          {
            "name": "run",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Run id of the producing job"
          },
          {
            "name": "commit",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Commit sha of the producing code"
          },
          {
            "name": "visibility",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["public", "private"]
            },
            "description": "private needs Pro or Max"
          },
          {
            "name": "json",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["1", "true"]
            },
            "description": "PUT only: answer with JSON instead of plain text"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "*/*": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          },
          "description": "The file as the raw request body (not multipart/form-data)"
        },
        "security": [
          {},
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "responses": {
          "201": {
            "description": "New dataset",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushResponse"
                }
              }
            }
          },
          "200": {
            "description": "New version, or unchanged: true when the bytes match the latest version",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushResponse"
                }
              }
            }
          },
          "402": {
            "description": "Upgrade required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "413": {
            "description": "Too large for a single request or the plan; the message names the multipart API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited or daily anonymous quota reached",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/push": {
      "post": {
        "summary": "Push a file",
        "operationId": "push",
        "description": "Same as PUT, always JSON. ?format= decides the parse regardless of Content-Type.",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["csv", "tsv", "json", "jsonl", "ndjson", "parquet"]
            },
            "description": "Decides the parse; otherwise the file extension, then Content-Type, then content sniffing"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "File name, e.g. orders.csv"
          },
          {
            "name": "title",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Dataset title (max 200)"
          },
          {
            "name": "summary",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "What this is and what to look at (max 4000)"
          },
          {
            "name": "key",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._-]{1,100}$"
            },
            "description": "Upsert one named dataset per account (API key required)"
          },
          {
            "name": "id_column",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Column identifying a row across versions, for changed-row diffs"
          },
          {
            "name": "dataset",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Push a new version of this dataset (needs its token or the owning account)"
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Where the data came from"
          },
          {
            "name": "run",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Run id of the producing job"
          },
          {
            "name": "commit",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Commit sha of the producing code"
          },
          {
            "name": "visibility",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["public", "private"]
            },
            "description": "private needs Pro or Max"
          },
          {
            "name": "json",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["1", "true"]
            },
            "description": "PUT only: answer with JSON instead of plain text"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "*/*": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          },
          "description": "The file as the raw request body (not multipart/form-data)"
        },
        "security": [
          {},
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "responses": {
          "201": {
            "description": "New dataset",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushResponse"
                }
              }
            }
          },
          "200": {
            "description": "New version, or unchanged: true when the bytes match the latest version",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushResponse"
                }
              }
            }
          },
          "402": {
            "description": "Upgrade required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "413": {
            "description": "Too large for a single request or the plan; the message names the multipart API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited or daily anonymous quota reached",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/datasets": {
      "get": {
        "summary": "List my datasets",
        "operationId": "listDatasets",
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Newest first, 50 per page",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "datasets": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "next_cursor": {
                      "type": ["string", "null"]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/datasets/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[a-z0-9]{10}$"
          },
          "description": "Dataset id"
        }
      ],
      "get": {
        "summary": "Dataset with latest version, versions, findings and preview",
        "operationId": "getDataset",
        "security": [
          {},
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update title, summary, id_column, visibility",
        "operationId": "updateDataset",
        "security": [
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": ["string", "null"]
                  },
                  "summary": {
                    "type": ["string", "null"]
                  },
                  "id_column": {
                    "type": ["string", "null"]
                  },
                  "visibility": {
                    "type": "string",
                    "enum": ["public", "private"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetMeta"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete (owner or admin)",
        "operationId": "deleteDataset",
        "security": [
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/datasets/{id}/versions/{n}": {
      "get": {
        "summary": "One version with preview",
        "operationId": "getVersion",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Dataset id"
          },
          {
            "name": "n",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Version number"
          }
        ],
        "security": [
          {},
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetResponse"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/datasets/{id}/versions/{n}/data": {
      "get": {
        "summary": "Version bytes",
        "operationId": "getVersionData",
        "description": "Immutable for public datasets; supports Range and If-None-Match.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Dataset id"
          },
          {
            "name": "n",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Version number"
          },
          {
            "name": "Range",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "bytes=start-end, bytes=start- or bytes=-suffix"
          }
        ],
        "security": [
          {},
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "File bytes",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                }
              },
              "Accept-Ranges": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "Partial content (single Range)",
            "headers": {
              "Content-Range": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match)"
          },
          "402": {
            "description": "Version locked on the owner's plan (reason locked_version)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "416": {
            "description": "Range not satisfiable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/{id}/raw": {
      "get": {
        "summary": "Latest version bytes",
        "operationId": "rawLatest",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Dataset id"
          },
          {
            "name": "Range",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "bytes=start-end, bytes=start- or bytes=-suffix"
          }
        ],
        "security": [
          {},
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "File bytes",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                }
              },
              "Accept-Ranges": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "Partial content (single Range)",
            "headers": {
              "Content-Range": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match)"
          },
          "402": {
            "description": "Version locked on the owner's plan (reason locked_version)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "416": {
            "description": "Range not satisfiable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "description": "Append the format extension (`/raw.csv`, `/raw.parquet`, `/raw.jsonl`, ...) so tools like DuckDB can pick a reader from the URL: `select * from 'https://rows.page/<id>/raw.csv'`. A mismatched extension returns 404 naming the right one."
      }
    },
    "/{id}/v{n}/raw": {
      "get": {
        "summary": "Version bytes",
        "operationId": "rawVersion",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Dataset id"
          },
          {
            "name": "n",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Version number"
          },
          {
            "name": "Range",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "bytes=start-end, bytes=start- or bytes=-suffix"
          }
        ],
        "security": [
          {},
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "File bytes",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                }
              },
              "Accept-Ranges": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "Partial content (single Range)",
            "headers": {
              "Content-Range": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match)"
          },
          "402": {
            "description": "Version locked on the owner's plan (reason locked_version)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "416": {
            "description": "Range not satisfiable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        },
        "description": "Append the format extension (`/raw.csv`, `/raw.parquet`, `/raw.jsonl`, ...) so tools like DuckDB can pick a reader from the URL: `select * from 'https://rows.page/<id>/raw.csv'`. A mismatched extension returns 404 naming the right one."
      }
    },
    "/api/v1/datasets/{id}/findings": {
      "post": {
        "summary": "Pin a finding",
        "operationId": "createFinding",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Dataset id"
          }
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FindingInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Finding"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/datasets/{id}/findings/{fid}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[a-z0-9]{10}$"
          },
          "description": "Dataset id"
        },
        {
          "name": "fid",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "patch": {
        "summary": "Edit a finding",
        "operationId": "updateFinding",
        "security": [
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FindingInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Finding"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Remove a finding",
        "operationId": "deleteFinding",
        "security": [
          {
            "bearer": []
          },
          {
            "datasetToken": []
          }
        ],
        "responses": {
          "204": {
            "description": "Removed"
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/datasets/{id}/keep": {
      "post": {
        "summary": "Keep an anonymous dataset on your account",
        "operationId": "keepDataset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Dataset id"
          }
        ],
        "description": "Signed in (Bearer) plus the dataset token in X-Rows-Token. Clears the expiry, or 402 keep_limit when the plan's datasets are used up.",
        "security": [
          {
            "bearer": [],
            "datasetToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Kept",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetMeta"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/datasets/{id}/report": {
      "post": {
        "summary": "Report abuse",
        "operationId": "reportDataset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Dataset id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["reason"],
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "email": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Reported"
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me": {
      "get": {
        "summary": "Account, plan, limits, usage",
        "operationId": "getMe",
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/keys": {
      "get": {
        "summary": "List API keys",
        "operationId": "listKeys",
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ApiKeyInfo"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create an API key (shown once)",
        "operationId": "createKey",
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": ["string", "null"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiKeyInfo"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/keys/{keyId}": {
      "delete": {
        "summary": "Revoke an API key",
        "operationId": "deleteKey",
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Revoked"
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/uploads": {
      "post": {
        "summary": "Start a multipart upload (Pro/Max, files over 100 MB)",
        "operationId": "createUpload",
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["csv", "tsv", "json", "jsonl", "ndjson", "parquet"]
            },
            "description": "Decides the parse; otherwise the file extension, then Content-Type, then content sniffing"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "File name, e.g. orders.csv"
          },
          {
            "name": "title",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Dataset title (max 200)"
          },
          {
            "name": "summary",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "What this is and what to look at (max 4000)"
          },
          {
            "name": "key",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._-]{1,100}$"
            },
            "description": "Upsert one named dataset per account (API key required)"
          },
          {
            "name": "id_column",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Column identifying a row across versions, for changed-row diffs"
          },
          {
            "name": "dataset",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]{10}$"
            },
            "description": "Push a new version of this dataset (needs its token or the owning account)"
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Where the data came from"
          },
          {
            "name": "run",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Run id of the producing job"
          },
          {
            "name": "commit",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Commit sha of the producing code"
          },
          {
            "name": "visibility",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["public", "private"]
            },
            "description": "private needs Pro or Max"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "bytes": {
                    "type": "integer",
                    "description": "Total size, checked against the plan cap"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "upload_id": {
                      "type": "string"
                    },
                    "dataset_id": {
                      "type": "string"
                    },
                    "part_bytes": {
                      "type": "integer"
                    },
                    "max_bytes": {
                      "type": "integer"
                    },
                    "part_url": {
                      "type": "string"
                    },
                    "complete_url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "413": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/uploads/{uploadId}/{part}": {
      "put": {
        "summary": "Upload one part",
        "operationId": "uploadPart",
        "security": [
          {
            "bearer": []
          }
        ],
        "description": "Parts are numbered from 1; every part except the last must have the same size (part_bytes, at least 5 MiB). Content-Length is required.",
        "parameters": [
          {
            "name": "uploadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "part",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "*/*": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          },
          "description": "The file as the raw request body (not multipart/form-data)"
        },
        "responses": {
          "200": {
            "description": "Stored",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "411": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "413": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/uploads/{uploadId}/complete": {
      "post": {
        "summary": "Finish a multipart upload",
        "operationId": "completeUpload",
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "uploadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "New dataset",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushResponse"
                }
              }
            }
          },
          "200": {
            "description": "New version or unchanged",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushResponse"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "410": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/fetch": {
      "get": {
        "summary": "Fetch a public file for remote mode",
        "operationId": "fetchRemote",
        "description": "For sources without CORS. http(s) only, private and local addresses blocked, 5 redirects, 30 s, 100 MB. Always application/octet-stream.",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Bytes",
            "headers": {
              "X-Rows-Final-Url": {
                "schema": {
                  "type": "string"
                }
              },
              "X-Rows-Upstream-Type": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "413": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "502": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "504": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/events": {
      "post": {
        "summary": "Client funnel events",
        "operationId": "events",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Recorded"
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/interest": {
      "post": {
        "summary": "Register interest in an upcoming feature",
        "operationId": "interest",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["feature"],
                "properties": {
                  "feature": {
                    "type": "string",
                    "enum": ["watch", "track", "private", "history"]
                  },
                  "dataset_id": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Recorded"
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/billing/checkout": {
      "post": {
        "summary": "Start a checkout",
        "operationId": "checkout",
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["plan"],
                "properties": {
                  "plan": {
                    "type": "string",
                    "enum": ["pro", "max"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Redirect URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "502": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/billing/portal": {
      "post": {
        "summary": "Open the billing portal",
        "operationId": "billingPortal",
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Redirect URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "502": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/health": {
      "get": {
        "summary": "Health",
        "operationId": "health",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "version": {
                      "type": ["string", "null"]
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
