{
  "openapi": "3.1.0",
  "info": {
    "title": "SnowLeopard API",
    "description": "Natural language querying capabilities over structured data",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.snowleopard.ai",
      "description": "Production server"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/instances/{instance_id}/retrieve": {
      "post": {
        "summary": "Retrieve complete query results",
        "description": "Execute a natural language query against your instance's data sources and return the retrieved data.",
        "operationId": "retrieve",
        "parameters": [
          {
            "name": "instance_id",
            "in": "path",
            "required": true,
            "description": "Unique identifier for the instance to query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userQuery"
                ],
                "properties": {
                  "userQuery": {
                    "type": "string",
                    "description": "Natural language query to execute against your instance's data sources",
                    "example": "How many users signed up last month?"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful query execution",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RetrieveResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request error (e.g. missing required request body field)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            }
          },
          "409": {
            "description": "Query execution error (e.g. invalid SQL generated)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Python",
            "label": "Asynchronous",
            "source": "from snowleopard import AsyncSnowLeopardClient\n\nasync def main():\n    client = AsyncSnowLeopardClient(api_key=\"{api_key}\")\n    response = await client.retrieve(\n        instance_id=\"{instance_id}\",\n        user_query=\"How many users signed up last month?\"\n    )\n    print(response.data)\n"
          },
          {
            "lang": "Python",
            "label": "Synchronous",
            "source": "from snowleopard import SnowLeopardClient\n\nclient = SnowLeopardClient(api_key=\"{api_key}\")\nresponse = client.retrieve(\n    instance_id=\"{instance_id}\",\n    user_query=\"How many users signed up last month?\"\n)\nprint(response.data)\n"
          },
          {
            "lang": "TypeScript",
            "label": "TypeScript",
            "source": "import { SnowLeopardClient } from '@snowleopard-ai/client';\n\nconst client = new SnowLeopardClient({\n    apiKey: 'your-api-key'\n});\n\nconst response = await client.retrieve({\n    instanceId: 'your-instance-id',\n    userQuery: 'How many users signed up last month?'\n});\n\nconsole.log(response.data);\nawait client.close();\n"
          }
        ]
      }
    },
    "/v1/instances/{instance_id}/feedback": {
      "post": {
        "summary": "Submit feedback",
        "description": "Submit plain-text feedback to help Snow Leopard better understand your schema. Feedback is processed asynchronously and updates your instance's annotation. Corrections persist across sessions and improve future query results.",
        "operationId": "submitFeedback",
        "parameters": [
          {
            "name": "instance_id",
            "in": "path",
            "required": true,
            "description": "Unique identifier for the instance",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "feedbackText"
                ],
                "properties": {
                  "feedbackText": {
                    "type": "string",
                    "description": "Plain-text description of the correction. Maximum 2000 characters; longer values are silently truncated and the response will include truncated: true.",
                    "example": "The revenue column in the orders table should be labeled 'gross revenue before discounts', not 'net revenue'."
                  },
                  "datasourceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "UUID of the target data source. Takes priority over schemaId when both are provided. Recommended for instances with multiple data sources."
                  },
                  "schemaId": {
                    "type": "string",
                    "description": "Schema identifier for the target data source (e.g. 'northwind'). Available as the schemaId field in /retrieve and /response results. Used when datasourceId is not provided. If neither field is supplied, feedback is applied to the first connected data source."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Feedback accepted and queued for processing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedbackResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request (e.g. missing feedbackText)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            }
          },
          "404": {
            "description": "Instance or data source not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            }
          },
          "422": {
            "description": "Instance has no connected data source",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error submitting feedback to the processing pipeline",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Python",
            "label": "Asynchronous",
            "source": "from snowleopard import AsyncSnowLeopardClient\n\nasync def main():\n    client = AsyncSnowLeopardClient(api_key=\"{api_key}\")\n    response = await client.feedback(\n        instance_id=\"{instance_id}\",\n        feedback_text=\"The revenue column should be labeled 'gross revenue before discounts'.\"\n    )\n"
          },
          {
            "lang": "Python",
            "label": "Synchronous",
            "source": "from snowleopard import SnowLeopardClient\n\nclient = SnowLeopardClient(api_key=\"{api_key}\")\nresponse = client.feedback(\n    instance_id=\"{instance_id}\",\n    feedback_text=\"The revenue column should be labeled 'gross revenue before discounts'.\"\n)\n"
          },
          {
            "lang": "TypeScript",
            "label": "TypeScript",
            "source": "import { SnowLeopardClient } from '@snowleopard-ai/client';\n\nconst client = new SnowLeopardClient({\n    apiKey: 'your-api-key'\n});\n\nawait client.feedback({\n    instanceId: 'your-instance-id',\n    feedbackText: \"The revenue column should be labeled 'gross revenue before discounts'.\"\n});\n\nawait client.close();\n"
          }
        ]
      }
    },
    "/v1/instances/{instance_id}/response": {
      "post": {
        "summary": "Stream query results",
        "description": "Execute a natural language query and return the summarized results in natural language.",
        "operationId": "response",
        "parameters": [
          {
            "name": "instance_id",
            "in": "path",
            "required": true,
            "description": "Unique identifier for the instance to query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userQuery"
                ],
                "properties": {
                  "userQuery": {
                    "type": "string",
                    "description": "Natural language query to execute against your instance's data sources",
                    "example": "How many users signed up last month?"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Streaming response with newline-delimited JSON objects",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Stream of JSON objects, one per line, in order: ResponseStart, ResponseData, ResponseLLMResult (or EarlyTermination)",
                  "oneOf": [
                    {
                      "title": "responseStart",
                      "$ref": "#/components/schemas/ResponseStart"
                    },
                    {
                      "title": "responseData",
                      "$ref": "#/components/schemas/ResponseData"
                    },
                    {
                      "title": "responseResult",
                      "$ref": "#/components/schemas/ResponseLLMResult"
                    },
                    {
                      "title": "earlyTermination",
                      "$ref": "#/components/schemas/EarlyTermination"
                    }
                  ],
                  "discriminator": {
                    "propertyName": "__type__",
                    "mapping": {
                      "responseStart": "#/components/schemas/ResponseStart",
                      "responseData": "#/components/schemas/ResponseData",
                      "responseResult": "#/components/schemas/ResponseLLMResult",
                      "earlyTermination": "#/components/schemas/EarlyTermination"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request error (e.g. missing required request body field)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/APIError"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Python",
            "label": "Asynchronous",
            "source": "from snowleopard import AsyncSnowLeopardClient\n\nasync def main():\n    client = AsyncSnowLeopardClient(api_key=\"{api_key}\")\n    async for response in client.response(\n        instance_id=\"{instance_id}\",\n        user_query=\"How many users signed up last month?\"\n    ):\n        print(response)\n"
          },
          {
            "lang": "Python",
            "label": "Synchronous",
            "source": "from snowleopard import SnowLeopardClient\n\nclient = SnowLeopardClient(api_key=\"{api_key}\")\nfor response in client.response(\n        instance_id=\"{instance_id}\",\n        user_query=\"How many users signed up last month?\"\n):\n    print(response)\n"
          },
          {
            "lang": "TypeScript",
            "label": "TypeScript",
            "source": "import { SnowLeopardClient } from '@snowleopard-ai/client';\n\nconst client = new SnowLeopardClient({\n    apiKey: 'your-api-key'\n});\n\nfor await (const chunk of client.response({\n    instanceId: 'your-instance-id',\n    userQuery: 'How many users signed up last month?'\n})) {\n    console.log(chunk);\n}\n\nawait client.close();\n"
          }
        ]
      }
    },
    "/v1/instances/{instance_id}/staged-corrections": {
      "post": {
        "x-codeSamples": [
          {
            "lang": "Python",
            "label": "Asynchronous",
            "source": "from snowleopard import AsyncSnowLeopardClient\n\nasync def main():\n    client = AsyncSnowLeopardClient(api_key=\"{api_key}\")\n    result = await client.staged_corrections(\n        instance_id=\"{instance_id}\",\n        since_revision=0\n    )\n    print(result.current_revision)\n    for correction in result.corrections:\n        print(correction)\n"
          },
          {
            "lang": "Python",
            "label": "Synchronous",
            "source": "from snowleopard import SnowLeopardClient\n\nclient = SnowLeopardClient(api_key=\"{api_key}\")\nresult = client.staged_corrections(\n    instance_id=\"{instance_id}\",\n    since_revision=0\n)\nprint(result.current_revision)\nfor correction in result.corrections:\n    print(correction)\n"
          },
          {
            "lang": "TypeScript",
            "label": "TypeScript",
            "source": "import { SnowLeopardClient } from '@snowleopard-ai/client';\n\nconst client = new SnowLeopardClient({\n    apiKey: 'your-api-key'\n});\n\nconst result = await client.stagedCorrections({\n    instanceId: 'your-instance-id',\n    sinceRevision: 0\n});\n\nconsole.log(result.currentRevision);\nfor (const correction of result.corrections) {\n    console.log(correction);\n}\nawait client.close();\n"
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "api_key",
        "description": "Bearer authentication header of the form `Bearer <api_key>`. API keys are created per instance in Snow Leopard Cloud."
      }
    },
    "schemas": {
      "RetrieveResponse": {
        "type": "object",
        "required": [
          "__type__",
          "callId",
          "data",
          "responseStatus"
        ],
        "properties": {
          "__type__": {
            "type": "string",
            "enum": [
              "retrieveResponse"
            ],
            "description": "Type discriminator"
          },
          "callId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this API call"
          },
          "data": {
            "type": "array",
            "description": "Array of query results or errors",
            "items": {
              "oneOf": [
                {
                  "title": "schemaData",
                  "$ref": "#/components/schemas/SchemaData"
                },
                {
                  "title": "errorSchemaData",
                  "$ref": "#/components/schemas/ErrorSchemaData"
                }
              ]
            }
          },
          "responseStatus": {
            "$ref": "#/components/schemas/ResponseStatus"
          }
        }
      },
      "APIError": {
        "type": "object",
        "required": [
          "__type__",
          "callId",
          "responseStatus",
          "description"
        ],
        "properties": {
          "__type__": {
            "type": "string",
            "enum": [
              "apiError"
            ],
            "description": "Type discriminator"
          },
          "callId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this API call"
          },
          "responseStatus": {
            "type": "string",
            "description": "Status of the response"
          },
          "description": {
            "type": "string",
            "description": "Error description"
          }
        }
      },
      "SchemaData": {
        "type": "object",
        "required": [
          "__type__",
          "schemaId",
          "schemaType",
          "query",
          "rows",
          "querySummary",
          "rowMax",
          "isTrimmed"
        ],
        "properties": {
          "__type__": {
            "type": "string",
            "enum": [
              "schemaData"
            ],
            "description": "Type discriminator"
          },
          "schemaId": {
            "type": "string",
            "description": "Identifier for the schema/database queried"
          },
          "schemaType": {
            "type": "string",
            "description": "Type of database (e.g. SQLite, PostgreSQL)",
            "example": "SQLite"
          },
          "query": {
            "type": "string",
            "description": "Generated SQL query that was executed"
          },
          "rows": {
            "type": "array",
            "description": "Result rows from the query",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "querySummary": {
            "type": "object",
            "description": "Detailed explanation of the query",
            "properties": {
              "technical_details": {
                "type": "string",
                "description": "Technical explanation of the query logic"
              },
              "non_technical_explanation": {
                "type": "string",
                "description": "Plain language explanation for non-technical users"
              }
            }
          },
          "rowMax": {
            "type": "integer",
            "description": "Maximum number of rows that can be returned"
          },
          "isTrimmed": {
            "type": "boolean",
            "description": "Whether the result set was trimmed due to size limits"
          },
          "callId": {
            "type": "string",
            "format": "uuid",
            "description": "Call identifier (optional)"
          }
        }
      },
      "ErrorSchemaData": {
        "type": "object",
        "required": [
          "__type__",
          "schemaType",
          "schemaId",
          "query",
          "error",
          "querySummary"
        ],
        "properties": {
          "__type__": {
            "type": "string",
            "enum": [
              "errorSchemaData"
            ],
            "description": "Type discriminator"
          },
          "schemaId": {
            "type": "string",
            "description": "Identifier for the schema/database queried"
          },
          "schemaType": {
            "type": "string",
            "description": "Type of database",
            "example": "SQLite"
          },
          "query": {
            "type": "string",
            "description": "Generated SQL query that failed"
          },
          "error": {
            "type": "string",
            "description": "Error message from query execution"
          },
          "querySummary": {
            "type": "object",
            "description": "Explanation of what the query was attempting to do",
            "properties": {
              "technical_details": {
                "type": "string",
                "description": "Technical explanation of the query logic"
              },
              "non_technical_explanation": {
                "type": "string",
                "description": "Plain language explanation for non-technical users"
              }
            }
          },
          "datastoreExceptionInfo": {
            "type": "string",
            "nullable": true,
            "description": "Additional datastore-specific error information"
          },
          "callId": {
            "type": "string",
            "format": "uuid",
            "description": "Call identifier (optional)"
          }
        }
      },
      "ResponseStart": {
        "type": "object",
        "required": [
          "__type__",
          "callId",
          "userQuery"
        ],
        "properties": {
          "__type__": {
            "type": "string",
            "enum": [
              "responseStart"
            ],
            "description": "Type discriminator"
          },
          "callId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this API call"
          },
          "userQuery": {
            "type": "string",
            "description": "The original user query"
          }
        }
      },
      "ResponseData": {
        "type": "object",
        "required": [
          "__type__",
          "callId",
          "data"
        ],
        "properties": {
          "__type__": {
            "type": "string",
            "enum": [
              "responseData"
            ],
            "description": "Type discriminator"
          },
          "callId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this API call"
          },
          "data": {
            "type": "array",
            "description": "Array of query results or errors",
            "items": {
              "oneOf": [
                {
                  "title": "schemaData",
                  "$ref": "#/components/schemas/SchemaData"
                },
                {
                  "title": "errorSchemaData",
                  "$ref": "#/components/schemas/ErrorSchemaData"
                }
              ]
            }
          }
        }
      },
      "ResponseLLMResult": {
        "type": "object",
        "required": [
          "__type__",
          "callId",
          "responseStatus",
          "llmResponse"
        ],
        "properties": {
          "__type__": {
            "type": "string",
            "enum": [
              "responseResult"
            ],
            "description": "Type discriminator"
          },
          "callId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this API call"
          },
          "responseStatus": {
            "$ref": "#/components/schemas/ResponseStatus"
          },
          "llmResponse": {
            "type": "object",
            "description": "LLM-generated response with natural language answer",
            "properties": {
              "status": {
                "type": "string",
                "description": "Status of LLM processing"
              },
              "data": {
                "type": "object",
                "additionalProperties": true,
                "description": "Extracted key data points"
              },
              "complete_answer": {
                "type": "string",
                "description": "Natural language answer to the user's query"
              },
              "analysis": {
                "type": "object",
                "additionalProperties": true,
                "description": "Analysis and insights"
              },
              "explanation": {
                "type": "object",
                "properties": {
                  "howDataWasUsed": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Explanation of how the data was processed"
                  }
                }
              },
              "comments": {
                "type": "string",
                "description": "Additional comments about the result"
              }
            }
          }
        }
      },
      "EarlyTermination": {
        "type": "object",
        "required": [
          "__type__",
          "callId",
          "responseStatus",
          "reason",
          "extra"
        ],
        "properties": {
          "__type__": {
            "type": "string",
            "enum": [
              "earlyTermination"
            ],
            "description": "Type discriminator"
          },
          "callId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this API call"
          },
          "responseStatus": {
            "$ref": "#/components/schemas/ResponseStatus"
          },
          "reason": {
            "type": "string",
            "description": "Reason for early termination"
          },
          "extra": {
            "type": "object",
            "additionalProperties": true,
            "description": "Additional context about the termination"
          }
        }
      },
      "ResponseStatus": {
        "type": "string",
        "enum": [
          "SUCCESS",
          "NOT_FOUND_IN_SCHEMA",
          "UNKNOWN",
          "INTERNAL_SERVER_ERROR",
          "AUTHORIZATION_FAILED",
          "LLM_ERROR",
          "LLM_TOKEN_LIMIT_REACHED"
        ],
        "description": "Status of the API response"
      },
      "FeedbackResponse": {
        "type": "object",
        "required": [
          "ok",
          "feedbackId",
          "gateStatus"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ],
            "description": "Always true for a 202 response."
          },
          "feedbackId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the submitted feedback"
          },
          "gateStatus": {
            "type": "string",
            "enum": [
              "raw"
            ],
            "description": "Acknowledgment state at submission time. Always 'raw'. Snow Leopard processes feedback asynchronously; there is no polling endpoint to track status changes."
          },
          "truncated": {
            "type": "boolean",
            "description": "Only present when feedbackText exceeded 2000 characters and was silently truncated to fit."
          }
        }
      }
    }
  }
}