{
  "openapi": "3.1.0",
  "info": {
    "title": "Canonn API",
    "version": "1.2.0",
    "summary": "Grounded answers from your own documents.",
    "description": "Canonn serves **canonn-r1**, a model fine-tuned for context faithfulness: it\nanswers from the documents you supply and says so when the answer is not there.\nEach request is answered by one of four experts on the same base (default,\nconflict, injection, absent): a trained router picks among the first three,\nand a check on whether the data contains the answer can hand it to `absent`.\nThe choice is reported in `canonn.route`; when the router does not run, a\nconflict check stands in.\nBoth report contradictions in `canonn.conflict`.\n\nThe API is **OpenAI-compatible**. Point any OpenAI SDK at\n`https://api.canonn.ai/v1`, set your Canonn key, and existing code works\nunchanged. Every example in this specification was run against\nproduction on 28 September 2026.\n\n## Authentication\n\nEvery request carries a bearer key created in the\n[dashboard](https://canonn.ai/dashboard/):\n\n```\nAuthorization: Bearer canonn-sk-...\n```\n\nA key is shown once at creation and stored only as a hash. It cannot be\nrecovered, only revoked and replaced.\n\n## How to prompt it\n\nPut the documents in the system message and the question in the user\nmessage. No rulebook is needed: faithfulness is trained into the weights,\nnot instructed at runtime.\n\n```\nsystem: Answer from the data below.\n\n        Data: Refunds are accepted within 45 days of purchase.\nuser:   What is the refund window?\n```\n\n## Pricing and limits\n\nUsage is billed per token, $0.25 per 1M input tokens and $1 per 1M output\ntokens, drawn from prepaid credits. New accounts get 100 free requests on\nsignup, no card; a successful referral adds 1,000 requests to both\naccounts. Past that, without credits, the API answers `402`. Context\nwindow 16,384 tokens, max output 4,096 tokens, 120 chat completions per\nminute per key. Inference runs in Canada.\n\n## Errors\n\n`/v1/chat/completions`, `/v1/models` and `/v1/files` (with their\nsub-routes) return the OpenAI error object\n`{\"error\": {\"message\", \"type\", \"param\", \"code\"}}`. `/v1/audits` returns\n`{\"error\": \"message\"}`.\n\n## Versioning and deprecation\n\nThe stable API is namespaced under `/v1`. Breaking changes use a new major\npath. See https://canonn.ai/developers/versioning/ for notice periods and\nthe response headers used for deprecations.\n",
    "contact": {
      "name": "Canonn",
      "email": "hello@canonn.ai",
      "url": "https://canonn.ai"
    },
    "termsOfService": "https://canonn.ai/legal/#terms",
    "license": {
      "name": "Canonn Terms of Service",
      "url": "https://canonn.ai/legal/#terms"
    }
  },
  "servers": [
    {
      "url": "https://api.canonn.ai/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Chat",
      "description": "Generating grounded answers."
    },
    {
      "name": "Files",
      "description": "Knowledge files that chat completions can ground on."
    },
    {
      "name": "Audits",
      "description": "Contradictions and out-of-date statements inside one knowledge file."
    },
    {
      "name": "Models",
      "description": "What this API serves."
    }
  ],
  "paths": {
    "/chat/completions": {
      "post": {
        "tags": [
          "Chat"
        ],
        "operationId": "createChatCompletion",
        "summary": "Create a grounded completion",
        "description": "OpenAI-compatible chat completion. Set `stream: true` for server-sent events; chunks arrive as `data: {...}` lines terminated by `data: [DONE]`. The chunk that carries `finish_reason` also carries `usage`; with `stream_options.include_usage` the usage comes instead in a separate final chunk with empty `choices`.\n\nNon-streamed responses carry a `canonn` object (route, conflict, citations when grounded, AI-generated mark). A stream carries it as a last `data: {\"canonn\": {...}}` event only when the request sets `\"canonn\": true`.\n\nNon-streamed generations longer than about 100 seconds can hit the edge's first-byte timeout; use streaming for long outputs.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletionRequest"
              },
              "examples": {
                "grounded": {
                  "summary": "Answer from supplied data",
                  "value": {
                    "model": "canonn-r1",
                    "messages": [
                      {
                        "role": "system",
                        "content": "Answer from the data below.\n\nData: Refund window: 45 days from purchase."
                      },
                      {
                        "role": "user",
                        "content": "How long do I have to request a refund?"
                      }
                    ]
                  }
                },
                "absent": {
                  "summary": "A question the data cannot answer",
                  "description": "Canonn declines instead of inventing an answer.",
                  "value": {
                    "model": "canonn-r1",
                    "messages": [
                      {
                        "role": "system",
                        "content": "Answer from the data below.\n\nData: Plan A costs 10 dollars per month."
                      },
                      {
                        "role": "user",
                        "content": "How much does Plan B cost?"
                      }
                    ]
                  }
                },
                "files": {
                  "summary": "Grounded on uploaded files",
                  "value": {
                    "model": "canonn-r1",
                    "files": [
                      "file-2da93b04d430cc5e52d1ef9b"
                    ],
                    "messages": [
                      {
                        "role": "user",
                        "content": "What does HarborPay charge per card transaction?"
                      }
                    ]
                  }
                },
                "streaming": {
                  "summary": "Streamed response",
                  "value": {
                    "model": "canonn-r1",
                    "stream": true,
                    "messages": [
                      {
                        "role": "system",
                        "content": "Answer from the data below.\n\nData: Support hours are 9am to 5pm on weekdays."
                      },
                      {
                        "role": "user",
                        "content": "Is support available on Saturday?"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A completion. When `stream` is true the media type is\n`text/event-stream` instead of `application/json`.\n",
            "headers": {
              "X-Canonn-AI-Generated": {
                "description": "Always `true`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Canonn-Files": {
                "description": "Streams grounded on files only. Comma-separated file ids.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletion"
                },
                "examples": {
                  "grounded": {
                    "value": {
                      "id": "chatcmpl-84af4cb938563908",
                      "object": "chat.completion",
                      "created": 1790572843,
                      "model": "canonn-r1",
                      "choices": [
                        {
                          "index": 0,
                          "message": {
                            "role": "assistant",
                            "content": "45 days from purchase."
                          },
                          "finish_reason": "stop",
                          "logprobs": null
                        }
                      ],
                      "usage": {
                        "prompt_tokens": 47,
                        "completion_tokens": 7,
                        "total_tokens": 54
                      },
                      "canonn": {
                        "ai_generated": true,
                        "generator": "canonn-r1",
                        "provider": "Canonn",
                        "generated_at": "2026-09-28T05:20:43.000Z",
                        "standard": "EU AI Act Art. 50(2)"
                      }
                    }
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "stream": {
                    "value": "data: {\"id\":\"chatcmpl-8a4413e02fea2712\",\"object\":\"chat.completion.chunk\",\"created\":1790572881,\"model\":\"canonn-r1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"The\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-8a4413e02fea2712\",\"object\":\"chat.completion.chunk\",\"created\":1790572881,\"model\":\"canonn-r1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\"},\"finish_reason\":\"stop\"}],\"usage\":{\"prompt_tokens\":45,\"completion_tokens\":30,\"total_tokens\":75}}\n\ndata: [DONE]\n"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/UpstreamUnavailable"
          }
        }
      }
    },
    "/models": {
      "get": {
        "tags": [
          "Models"
        ],
        "operationId": "listModels",
        "summary": "List available models",
        "description": "Returns the OpenAI-compatible model identifiers available to the authenticated API key.",
        "responses": {
          "200": {
            "description": "The models this key can address.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Model"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "canonn-r1",
                      "object": "model",
                      "created": 1785196800,
                      "owned_by": "canonn"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/models/{model_id}": {
      "get": {
        "tags": [
          "Models"
        ],
        "operationId": "retrieveModel",
        "summary": "Retrieve a model",
        "description": "What the OpenAI SDKs' `models.retrieve` calls. `canonn-r1` and its alias `canonn/canonn-r1` (URL-encoded) return the model; any other id is a 404 with code `model_not_found`.",
        "parameters": [
          {
            "name": "model_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "canonn-r1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The model.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Model"
                },
                "example": {
                  "id": "canonn-r1",
                  "object": "model",
                  "created": 1785196800,
                  "owned_by": "canonn"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          }
        }
      }
    },
    "/models/catalog": {
      "get": {
        "tags": [
          "Models"
        ],
        "operationId": "getModelCatalog",
        "summary": "Model catalog with pricing",
        "description": "Public and unauthenticated. Returns the machine-readable catalog used by\naggregators and marketplaces: context length, modalities, supported\nparameters and per-token prices in USD.\n",
        "security": [],
        "responses": {
          "200": {
            "description": "Catalog entry per served model.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CatalogModel"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "canonn-r1",
                      "name": "Canonn R1",
                      "created": 1785196800,
                      "description": "A 9B model fine-tuned for context faithfulness: it answers from the documents it is given and says so when the answer is absent. The API flags contradictions (a conflict check in front of the model). Benchmarks: canonn.ai/benchmark",
                      "input_modalities": [
                        "text"
                      ],
                      "output_modalities": [
                        "text"
                      ],
                      "context_length": 16384,
                      "max_output_length": 4096,
                      "pricing": {
                        "prompt": "0.00000025",
                        "completion": "0.000001",
                        "image": "0",
                        "request": "0"
                      },
                      "quantization": "bf16",
                      "hugging_face_id": null,
                      "supported_sampling_parameters": [
                        "temperature",
                        "top_p",
                        "max_tokens",
                        "stop",
                        "seed"
                      ],
                      "supported_features": [
                        "streaming",
                        "json_mode",
                        "structured_outputs"
                      ],
                      "datacenters": [
                        {
                          "country_code": "CA"
                        }
                      ],
                      "is_ready": true,
                      "is_free": false
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/files": {
      "post": {
        "tags": [
          "Files"
        ],
        "operationId": "createFile",
        "summary": "Upload or import a knowledge file",
        "description": "Uploads a document to ground chat completions on. Accepts multipart/form-data with a `file` field (OpenAI-compatible) or `application/json` with `filename` and `content`. Supported: plain text, Markdown, JSON (one passage per record), HTML. Max 1 MB per uploaded file, 100 files per account, 30 uploads an hour.\n\nA JSON body may instead name a source the server fetches: `url` (with optional `crawl`), `sitemap`, `feed`, `zendesk`, `helpcenter`, `github`, `postgres`, `mysql` or `rest`. Web imports add `found` and `records` to the response.\n\nThe file answers at once from a size-based first cut; the model then re-cuts it in the background (`chunking`: `pending`, `working`, then `model`, `partial` or `heuristic`).",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "purpose": {
                    "type": "string",
                    "example": "assistants"
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileSourceRequest"
              },
              "examples": {
                "text": {
                  "summary": "Text you extracted yourself",
                  "value": {
                    "filename": "faq.txt",
                    "content": "Q: What is the refund window? A: 45 days from purchase."
                  }
                },
                "url": {
                  "summary": "One public page",
                  "value": {
                    "url": "https://canonn.ai/about/"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored file.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/File"
                },
                "example": {
                  "id": "file-2da93b04d430cc5e52d1ef9b",
                  "object": "file",
                  "purpose": "assistants",
                  "filename": "policy.md",
                  "bytes": 365,
                  "created_at": 1790572907,
                  "status": "processed",
                  "chunk_count": 1,
                  "chunking": "pending"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "get": {
        "tags": [
          "Files"
        ],
        "operationId": "listFiles",
        "summary": "List knowledge files",
        "description": "Lists every knowledge file on the account, newest first.",
        "responses": {
          "200": {
            "description": "Files owned by the key's account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "object",
                    "data"
                  ],
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/File"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/files/preview": {
      "post": {
        "tags": [
          "Files"
        ],
        "operationId": "previewDatabaseSource",
        "summary": "Preview a database source",
        "description": "With the same `postgres` or `mysql` body as POST /files, returns the first 5 rows; with `\"tables\": true` inside the `postgres` or `mysql` object, lists the tables with row counts and columns. Nothing is stored.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "postgres": {
                    "$ref": "#/components/schemas/SqlSource"
                  },
                  "mysql": {
                    "$ref": "#/components/schemas/SqlSource"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Preview rows, or the table list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/files/{file_id}": {
      "get": {
        "tags": [
          "Files"
        ],
        "operationId": "retrieveFile",
        "summary": "Retrieve a file's metadata",
        "description": "Returns metadata and chunking state for one file on the account.",
        "parameters": [
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "responses": {
          "200": {
            "description": "The file.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/File"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "delete": {
        "tags": [
          "Files"
        ],
        "operationId": "deleteFile",
        "summary": "Delete a file and its passages",
        "description": "Permanently removes the file and all passages derived from it.",
        "parameters": [
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion confirmation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "object",
                    "deleted"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "object": {
                      "type": "string",
                      "const": "file"
                    },
                    "deleted": {
                      "type": "boolean",
                      "const": true
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/files/{file_id}/content": {
      "get": {
        "tags": [
          "Files"
        ],
        "operationId": "downloadFileContent",
        "summary": "Download the file's extracted text",
        "description": "Returns plain text reconstructed from the file's stored passages.",
        "parameters": [
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "responses": {
          "200": {
            "description": "Plain-text content reconstructed from the stored passages.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/files/{file_id}/chunks": {
      "get": {
        "tags": [
          "Files"
        ],
        "operationId": "listFileChunks",
        "summary": "List a file's passages",
        "description": "The passages as retrieval sees them, with the context line the model wrote for each and how each was cut (`judge`, `heuristic` or `record`).",
        "parameters": [
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "responses": {
          "200": {
            "description": "The file's passages in order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChunkList"
                },
                "example": {
                  "object": "list",
                  "file_id": "file-2da93b04d430cc5e52d1ef9b",
                  "filename": "policy.md",
                  "chunking": "model",
                  "chunking_at": 1790572911,
                  "chunk_count": 1,
                  "data": [
                    {
                      "ordinal": 0,
                      "method": "judge",
                      "context": "HarborPay pricing policy - pricing policy: HarborPay charges 2.9% plus 30 cents per card transaction, with a 2026 note of 3.1%.",
                      "text": "# HarborPay pricing policy\n\nHarborPay charges 2.9% plus 30 cents per card transaction.\n\nInternational cards add 1.5%.",
                      "chars": 492,
                      "n_tokens": 66
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/audits": {
      "post": {
        "tags": [
          "Audits"
        ],
        "operationId": "createAudit",
        "summary": "Audit a knowledge file",
        "description": "Finds statements in one file that contradict each other or have gone out of date. Returns at once with 202; poll GET /audits/{audit_id} until `status` is `done`. Instead of `file_id`, the body may name a source to import first (`url` with optional `crawl`, `sitemap` or `zendesk`); the imported file stays on the account. 5 audits a day per account.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "file_id": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  },
                  "crawl": {
                    "type": "boolean"
                  },
                  "sitemap": {
                    "type": "string"
                  },
                  "zendesk": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "file_id": "file-2da93b04d430cc5e52d1ef9b"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The audit was created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "file_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "judging",
                        "done"
                      ]
                    },
                    "chunks": {
                      "type": "integer"
                    },
                    "claims": {
                      "type": "integer"
                    },
                    "candidates": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "id": "audit-f2aa302029e45b6d7026",
                  "file_id": "file-2da93b04d430cc5e52d1ef9b",
                  "status": "done",
                  "chunks": 1,
                  "claims": 4,
                  "candidates": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/FlatBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/FlatUnauthorized"
          },
          "404": {
            "$ref": "#/components/responses/FlatNotFound"
          },
          "429": {
            "$ref": "#/components/responses/FlatRateLimited"
          }
        }
      },
      "get": {
        "tags": [
          "Audits"
        ],
        "operationId": "listAudits",
        "summary": "List audits",
        "description": "The account's 50 most recent audits, without reports.",
        "responses": {
          "200": {
            "description": "Audits, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Audit"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/FlatUnauthorized"
          }
        }
      }
    },
    "/audits/{audit_id}": {
      "get": {
        "tags": [
          "Audits"
        ],
        "operationId": "retrieveAudit",
        "summary": "Retrieve an audit",
        "description": "Progress, and once `status` is `done`, the report.",
        "parameters": [
          {
            "name": "audit_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The audit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Audit"
                },
                "example": {
                  "id": "audit-f2aa302029e45b6d7026",
                  "object": "audit",
                  "file_id": "file-2da93b04d430cc5e52d1ef9b",
                  "source": "policy.md",
                  "status": "done",
                  "stage": "no measurable claims disagree",
                  "chunks": 1,
                  "claims": 4,
                  "candidates": 0,
                  "judged": 0,
                  "progress": 1,
                  "created_at": 1790572956,
                  "updated_at": 1790572956,
                  "report": {
                    "judge": "canonn-r1",
                    "chunks": 1,
                    "claims": 4,
                    "candidates": 0,
                    "conflicts": 0,
                    "stale": 0,
                    "items": []
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/FlatUnauthorized"
          },
          "404": {
            "$ref": "#/components/responses/FlatNotFound"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "A Canonn API key, created in the dashboard (`canonn-sk-...`)."
      }
    },
    "parameters": {
      "FileId": {
        "name": "file_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "example": "file-2da93b04d430cc5e52d1ef9b"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Malformed request body, or a parameter canonn-r1 does not support.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "invalid_json": {
                "value": {
                  "error": {
                    "message": "invalid json",
                    "type": "invalid_request_error",
                    "param": null,
                    "code": null
                  }
                }
              },
              "unsupported": {
                "value": {
                  "error": {
                    "message": "tools are not supported by canonn-r1 yet",
                    "type": "invalid_request_error",
                    "param": "tools",
                    "code": "unsupported_parameter"
                  }
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, malformed, or revoked API key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "message": "invalid api key",
                "type": "authentication_error",
                "param": null,
                "code": "invalid_api_key"
              }
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "The free requests are spent and the account has no credits. Add\ncredits in the dashboard to continue. The body adds a `free_tier`\nobject with the account's limits.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ModelNotFound": {
        "description": "A model other than canonn-r1.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "message": "The model 'gpt-4o' does not exist. Use 'canonn-r1'.",
                "type": "invalid_request_error",
                "param": "model",
                "code": "model_not_found"
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "No such file on the account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "message": "file not found",
                "type": "invalid_request_error",
                "param": null,
                "code": "not_found"
              }
            }
          }
        }
      },
      "TooLarge": {
        "description": "An uploaded file over 1 MB.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "More than 120 chat completions a minute on one key (code\n`rate_limit_exceeded`), more than 30 uploads an hour, or every serving\nnode busy (code `capacity`, with `Retry-After: 2`).\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "UpstreamUnavailable": {
        "description": "The model could not be reached. Retry; requests are not billed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "FlatBadRequest": {
        "description": "Malformed body or no source named.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/FlatError"
            },
            "example": {
              "error": "file_id, zendesk, sitemap or url is required"
            }
          }
        }
      },
      "FlatUnauthorized": {
        "description": "Missing, malformed, or revoked API key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/FlatError"
            },
            "example": {
              "error": "invalid API key"
            }
          }
        }
      },
      "FlatNotFound": {
        "description": "No such file or audit on the account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/FlatError"
            },
            "example": {
              "error": "audit not found"
            }
          }
        }
      },
      "FlatRateLimited": {
        "description": "More than 5 audits in a day.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/FlatError"
            },
            "example": {
              "error": "audit limit reached (5 a day)"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "message",
              "type",
              "param",
              "code"
            ],
            "properties": {
              "message": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "description": "invalid_request_error, authentication_error, insufficient_quota, rate_limit_error or server_error."
              },
              "param": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "code": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        }
      },
      "FlatError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "Message": {
        "type": "object",
        "required": [
          "role",
          "content"
        ],
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "system",
              "user",
              "assistant"
            ],
            "description": "Put the documents to answer from in the `system` message and the\nquestion in the `user` message.\n"
          },
          "content": {
            "type": "string"
          }
        }
      },
      "ChatCompletionRequest": {
        "type": "object",
        "required": [
          "messages"
        ],
        "properties": {
          "model": {
            "type": "string",
            "default": "canonn-r1",
            "description": "`canonn-r1` (the alias `canonn/canonn-r1` also works). Omitted means\ncanonn-r1; any other name is a 404 with code `model_not_found`.\n"
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "description": "Return server-sent events instead of a single JSON body."
          },
          "stream_options": {
            "type": "object",
            "properties": {
              "include_usage": {
                "type": "boolean",
                "description": "Adds OpenAI's separate final usage chunk."
              }
            }
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 2,
            "default": 0.2,
            "description": "Set 0 for extraction work; higher values only add variance."
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 1,
            "maximum": 4096,
            "default": 1024,
            "description": "Values above 4096 are lowered to 4096."
          },
          "top_p": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "stop": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "seed": {
            "type": "integer"
          },
          "response_format": {
            "type": "object",
            "description": "`{\"type\": \"json_object\"}` or `{\"type\": \"json_schema\", ...}`, as in the OpenAI API."
          },
          "files": {
            "description": "Ground the answer on uploaded knowledge files: an array of up to 20 file ids, or `true` for every file on the account. The server retrieves the most relevant passages and builds the grounded prompt; the response's `canonn.citations` names them.",
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "array",
                "maxItems": 20,
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "retrieval": {
            "type": "object",
            "description": "Retrieval tuning when `files` is set.",
            "properties": {
              "top_k": {
                "type": "integer",
                "default": 8,
                "maximum": 40
              },
              "budget": {
                "type": "integer",
                "default": 12000,
                "maximum": 60000,
                "description": "Max characters of retrieved data placed in front of the model."
              }
            }
          },
          "canonn": {
            "type": "boolean",
            "default": false,
            "description": "Streams only. Adds a `data: {\"canonn\": {...}}` event before `[DONE]`."
          },
          "tools": {
            "description": "Not supported. A non-empty list is a 400 with code `unsupported_parameter`."
          },
          "logprobs": {
            "description": "Not supported. `true` is a 400 with code `unsupported_parameter`."
          },
          "n": {
            "description": "Ignored. Every request returns one choice."
          }
        }
      },
      "Choice": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer"
          },
          "message": {
            "$ref": "#/components/schemas/Message"
          },
          "finish_reason": {
            "type": "string",
            "enum": [
              "stop",
              "length"
            ],
            "description": "`length` means the answer was cut off by `max_tokens`. Raise it and\nretry rather than shipping a truncated answer.\n"
          },
          "logprobs": {
            "type": "null"
          }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "prompt_tokens": {
            "type": "integer"
          },
          "completion_tokens": {
            "type": "integer"
          },
          "total_tokens": {
            "type": "integer"
          }
        }
      },
      "Citation": {
        "type": "object",
        "properties": {
          "file_id": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "ordinal": {
            "type": "integer",
            "description": "The passage's position in the file, as in GET /files/{file_id}/chunks."
          },
          "score": {
            "type": "number"
          },
          "excerpt": {
            "type": "string",
            "description": "The first 400 characters of the passage, context line included."
          }
        }
      },
      "CanonnExtras": {
        "type": "object",
        "description": "Canonn's additions to a completion. OpenAI SDKs ignore the field.",
        "properties": {
          "route": {
            "type": "object",
            "description": "Present when the router ran (data between 300 and 60,000\ncharacters). `p` is null when the router could not be reached and\nthe default expert answered. `p_absent` is present when the check on\nwhether the data contains the answer ran.\n",
            "properties": {
              "route": {
                "type": "string",
                "enum": [
                  "default",
                  "conflict",
                  "injection",
                  "absent"
                ]
              },
              "p": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "default": {
                    "type": "number"
                  },
                  "conflict": {
                    "type": "number"
                  },
                  "injection": {
                    "type": "number"
                  }
                }
              },
              "p_absent": {
                "type": "number",
                "description": "Probability that the data does not contain the answer."
              }
            }
          },
          "conflict": {
            "type": "object",
            "description": "Present when the router or the conflict check ran.",
            "properties": {
              "p": {
                "type": "number",
                "description": "Probability that the data contradicts itself on this question."
              },
              "flagged": {
                "type": "boolean",
                "description": "Whether the answer was sent down the conflict path."
              }
            }
          },
          "files": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "citations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Citation"
            }
          },
          "ai_generated": {
            "type": "boolean"
          },
          "generator": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "standard": {
            "type": "string",
            "example": "EU AI Act Art. 50(2)"
          }
        }
      },
      "ChatCompletion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "chat.completion"
          },
          "created": {
            "type": "integer",
            "description": "Unix seconds."
          },
          "model": {
            "type": "string"
          },
          "choices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Choice"
            }
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          },
          "canonn": {
            "$ref": "#/components/schemas/CanonnExtras"
          }
        }
      },
      "Model": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "model"
          },
          "created": {
            "type": "integer"
          },
          "owned_by": {
            "type": "string"
          }
        }
      },
      "CatalogModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "created": {
            "type": "integer"
          },
          "description": {
            "type": "string"
          },
          "input_modalities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "output_modalities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "context_length": {
            "type": "integer"
          },
          "max_output_length": {
            "type": "integer"
          },
          "pricing": {
            "type": "object",
            "description": "USD per token, as strings.",
            "properties": {
              "prompt": {
                "type": "string"
              },
              "completion": {
                "type": "string"
              },
              "image": {
                "type": "string"
              },
              "request": {
                "type": "string"
              }
            }
          },
          "quantization": {
            "type": "string"
          },
          "hugging_face_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "supported_sampling_parameters": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "supported_features": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "datacenters": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "country_code": {
                  "type": "string",
                  "description": "ISO 3166-1 alpha-2"
                }
              }
            }
          },
          "is_ready": {
            "type": "boolean"
          },
          "is_free": {
            "type": "boolean"
          }
        }
      },
      "SqlSource": {
        "type": "object",
        "properties": {
          "connection_string": {
            "type": "string"
          },
          "query": {
            "type": "string"
          },
          "table": {
            "type": "object",
            "properties": {
              "schema": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "tables": {
            "type": "boolean"
          }
        }
      },
      "FileSourceRequest": {
        "type": "object",
        "description": "Exactly one source.",
        "properties": {
          "filename": {
            "type": "string"
          },
          "content": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "crawl": {
            "type": "boolean"
          },
          "sitemap": {
            "type": "string"
          },
          "feed": {
            "type": "string"
          },
          "zendesk": {
            "type": "string",
            "example": "support.acme.com"
          },
          "helpcenter": {
            "type": "object",
            "properties": {
              "provider": {
                "type": "string",
                "enum": [
                  "intercom",
                  "helpscout",
                  "hubspot"
                ]
              },
              "url": {
                "type": "string"
              }
            }
          },
          "github": {
            "type": "string",
            "example": "owner/repo"
          },
          "postgres": {
            "$ref": "#/components/schemas/SqlSource"
          },
          "mysql": {
            "$ref": "#/components/schemas/SqlSource"
          },
          "rest": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string"
              },
              "authorization": {
                "type": "string"
              }
            }
          }
        }
      },
      "File": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "file-2da93b04d430cc5e52d1ef9b"
          },
          "object": {
            "type": "string",
            "example": "file"
          },
          "purpose": {
            "type": "string",
            "example": "assistants"
          },
          "filename": {
            "type": "string"
          },
          "bytes": {
            "type": "integer"
          },
          "created_at": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "example": "processed"
          },
          "chunk_count": {
            "type": "integer",
            "description": "Retrievable passages extracted from the file."
          },
          "chunking": {
            "type": "string",
            "enum": [
              "pending",
              "working",
              "model",
              "partial",
              "heuristic"
            ],
            "description": "Where the model re-cut of the file stands."
          },
          "found": {
            "type": "integer",
            "description": "Web imports only. Records the source offered."
          },
          "records": {
            "type": "integer",
            "description": "Web imports only. Records imported."
          }
        }
      },
      "ChunkList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "file_id": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "chunking": {
            "type": "string"
          },
          "chunking_at": {
            "type": [
              "integer",
              "null"
            ]
          },
          "chunk_count": {
            "type": "integer"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "ordinal": {
                  "type": "integer"
                },
                "method": {
                  "type": "string",
                  "enum": [
                    "judge",
                    "heuristic",
                    "record"
                  ]
                },
                "context": {
                  "type": "string"
                },
                "text": {
                  "type": "string"
                },
                "chars": {
                  "type": "integer"
                },
                "n_tokens": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "Audit": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "audit"
          },
          "file_id": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "judging",
              "done"
            ]
          },
          "stage": {
            "type": "string"
          },
          "chunks": {
            "type": "integer"
          },
          "claims": {
            "type": "integer"
          },
          "candidates": {
            "type": "integer"
          },
          "judged": {
            "type": "integer"
          },
          "progress": {
            "type": "number"
          },
          "created_at": {
            "type": "integer"
          },
          "updated_at": {
            "type": "integer"
          },
          "report": {
            "type": "object",
            "description": "Present once `status` is `done` (GET /audits/{audit_id} only).",
            "properties": {
              "judge": {
                "type": "string"
              },
              "chunks": {
                "type": "integer"
              },
              "claims": {
                "type": "integer"
              },
              "candidates": {
                "type": "integer"
              },
              "conflicts": {
                "type": "integer"
              },
              "stale": {
                "type": "integer"
              },
              "possible": {
                "type": "integer"
              },
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "kind": {
                      "type": "string",
                      "enum": [
                        "conflict",
                        "stale"
                      ]
                    },
                    "confidence": {
                      "type": "string",
                      "enum": [
                        "likely",
                        "possible"
                      ]
                    },
                    "p": {
                      "type": "number"
                    },
                    "topic": {
                      "type": "string"
                    },
                    "a": {
                      "type": "object",
                      "properties": {
                        "ordinal": {
                          "type": "integer"
                        },
                        "quote": {
                          "type": "string"
                        },
                        "value": {
                          "type": "string"
                        }
                      }
                    },
                    "b": {
                      "type": "object",
                      "properties": {
                        "ordinal": {
                          "type": "integer"
                        },
                        "quote": {
                          "type": "string"
                        },
                        "value": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
