{
  "swagger": "2.0",
  "info": {
    "title": "SQL service",
    "version": "0.1507.0",
    "description": "Send your API key as a bearer token: `Authorization: Bearer <api key>`."
  },
  "tags": [
    {
      "name": "SqlService",
      "x-displayName": "SQL service",
      "description": "Executes read-only SQL queries against Nominal telemetry tables.",
      "x-errors": [
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "NominalSqlV1:SqlErrorInvalidQuery",
          "message": "SQL query is invalid"
        },
        {
          "status": 404,
          "errorCode": "NOT_FOUND",
          "errorName": "NominalSqlV1:SqlErrorDatasetsNotFound",
          "message": "One or more requested datasets could not be found in the specified workspace"
        },
        {
          "status": 500,
          "errorCode": "INTERNAL",
          "errorName": "NominalSqlV1:SqlErrorExecutionFailed",
          "message": "An unexpected internal error occurred while executing the SQL query"
        },
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "NominalSqlV1:SqlErrorExportNotSupportedForBackend",
          "message": "SQL export is not supported for this query backend"
        },
        {
          "status": 500,
          "errorCode": "FAILED_PRECONDITION",
          "errorName": "NominalSqlV1:SqlErrorExportNotConfigured",
          "message": "SQL export is not configured for this deployment"
        },
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "NominalSqlV1:SqlErrorQueryTimeout",
          "message": "The query timed out before it could complete"
        },
        {
          "status": 429,
          "message": "The query exceeded a resource limit"
        },
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "NominalSqlV1:SqlErrorDatasetStorageTypeNotSupported",
          "message": "Datasets with this storage type are not yet supported by SQL queries"
        },
        {
          "status": 404,
          "errorCode": "NOT_FOUND",
          "errorName": "NominalSqlV1:SqlErrorDataNotFoundForType",
          "message": "No data of the requested type exists for one or more of the requested datasets"
        },
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "NominalSqlV1:SqlErrorResultSizeExceeded",
          "message": "The query result exceeded the maximum result size"
        },
        {
          "status": 500,
          "errorCode": "INTERNAL",
          "errorName": "NominalSqlV1:SqlErrorQueryScopeTooLarge",
          "message": "The query spans more datasets than can be planned at once"
        },
        {
          "status": 500,
          "errorCode": "INTERNAL",
          "errorName": "NominalSqlV1:SqlErrorQueryCancelled",
          "message": "The query was cancelled"
        },
        {
          "status": 401,
          "errorCode": "UNAUTHORIZED",
          "errorName": "NominalSqlV1:SqlErrorUnauthenticated",
          "message": "The request could not be authenticated"
        },
        {
          "status": 403,
          "errorCode": "PERMISSION_DENIED",
          "errorName": "NominalSqlV1:SqlErrorPermissionDenied",
          "message": "The caller does not have permission to perform this request"
        }
      ]
    }
  ],
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
    "/sql/v1/catalog": {
      "get": {
        "operationId": "SqlService_GetSqlCatalog",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GetSqlCatalogResponse"
            },
            "x-example": {
              "sqlCatalog": {
                "tables": [
                  {
                    "name": "<name>",
                    "columns": [
                      {
                        "name": "<name>",
                        "type": "<type>",
                        "nullable": true,
                        "dataType": {
                          "scalar": "SQL_CATALOG_SCALAR_TYPE_VARCHAR"
                        }
                      }
                    ]
                  }
                ],
                "functions": [
                  {
                    "name": "<name>",
                    "kind": "SQL_CATALOG_FUNCTION_KIND_SCALAR",
                    "supportsOver": true,
                    "minArgs": 1,
                    "maxArgs": 1,
                    "argumentTypeFamilies": [
                      "<argument type families>"
                    ],
                    "returnTypeFamily": "<return type family>"
                  }
                ]
              }
            }
          }
        },
        "tags": [
          "SqlService"
        ],
        "summary": "Get SQL catalog",
        "description": "Get the queryable SQL surface: tables, columns, and allowed functions."
      }
    },
    "/sql/v1/query": {
      "post": {
        "operationId": "SqlService_Query",
        "responses": {
          "200": {
            "description": "Response bytes encoded according to SqlServiceQueryRequest.result_format. Defaults to an Arrow IPC stream when no result_format is specified.",
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/SqlServiceQueryRequest"
            },
            "x-example": {
              "query": "<query>",
              "workspaceRid": "<workspace rid>"
            }
          }
        ],
        "tags": [
          "SqlService"
        ],
        "summary": "Query",
        "description": "Validate, authorize, lower, and execute a bounded SQL query.",
        "produces": [
          "application/octet-stream"
        ]
      }
    },
    "/sql/v1/query/export": {
      "post": {
        "operationId": "SqlService_Export",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/SqlServiceExportResponse"
            },
            "x-example": {
              "presignedUrl": "<presigned url>",
              "queryId": "<query id>"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/SqlServiceExportRequest"
            },
            "x-example": {
              "query": "<query>",
              "workspaceRid": "<workspace rid>"
            }
          }
        ],
        "tags": [
          "SqlService"
        ],
        "summary": "Export",
        "description": "Run an unbounded SQL query. Write the full result to object storage in the requested format, and return a presigned URL."
      }
    }
  },
  "definitions": {
    "GetSqlCatalogResponse": {
      "type": "object",
      "properties": {
        "sqlCatalog": {
          "$ref": "#/definitions/SqlCatalog"
        }
      }
    },
    "SqlCatalog": {
      "type": "object",
      "properties": {
        "tables": {
          "type": "array",
          "items": {
            "type": "object",
            "$ref": "#/definitions/SqlCatalogTable"
          }
        },
        "functions": {
          "type": "array",
          "items": {
            "type": "object",
            "$ref": "#/definitions/SqlCatalogFunction"
          }
        }
      },
      "description": "The queryable logical SQL surface."
    },
    "SqlCatalogColumn": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "type": {
          "type": "string",
          "description": "Top-level SQL type name, e.g. TIMESTAMP, DOUBLE, BIGINT, VARCHAR, MAP, or ARRAY. Collection element types are only carried by data_type."
        },
        "nullable": {
          "type": "boolean"
        },
        "dataType": {
          "$ref": "#/definitions/SqlCatalogDataType"
        }
      }
    },
    "SqlCatalogDataType": {
      "type": "object",
      "properties": {
        "scalar": {
          "$ref": "#/definitions/SqlCatalogScalarType"
        },
        "arrayElement": {
          "$ref": "#/definitions/SqlCatalogDataType"
        },
        "map": {
          "$ref": "#/definitions/SqlCatalogMapType"
        }
      },
      "description": "Full logical type of a column, including collection element types.\n\nSet at most one of the fields below.",
      "x-oneofs": [
        {
          "fields": [
            "scalar",
            "arrayElement",
            "map"
          ],
          "required": false
        }
      ],
      "example": {
        "scalar": "SQL_CATALOG_SCALAR_TYPE_VARCHAR"
      }
    },
    "SqlCatalogFunction": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Uppercase function name, e.g. AVG, COUNT, DATE_BIN."
        },
        "kind": {
          "$ref": "#/definitions/SqlCatalogFunctionKind"
        },
        "supportsOver": {
          "type": "boolean",
          "description": "Whether calls may carry an OVER clause. Always true for WINDOW functions, which require one."
        },
        "minArgs": {
          "type": "integer",
          "format": "int32",
          "description": "Minimum number of arguments."
        },
        "maxArgs": {
          "type": "integer",
          "format": "int32",
          "description": "Maximum number of arguments; unset when the function is variadic."
        },
        "argumentTypeFamilies": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Best-effort operand type families (e.g. NUMERIC, DATETIME, CHARACTER, ANY), one per argument position up to max_args. Empty when the function's operand rules are not statically known."
        },
        "returnTypeFamily": {
          "type": "string",
          "description": "Best-effort type family of the result (e.g. NUMERIC, TIMESTAMP, CHARACTER, BOOLEAN). Unset when the result type depends on the argument types in a way that is not statically known."
        }
      }
    },
    "SqlCatalogFunctionKind": {
      "type": "string",
      "enum": [
        "SQL_CATALOG_FUNCTION_KIND_UNSPECIFIED",
        "SQL_CATALOG_FUNCTION_KIND_SCALAR",
        "SQL_CATALOG_FUNCTION_KIND_AGGREGATE",
        "SQL_CATALOG_FUNCTION_KIND_WINDOW",
        "SQL_CATALOG_FUNCTION_KIND_TABLE"
      ],
      "default": "SQL_CATALOG_FUNCTION_KIND_UNSPECIFIED",
      "description": "- SQL_CATALOG_FUNCTION_KIND_WINDOW: Requires an OVER clause.",
      "example": "SQL_CATALOG_FUNCTION_KIND_SCALAR"
    },
    "SqlCatalogMapType": {
      "type": "object",
      "properties": {
        "key": {
          "$ref": "#/definitions/SqlCatalogDataType"
        },
        "value": {
          "$ref": "#/definitions/SqlCatalogDataType"
        }
      }
    },
    "SqlCatalogScalarType": {
      "type": "string",
      "enum": [
        "SQL_CATALOG_SCALAR_TYPE_UNSPECIFIED",
        "SQL_CATALOG_SCALAR_TYPE_VARCHAR",
        "SQL_CATALOG_SCALAR_TYPE_BOOLEAN",
        "SQL_CATALOG_SCALAR_TYPE_INTEGER",
        "SQL_CATALOG_SCALAR_TYPE_BIGINT",
        "SQL_CATALOG_SCALAR_TYPE_DOUBLE",
        "SQL_CATALOG_SCALAR_TYPE_TIMESTAMP",
        "SQL_CATALOG_SCALAR_TYPE_ANY"
      ],
      "default": "SQL_CATALOG_SCALAR_TYPE_UNSPECIFIED",
      "example": "SQL_CATALOG_SCALAR_TYPE_VARCHAR"
    },
    "SqlCatalogTable": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "columns": {
          "type": "array",
          "items": {
            "type": "object",
            "$ref": "#/definitions/SqlCatalogColumn"
          }
        }
      }
    },
    "SqlServiceExportFormat": {
      "type": "string",
      "enum": [
        "SQL_SERVICE_EXPORT_FORMAT_UNSPECIFIED",
        "SQL_SERVICE_EXPORT_FORMAT_CSV",
        "SQL_SERVICE_EXPORT_FORMAT_PARQUET"
      ],
      "default": "SQL_SERVICE_EXPORT_FORMAT_UNSPECIFIED",
      "description": "File format of an exported result. Unspecified means CSV.\n\n - SQL_SERVICE_EXPORT_FORMAT_CSV: CSV with a header row; nulls are empty fields.\n - SQL_SERVICE_EXPORT_FORMAT_PARQUET: A single Parquet file. Arrow-based readers can read it from the presigned URL. Configure it with SqlServiceExportRequest.parquet_options.",
      "example": "SQL_SERVICE_EXPORT_FORMAT_CSV"
    },
    "SqlServiceExportRequest": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "maxLength": 100000,
          "x-constraints": [
            "At most 100,000 characters."
          ]
        },
        "workspaceRid": {
          "type": "string"
        },
        "format": {
          "$ref": "#/definitions/SqlServiceExportFormat",
          "description": "File format written to object storage. Defaults to CSV."
        },
        "parquetOptions": {
          "$ref": "#/definitions/SqlServiceParquetOptions",
          "description": "Only valid with format PARQUET. Unset writes zstd with the server's default row group size."
        }
      },
      "required": [
        "query",
        "workspaceRid"
      ],
      "description": "parquet_options can only be set when format is SQL_SERVICE_EXPORT_FORMAT_PARQUET.",
      "example": {
        "query": "<query>",
        "workspaceRid": "<workspace rid>"
      }
    },
    "SqlServiceExportResponse": {
      "type": "object",
      "properties": {
        "presignedUrl": {
          "type": "string",
          "description": "Presigned URL for the exported file, written to object storage in the requested format."
        },
        "queryId": {
          "type": "string",
          "description": "Server-generated id for this query execution, also used as the data store query_id."
        }
      }
    },
    "SqlServiceParquetCompression": {
      "type": "string",
      "enum": [
        "SQL_SERVICE_PARQUET_COMPRESSION_UNSPECIFIED",
        "SQL_SERVICE_PARQUET_COMPRESSION_ZSTD",
        "SQL_SERVICE_PARQUET_COMPRESSION_LZ4",
        "SQL_SERVICE_PARQUET_COMPRESSION_SNAPPY",
        "SQL_SERVICE_PARQUET_COMPRESSION_NONE"
      ],
      "default": "SQL_SERVICE_PARQUET_COMPRESSION_UNSPECIFIED",
      "description": "Column compression codec for a Parquet export. Unspecified is zstd.",
      "example": "SQL_SERVICE_PARQUET_COMPRESSION_ZSTD"
    },
    "SqlServiceParquetOptions": {
      "type": "object",
      "properties": {
        "rowGroupRows": {
          "type": "string",
          "format": "uint64",
          "description": "Rows per row group, from 1,000 to 100,000,000. A reader skips or fetches whole row groups. Add an ORDER BY to the query so that each group holds a contiguous range of rows. A group closes early if it reaches the server's byte limit. Unset uses the server default.",
          "minimum": 1000,
          "maximum": 100000000,
          "x-constraints": [
            "From 1,000 to 100,000,000."
          ]
        },
        "compression": {
          "$ref": "#/definitions/SqlServiceParquetCompression",
          "description": "Defaults to zstd."
        }
      },
      "description": "How a Parquet export is written."
    },
    "SqlServiceQueryRequest": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "maxLength": 100000,
          "x-constraints": [
            "At most 100,000 characters."
          ]
        },
        "maxRows": {
          "type": "integer",
          "format": "int32",
          "description": "Optional cap on the number of rows returned. When unset, results are unbounded (subject to the server-side byte/time limits); data store and mixed queries stream, pure metadata store materializes. Zero returns only the result's schema.",
          "minimum": 0,
          "maximum": 5000,
          "x-constraints": [
            "From 0 to 5,000."
          ]
        },
        "workspaceRid": {
          "type": "string"
        },
        "resultFormat": {
          "$ref": "#/definitions/SqlServiceQueryResultFormat",
          "description": "Encoding for the streamed response payload. Defaults to Arrow IPC stream for backward compatibility."
        }
      },
      "required": [
        "query",
        "workspaceRid"
      ],
      "example": {
        "query": "<query>",
        "workspaceRid": "<workspace rid>"
      }
    },
    "SqlServiceQueryResultFormat": {
      "type": "string",
      "enum": [
        "SQL_SERVICE_QUERY_RESULT_FORMAT_UNSPECIFIED",
        "SQL_SERVICE_QUERY_RESULT_FORMAT_ARROW_STREAM",
        "SQL_SERVICE_QUERY_RESULT_FORMAT_JSON_LINES",
        "SQL_SERVICE_QUERY_RESULT_FORMAT_CSV"
      ],
      "default": "SQL_SERVICE_QUERY_RESULT_FORMAT_UNSPECIFIED",
      "example": "SQL_SERVICE_QUERY_RESULT_FORMAT_ARROW_STREAM"
    }
  },
  "securityDefinitions": {
    "ApiKey": {
      "type": "apiKey",
      "in": "header",
      "name": "Authorization",
      "description": "Your API key as a bearer token: `Authorization: Bearer <api key>`."
    }
  },
  "security": [
    {
      "ApiKey": []
    }
  ]
}
