{"openapi":"3.1.0","info":{"title":"Altertable Lakehouse API","description":"API for data lakehouse operations including querying, upserting, and SQL sanitization","license":{"name":"MIT","url":"https://opensource.org/licenses/MIT"},"version":"0.1.0"},"paths":{"/append":{"post":{"tags":["Lakehouse"],"operationId":"append","parameters":[{"name":"catalog","in":"query","description":"Name of the catalog to append data to","required":true,"schema":{"type":"string"}},{"name":"schema","in":"query","description":"Name of the schema to append data to","required":true,"schema":{"type":"string"}},{"name":"table","in":"query","description":"Name of the table to append to","required":true,"schema":{"type":"string"}},{"name":"sync","in":"query","description":"When true, wait for the task to complete before returning","required":false,"schema":{"type":"boolean"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppendRequest"}}},"required":true},"responses":{"200":{"description":"Append data to a table","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppendResponse"},"example":{"error_code":null,"ok":true,"task_id":"019f992b-58b0-7682-87b6-d5eaebed23ae"}}}},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"}},"security":[{"basic_auth":[]}]}},"/autocomplete":{"post":{"tags":["Lakehouse"],"operationId":"autocomplete","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutocompleteRequest"}}},"required":true},"responses":{"200":{"description":"SQL autocomplete suggestions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutocompleteResponse"},"example":{"connections_errors":{},"statement":"SEL","suggestions":[]}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"Authentication required"}},"security":[{"basic_auth":[]}]}},"/explain":{"post":{"tags":["Lakehouse"],"operationId":"explain","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExplainRequest"}}},"required":true},"responses":{"200":{"description":"Explain result for the SQL statement","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExplainResponse"},"example":{"connections_errors":{},"statement":"SELECT * FROM users WHERE age > 25","tables":[]}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"Authentication required"}},"security":[{"basic_auth":[]}]}},"/query":{"post":{"tags":["Lakehouse"],"operationId":"query","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryRequest"}}},"required":true},"responses":{"200":{"description":"Execute a SQL query and return streaming data in the requested format","content":{"application/x-ndjson":{"schema":{"type":"string"},"example":"{\"statement\":\"SELECT 1\",\"rows_limit\":null,\"rows_offset\":null,\"init_time_ms\":0,\"connections_errors\":{},\"session_id\":\"123e4567-e89b-12d3-a456-426614174000\",\"query_id\":\"123e4567-e89b-12d3-a456-426614174000\",\"worker_slug\":\"worker-abc\"}\n[\"1\"]\n[1]\n"}}},"400":{"description":"Invalid SQL query or sanitization failed"},"401":{"description":"Authentication required"}},"security":[{"basic_auth":[]}]}},"/query/{query_id}":{"get":{"tags":["Lakehouse"],"operationId":"get","parameters":[{"name":"query_id","in":"path","description":"Query ID to get","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Query log","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryLogResponse"}}}},"401":{"description":"Authentication required"},"404":{"description":"Query not found"}},"security":[{"basic_auth":[]}]},"delete":{"tags":["Lakehouse"],"operationId":"cancel","parameters":[{"name":"query_id","in":"path","description":"Query ID to cancel","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"session_id","in":"query","description":"Session ID that owns the query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Query cancellation response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelQueryResponse"}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"Authentication required"},"404":{"description":"Session not found"}},"security":[{"basic_auth":[]}]}},"/tasks/{task_id}":{"get":{"tags":["Lakehouse"],"operationId":"get_task","parameters":[{"name":"task_id","in":"path","description":"Task ID returned by the /append endpoint","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Task status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskResponse"}}}},"400":{"description":"Invalid task ID"},"401":{"description":"Authentication required"}},"security":[{"basic_auth":[]}]}},"/upload":{"post":{"tags":["Lakehouse"],"operationId":"upload","parameters":[{"name":"catalog","in":"query","description":"Name of the catalog to ingest data into","required":true,"schema":{"type":"string"}},{"name":"schema","in":"query","description":"Name of the schema within the catalog","required":true,"schema":{"type":"string"}},{"name":"table","in":"query","description":"Name of the table to create or insert into","required":true,"schema":{"type":"string"}},{"name":"mode","in":"query","description":"How data is inserted (create, append, overwrite)","required":true,"schema":{"$ref":"#/components/schemas/UploadMode"}}],"requestBody":{"description":"File data in the specified format (CSV, JSON, or Parquet)","content":{"application/octet-stream":{"schema":{"type":"array","items":{"type":"integer","format":"int32","minimum":0}}}},"required":true},"responses":{"200":{"description":"File uploaded successfully"},"400":{"description":"Invalid request (e.g., malformed file)"},"401":{"description":"Authentication required"}},"security":[{"basic_auth":[]}]}},"/upsert":{"post":{"tags":["Lakehouse"],"operationId":"upsert","parameters":[{"name":"catalog","in":"query","description":"Name of the catalog to ingest data into","required":true,"schema":{"type":"string"}},{"name":"schema","in":"query","description":"Name of the schema within the catalog","required":true,"schema":{"type":"string"}},{"name":"table","in":"query","description":"Name of the table to upsert into","required":true,"schema":{"type":"string"}},{"name":"primary_key","in":"query","description":"Primary key column name used to match and update existing rows","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"File data in the specified format (CSV, JSON, or Parquet)","content":{"application/octet-stream":{"schema":{"type":"array","items":{"type":"integer","format":"int32","minimum":0}}}},"required":true},"responses":{"200":{"description":"File upserted successfully"},"400":{"description":"Invalid request (e.g., malformed file or missing primary_key)"},"401":{"description":"Authentication required"}},"security":[{"basic_auth":[]}]}},"/validate":{"post":{"tags":["Lakehouse"],"operationId":"validate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateRequest"}}},"required":true},"responses":{"200":{"description":"Validation result for the SQL statement","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateResponse"},"example":{"connections_errors":{},"statement":"SELECT * FROM users","valid":true}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"Authentication required"}},"security":[{"basic_auth":[]}]}}},"components":{"schemas":{"AppendErrorCode":{"type":"string","enum":["invalid-data","incompatible-schema"]},"AppendParams":{"type":"object","description":"Query parameters for append","required":["catalog","schema","table"],"properties":{"catalog":{"type":"string","description":"Name of the catalog to append data to","example":"my_catalog"},"schema":{"type":"string","description":"Name of the schema within the catalog","example":"public"},"sync":{"type":"boolean","description":"When true, wait for the task to complete before returning"},"table":{"type":"string","description":"Name of the table to append to","example":"users"}}},"AppendPayload":{"type":"object","additionalProperties":{},"propertyNames":{"type":"string"}},"AppendRequest":{"oneOf":[{"$ref":"#/components/schemas/AppendPayload"},{"type":"array","items":{"$ref":"#/components/schemas/AppendPayload"}}]},"AppendResponse":{"type":"object","description":"Response from appending data","required":["ok"],"properties":{"error_code":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/AppendErrorCode","description":"Error code if the data was not successfully appended"}]},"error_message":{"type":["string","null"],"description":"Human-readable error message if the data was not successfully appended"},"ok":{"type":"boolean","description":"Indicates whether the data was successfully enqueued for processing"},"task_id":{"type":["string","null"],"format":"uuid","description":"Task ID that can be used to track the processing status of this batch via GET /tasks/{task_id}"}}},"AutocompleteRequest":{"type":"object","description":"Request for SQL autocomplete suggestions","required":["statement"],"properties":{"catalog":{"type":["string","null"],"description":"Catalog name (optional)","example":"my_catalog"},"max_suggestions":{"type":["integer","null"],"format":"int32","description":"Maximum number of suggestions to return (default 20, max 200)","minimum":0},"schema":{"type":["string","null"],"description":"Schema name (optional)","example":"public"},"session_id":{"type":["string","null"],"description":"Session ID to use (optional)","example":"123e4567-e89b-12d3-a456-426614174000"},"statement":{"type":"string","description":"Partial SQL statement to complete","example":"SELECT ma"}}},"AutocompleteResponse":{"type":"object","description":"Response with autocomplete suggestions","required":["suggestions","statement","connections_errors"],"properties":{"connections_errors":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"statement":{"type":"string"},"suggestions":{"type":"array","items":{"$ref":"#/components/schemas/AutocompleteSuggestion"}}}},"AutocompleteSuggestion":{"type":"object","description":"One row from DuckDB `sql_smart_auto_complete`","required":["suggestion","suggestion_start","suggestion_type","suggestion_score"],"properties":{"extra_char":{"type":["string","null"]},"suggestion":{"type":"string"},"suggestion_score":{"type":"integer","format":"int64","minimum":0},"suggestion_start":{"type":"integer","format":"int32"},"suggestion_type":{"type":"string"}}},"CachingStats":{"type":"object","required":["data_hits","data_misses","data_bytes_hits","data_bytes_misses","filehandle_hits","filehandle_misses","metadata_hits","metadata_misses"],"properties":{"data_bytes_hits":{"type":"integer","format":"int64","minimum":0},"data_bytes_misses":{"type":"integer","format":"int64","minimum":0},"data_hits":{"type":"integer","format":"int64","minimum":0},"data_misses":{"type":"integer","format":"int64","minimum":0},"filehandle_hits":{"type":"integer","format":"int64","minimum":0},"filehandle_misses":{"type":"integer","format":"int64","minimum":0},"metadata_hits":{"type":"integer","format":"int64","minimum":0},"metadata_misses":{"type":"integer","format":"int64","minimum":0}}},"CancelQueryResponse":{"type":"object","required":["cancelled","message"],"properties":{"cancelled":{"type":"boolean"},"message":{"type":"string"}}},"ComputeSize":{"type":"string","description":"Compute size for the query (XS, S, M, L, XL, or AUTO to infer it)","enum":["XS","S","M","L","XL","AUTO"]},"ExplainRequest":{"type":"object","description":"Request to explain a SQL statement and get scan estimates","required":["statement"],"properties":{"catalog":{"type":["string","null"],"description":"Catalog name to use for the explain operation","example":"my_catalog"},"include_plan":{"type":"boolean","description":"Whether to include the raw EXPLAIN plan in the response"},"schema":{"type":["string","null"],"description":"Schema name to use for the explain operation","example":"public"},"session_id":{"type":["string","null"],"description":"Session ID to use for the explain operation","example":"123e4567-e89b-12d3-a456-426614174000"},"statement":{"type":"string","description":"SQL statement to explain","example":"SELECT * FROM users WHERE age > 25"}}},"ExplainResponse":{"type":"object","description":"Response from SQL explain","required":["tables","statement","connections_errors"],"properties":{"connections_errors":{"type":"object","description":"Connection errors for attached catalogs","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"error":{"type":["string","null"],"description":"Error message if the explain failed"},"plan":{"description":"Raw EXPLAIN JSON plan (wrapped in array for API compatibility)"},"scanned_bytes_estimate":{"type":["integer","null"],"format":"int64","description":"Estimated bytes to scan after filter pruning","minimum":0},"scanned_files_estimate":{"type":["integer","null"],"format":"int64","description":"Estimated files to scan after filter pruning","minimum":0},"statement":{"type":"string","description":"The statement that was explained"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/TableScanEstimate"},"description":"Per-table scan estimates"},"total_bytes":{"type":["integer","null"],"format":"int64","description":"Total bytes across all table scans","minimum":0},"total_files":{"type":["integer","null"],"format":"int64","description":"Total files across all table scans","minimum":0}}},"MemoryStats":{"type":"object","required":["total_usage_bytes"],"properties":{"total_usage_bytes":{"type":"integer","format":"int64","minimum":0}}},"QueryLog":{"type":"object","required":["uuid","start_time","query","client_interface","visible","session_id","threads"],"properties":{"client_interface":{"$ref":"#/components/schemas/SessionKind"},"duration_ms":{"type":["integer","null"],"format":"int64","minimum":0},"end_time":{"type":["string","null"],"format":"date-time"},"error":{"type":["string","null"]},"fingerprint":{"type":["integer","null"],"format":"int64"},"query":{"type":"string"},"requested_by":{"type":["string","null"]},"session_id":{"type":"string"},"start_time":{"type":"string","format":"date-time"},"stats":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/QueryStats"}]},"threads":{"type":"integer","minimum":0},"user_agent":{"type":["string","null"]},"uuid":{"type":"string","format":"uuid"},"visible":{"type":"boolean"}}},"QueryLogResponse":{"allOf":[{"$ref":"#/components/schemas/QueryLog"},{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/QueryProgress"}]}]},"QueryProgress":{"type":"object","required":["percentage","rows_processed","total_rows"],"properties":{"percentage":{"type":"number","format":"double"},"rows_processed":{"type":"integer","format":"int64","minimum":0},"total_rows":{"type":"integer","format":"int64","minimum":0}}},"QueryRequest":{"type":"object","description":"Request to execute a SQL query against the lakehouse","required":["statement"],"properties":{"cache":{"type":["boolean","null"],"description":"Whether to enable caching (default: true). Caching speeds up queries for frequently accessed data. To disable when loading data into Altertable from an external source.","example":"true"},"catalog":{"type":["string","null"],"description":"Catalog name to query (optional, can be set in session)","example":"my_catalog"},"compute_size":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ComputeSize","description":"Compute size for the query (XS, S, M, L, XL, or AUTO to infer it).\nAUTO cannot be combined with an explicit `session_id`."}]},"dialect":{"type":["string","null"],"description":"Source SQL dialect to transpile from before execution (optional, defaults to DuckDB)","example":"snowflake"},"ephemeral":{"type":["boolean","null"],"description":"Whether to create an ephemeral session (default: false)"},"format":{"type":["string","null"],"description":"Output format: default, csv, jsonl, or parquet (optional, defaults to default)","example":"csv"},"limit":{"type":["integer","null"],"description":"Limit the number of rows returned (optional)","example":"100","minimum":0},"offset":{"type":["integer","null"],"description":"Offset the number of rows returned (optional)","example":"0","minimum":0},"query_id":{"type":["string","null"],"example":"123e4567-e89b-12d3-a456-426614174000"},"requested_by":{"type":["string","null"],"description":"Who issued the request (optional, used for logging)"},"sanitize":{"type":["boolean","null"],"description":"Whether to automatically limit the number of rows returned (default: false)","example":"true"},"schema":{"type":["string","null"],"description":"Schema name to query (optional, can be set in session)","example":"public"},"session_id":{"type":["string","null"],"description":"Session ID to use for the query (optional)","example":"123e4567-e89b-12d3-a456-426614174000"},"statement":{"type":"string","description":"SQL statement to execute","example":"SELECT * FROM users WHERE age > 25"},"timezone":{"type":["string","null"],"description":"Timezone to use for the query (optional, defaults to UTC)","example":"Europe/Paris"}}},"QueryStats":{"type":"object","properties":{"caching":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/CachingStats"}]},"memory":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/MemoryStats"}]},"scan":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ScanStats"}]}}},"ScanStats":{"type":"object","required":["estimated_result_rows","estimated_scanned_rows"],"properties":{"estimated_result_rows":{"type":"integer","format":"int64","minimum":0},"estimated_scanned_rows":{"type":"integer","format":"int64","minimum":0}}},"SessionKind":{"type":"string","enum":["ArrowFlightSQL","HTTP","Postgres"]},"TableScanEstimate":{"type":"object","description":"Per-table scan estimates with file statistics","required":["table_name","estimated_rows"],"properties":{"estimated_rows":{"type":"integer","format":"int64","description":"Estimated number of rows in the table","minimum":0},"filters":{"type":["string","null"],"description":"Filters applied to the table"},"scanned_bytes_estimate":{"type":["integer","null"],"format":"int64","description":"Estimated bytes to scan after filter pruning based on column min/max stats","minimum":0},"scanned_files_estimate":{"type":["integer","null"],"format":"int64","description":"Estimated files to scan after filter pruning based on column min/max stats","minimum":0},"table_name":{"type":"string","description":"Name of the table"},"total_bytes":{"type":["integer","null"],"format":"int64","description":"Total bytes across all data files","minimum":0},"total_files":{"type":["integer","null"],"format":"int64","description":"Total number of data files for this table","minimum":0}}},"TaskResponse":{"type":"object","description":"Response from querying a task's status","required":["task_id","status"],"properties":{"status":{"$ref":"#/components/schemas/TaskStatus","description":"Current status of the task"},"task_id":{"type":"string","format":"uuid","description":"The task ID"}}},"TaskStatus":{"type":"string","enum":["pending","completed"]},"UploadMode":{"type":"string","description":"Mode determining how uploaded data is inserted into the table","enum":["create","append","overwrite"]},"UploadParams":{"type":"object","description":"Query parameters for file upload","required":["catalog","schema","table"],"properties":{"catalog":{"type":"string","description":"Name of the catalog to upload data to","example":"my_catalog"},"mode":{"$ref":"#/components/schemas/UploadMode","description":"Upload mode determining how data is inserted"},"schema":{"type":"string","description":"Name of the schema within the catalog","example":"public"},"table":{"type":"string","description":"Name of the table to create or insert into","example":"users"}}},"UpsertParams":{"type":"object","description":"Query parameters for file upsert","required":["catalog","schema","table","primary_key"],"properties":{"catalog":{"type":"string","description":"Name of the catalog to upsert data to","example":"my_catalog"},"primary_key":{"type":"string","description":"Primary key column name used to match and update existing rows","example":"id"},"schema":{"type":"string","description":"Name of the schema within the catalog","example":"public"},"table":{"type":"string","description":"Name of the table to upsert into","example":"users"}}},"ValidateRequest":{"type":"object","description":"Request to validate a SQL statement","required":["statement"],"properties":{"catalog":{"type":["string","null"],"description":"Catalog name to use for validation (optional, can be set in session)","example":"my_catalog"},"schema":{"type":["string","null"],"description":"Schema name to use for validation (optional, can be set in session)","example":"public"},"session_id":{"type":["string","null"],"description":"Session ID to use for validation (optional)","example":"123e4567-e89b-12d3-a456-426614174000"},"statement":{"type":"string","description":"SQL statement to validate","example":"SELECT * FROM users WHERE age > 25"}}},"ValidateResponse":{"type":"object","description":"Response from SQL validation","required":["valid","statement","connections_errors"],"properties":{"connections_errors":{"type":"object","description":"Connection errors for attached catalogs","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"error":{"type":["string","null"],"description":"Error message if the statement is invalid"},"statement":{"type":"string","description":"The statement that was validated"},"valid":{"type":"boolean","description":"Whether the SQL statement is valid"}}}},"securitySchemes":{"basic_auth":{"type":"http","scheme":"basic","description":"Your lakehouse username and password to access the lakehouse API"}}},"tags":[{"name":"Lakehouse","description":"Data lakehouse operations"}]}