{
  "components": {
    "parameters": {
      "FolderId": {
        "description": "Owlish knowledge-folder identifier.",
        "in": "path",
        "name": "id",
        "required": true,
        "schema": {
          "example": "fld_abc123def456gh",
          "type": "string"
        }
      },
      "SourceId": {
        "description": "Owlish knowledge-source identifier.",
        "in": "path",
        "name": "id",
        "required": true,
        "schema": {
          "example": "src_abc123def456gh",
          "type": "string"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        },
        "description": "The request shape or resource state is not valid for this operation."
      },
      "Conflict": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        },
        "description": "The requested mutation conflicts with the current resource state."
      },
      "Forbidden": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        },
        "description": "The workspace plan or credential scope does not permit this operation."
      },
      "NotFound": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        },
        "description": "The resource does not exist in the credential's workspace."
      },
      "RateLimited": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        },
        "description": "The credential exceeded the API request rate limit."
      },
      "Unauthorized": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiError"
            }
          }
        },
        "description": "The Bearer token is missing, invalid, expired, or revoked."
      }
    },
    "schemas": {
      "ApiError": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "additionalProperties": false,
            "properties": {
              "code": {
                "description": "Stable machine-readable error code.",
                "example": "insufficient_scope",
                "type": "string"
              },
              "message": {
                "description": "Short action-oriented error description.",
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ],
            "type": "object"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "CapacityError": {
        "additionalProperties": false,
        "properties": {
          "code": {
            "const": "kb_capacity_reached"
          },
          "error": {
            "type": "string"
          },
          "limit_bytes": {
            "minimum": 0,
            "type": "integer"
          },
          "used_bytes": {
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "code",
          "error",
          "limit_bytes",
          "used_bytes"
        ],
        "type": "object"
      },
      "CreateFolderRequest": {
        "additionalProperties": false,
        "properties": {
          "name": {
            "description": "Human-readable folder name.",
            "example": "Product documentation",
            "minLength": 1,
            "type": "string"
          },
          "type": {
            "default": "file",
            "description": "Kind of content organized by the folder.",
            "enum": [
              "file",
              "direct_response",
              "website"
            ],
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "CreateSourceInput": {
        "oneOf": [
          {
            "additionalProperties": false,
            "properties": {
              "folder_id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "type": {
                "const": "webpage"
              },
              "url": {
                "format": "uri",
                "type": "string"
              }
            },
            "required": [
              "folder_id",
              "type",
              "url"
            ],
            "title": "Webpage source",
            "type": "object"
          },
          {
            "additionalProperties": false,
            "properties": {
              "file": {
                "additionalProperties": false,
                "properties": {
                  "content": {
                    "contentEncoding": "base64",
                    "description": "Base64-encoded file bytes.",
                    "type": "string"
                  },
                  "file_name": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "mime_type": {
                    "description": "IANA media type for the uploaded bytes.",
                    "example": "text/markdown",
                    "type": "string"
                  }
                },
                "required": [
                  "content",
                  "file_name",
                  "mime_type"
                ],
                "type": "object"
              },
              "folder_id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "type": {
                "const": "file"
              }
            },
            "required": [
              "file",
              "folder_id",
              "type"
            ],
            "title": "File source",
            "type": "object"
          }
        ],
        "type": "object"
      },
      "CreateSourcesRequest": {
        "additionalProperties": false,
        "properties": {
          "sources": {
            "items": {
              "$ref": "#/components/schemas/CreateSourceInput"
            },
            "maxItems": 100,
            "minItems": 1,
            "type": "array"
          }
        },
        "required": [
          "sources"
        ],
        "type": "object"
      },
      "DeleteResult": {
        "additionalProperties": false,
        "properties": {
          "deleted": {
            "const": true
          },
          "id": {
            "type": "string"
          },
          "permanent": {
            "type": "boolean"
          }
        },
        "required": [
          "deleted",
          "id",
          "permanent"
        ],
        "type": "object"
      },
      "Folder": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "example": "fld_abc123def456gh",
            "type": "string"
          },
          "name": {
            "example": "Product documentation",
            "type": "string"
          },
          "parent_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "source_count": {
            "minimum": 0,
            "type": "integer"
          },
          "sync": {
            "additionalProperties": false,
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "interval_hours": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "next_sync_at": {
                "format": "date-time",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "enabled",
              "interval_hours",
              "next_sync_at"
            ],
            "type": "object"
          },
          "type": {
            "enum": [
              "file",
              "direct_response",
              "website"
            ],
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "created_at",
          "id",
          "name",
          "parent_id",
          "source_count",
          "sync",
          "type",
          "updated_at"
        ],
        "type": "object"
      },
      "FolderList": {
        "additionalProperties": false,
        "properties": {
          "folders": {
            "items": {
              "$ref": "#/components/schemas/Folder"
            },
            "type": "array"
          }
        },
        "required": [
          "folders"
        ],
        "type": "object"
      },
      "FolderRetryResult": {
        "additionalProperties": false,
        "properties": {
          "folder_id": {
            "type": "string"
          },
          "retried_count": {
            "minimum": 0,
            "type": "integer"
          },
          "retried_source_ids": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "folder_id",
          "retried_count",
          "retried_source_ids"
        ],
        "type": "object"
      },
      "FolderSyncResult": {
        "additionalProperties": false,
        "properties": {
          "folder_id": {
            "type": "string"
          },
          "synced_count": {
            "minimum": 0,
            "type": "integer"
          },
          "synced_source_ids": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "folder_id",
          "synced_count",
          "synced_source_ids"
        ],
        "type": "object"
      },
      "MutationStatus": {
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "enum": [
              "pending",
              "processing"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "status"
        ],
        "type": "object"
      },
      "ReplaceSourceRequest": {
        "additionalProperties": false,
        "properties": {
          "file": {
            "additionalProperties": false,
            "properties": {
              "content": {
                "contentEncoding": "base64",
                "type": "string"
              },
              "file_name": {
                "minLength": 1,
                "type": "string"
              },
              "mime_type": {
                "type": "string"
              }
            },
            "required": [
              "content",
              "file_name",
              "mime_type"
            ],
            "type": "object"
          }
        },
        "required": [
          "file"
        ],
        "type": "object"
      },
      "Source": {
        "additionalProperties": false,
        "properties": {
          "chunk_count": {
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "content_date": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ]
          },
          "file": {
            "additionalProperties": false,
            "properties": {
              "content_hash": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "mime_type": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "size_bytes": {
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "storage_path": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "folder_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "example": "src_abc123def456gh",
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "processed_at": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "pending",
              "queued",
              "processing",
              "completed",
              "failed",
              "deleted",
              "needs_reindex"
            ],
            "type": "string"
          },
          "token_count": {
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "type": {
            "enum": [
              "file",
              "webpage",
              "direct_response",
              "other"
            ],
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          },
          "webpage": {
            "additionalProperties": false,
            "properties": {
              "crawled_at": {
                "format": "date-time",
                "type": [
                  "string",
                  "null"
                ]
              },
              "title": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "format": "uri",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          }
        },
        "required": [
          "chunk_count",
          "content_date",
          "created_at",
          "error_message",
          "folder_id",
          "id",
          "name",
          "processed_at",
          "status",
          "token_count",
          "type",
          "updated_at"
        ],
        "type": "object"
      },
      "SourceCreateResult": {
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "enum": [
              "pending",
              "processing"
            ],
            "type": "string"
          },
          "type": {
            "enum": [
              "file",
              "webpage"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "status",
          "type"
        ],
        "type": "object"
      },
      "SourceCreateResultList": {
        "additionalProperties": false,
        "properties": {
          "sources": {
            "items": {
              "$ref": "#/components/schemas/SourceCreateResult"
            },
            "type": "array"
          }
        },
        "required": [
          "sources"
        ],
        "type": "object"
      },
      "SourceList": {
        "additionalProperties": false,
        "properties": {
          "page": {
            "minimum": 1,
            "type": "integer"
          },
          "per_page": {
            "maximum": 100,
            "minimum": 1,
            "type": "integer"
          },
          "sources": {
            "items": {
              "$ref": "#/components/schemas/Source"
            },
            "type": "array"
          },
          "total": {
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "page",
          "per_page",
          "sources",
          "total"
        ],
        "type": "object"
      },
      "UpdateFolderRequest": {
        "additionalProperties": false,
        "anyOf": [
          {
            "required": [
              "name"
            ]
          },
          {
            "required": [
              "sync_enabled"
            ]
          },
          {
            "required": [
              "sync_interval_hours"
            ]
          }
        ],
        "properties": {
          "name": {
            "minLength": 1,
            "type": "string"
          },
          "sync_enabled": {
            "type": "boolean"
          },
          "sync_interval_hours": {
            "description": "Hours between automatic syncs; required when enabling sync.",
            "minimum": 1,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "UpdateSourceRequest": {
        "additionalProperties": false,
        "anyOf": [
          {
            "required": [
              "name"
            ]
          },
          {
            "required": [
              "folder_id"
            ]
          }
        ],
        "properties": {
          "folder_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "minLength": 1,
            "type": "string"
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "workspaceApiKey": {
        "bearerFormat": "Owlish workspace API key (owl_wsk_...)",
        "description": "Workspace-scoped API key created in Owlish Console under Settings > API keys. Each operation declares its least-privilege requirement in `x-required-scopes`; the complete machine-readable scope catalog is also published through RFC 9728 protected-resource metadata.",
        "scheme": "bearer",
        "type": "http",
        "x-scopes": {
          "knowledge_base:delete": "Soft-delete or permanently delete knowledge sources and folders.",
          "knowledge_base:read": "List and inspect knowledge sources and folders.",
          "knowledge_base:write": "Create, update, sync, retry, and restore knowledge sources and folders."
        }
      }
    }
  },
  "externalDocs": {
    "description": "Owlish developer documentation",
    "url": "https://owlish.bot/docs/developers/overview/"
  },
  "info": {
    "contact": {
      "email": "support@owlish.bot",
      "name": "Owlish developer support",
      "url": "https://owlish.bot/docs/help/"
    },
    "description": "Programmatic knowledge-base management for Owlish AI customer-support agents. The API is workspace-scoped, rate-limited to 100 requests per minute per credential, and available on Growth and Scale plans. Create keys in Owlish Console, grant only the scopes each integration needs, and use the RFC 9728 metadata endpoint for the canonical scope catalog.",
    "license": {
      "name": "Owlish Terms of Service",
      "url": "https://owlish.bot/legal/terms/"
    },
    "summary": "Manage the knowledge sources that ground Owlish agents.",
    "title": "Owlish Knowledge Base API",
    "version": "1.0.0"
  },
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "openapi": "3.1.1",
  "paths": {
    "/v1/folders": {
      "get": {
        "description": "Returns every active folder in the authenticated workspace, including source counts and automatic-sync settings.",
        "operationId": "listFolders",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolderList"
                }
              }
            },
            "description": "Active folders ordered by name."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "List folders",
        "tags": [
          "Folders"
        ],
        "x-required-scopes": [
          "knowledge_base:read"
        ]
      },
      "post": {
        "description": "Creates a knowledge folder in the authenticated workspace. Use the folder type that matches the sources it will organize.",
        "operationId": "createFolder",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFolderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Folder"
                }
              }
            },
            "description": "Folder created."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Create a folder",
        "tags": [
          "Folders"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      }
    },
    "/v1/folders/{id}": {
      "delete": {
        "description": "Soft-deletes a folder by default. `force=true` permits deleting a non-empty folder; `permanent=true` makes the deletion irreversible.",
        "operationId": "deleteFolder",
        "parameters": [
          {
            "$ref": "#/components/parameters/FolderId"
          },
          {
            "description": "Permit deletion when the folder contains sources.",
            "in": "query",
            "name": "force",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          },
          {
            "description": "Permanently delete instead of moving to the recycle bin.",
            "in": "query",
            "name": "permanent",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteResult"
                }
              }
            },
            "description": "Folder deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Delete a folder",
        "tags": [
          "Folders"
        ],
        "x-required-scopes": [
          "knowledge_base:delete"
        ]
      },
      "get": {
        "description": "Returns one active folder from the authenticated workspace, including source count and sync configuration.",
        "operationId": "getFolder",
        "parameters": [
          {
            "$ref": "#/components/parameters/FolderId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Folder"
                }
              }
            },
            "description": "Folder details."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Get a folder",
        "tags": [
          "Folders"
        ],
        "x-required-scopes": [
          "knowledge_base:read"
        ]
      },
      "patch": {
        "description": "Renames a folder, changes its automatic-sync configuration, or performs both changes atomically from the caller's perspective.",
        "operationId": "updateFolder",
        "parameters": [
          {
            "$ref": "#/components/parameters/FolderId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateFolderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Folder"
                }
              }
            },
            "description": "Updated folder."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Update a folder",
        "tags": [
          "Folders"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      }
    },
    "/v1/folders/{id}/retry": {
      "post": {
        "description": "Resets every failed source in the folder and enqueues the appropriate ingestion task for each retryable source.",
        "operationId": "retryFolderSources",
        "parameters": [
          {
            "$ref": "#/components/parameters/FolderId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolderRetryResult"
                }
              }
            },
            "description": "Failed sources queued for retry."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Retry failed folder sources",
        "tags": [
          "Folders"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      }
    },
    "/v1/folders/{id}/sync": {
      "post": {
        "description": "Enqueues a fresh crawl and ingestion task for every webpage source in the folder; file and direct-response sources are skipped.",
        "operationId": "syncFolderSources",
        "parameters": [
          {
            "$ref": "#/components/parameters/FolderId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolderSyncResult"
                }
              }
            },
            "description": "Webpage sources queued for synchronization."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Synchronize a folder",
        "tags": [
          "Folders"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      }
    },
    "/v1/sources": {
      "get": {
        "description": "Returns a paginated list of active knowledge sources in the authenticated workspace, with optional folder, status, and type filters.",
        "operationId": "listSources",
        "parameters": [
          {
            "description": "One-based result page.",
            "in": "query",
            "name": "page",
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Results per page, capped at 100.",
            "in": "query",
            "name": "per_page",
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Folder identifier, or the literal `null` for unfiled sources.",
            "in": "query",
            "name": "folder_id",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Processing-status filter.",
            "in": "query",
            "name": "status",
            "schema": {
              "enum": [
                "pending",
                "queued",
                "processing",
                "completed",
                "failed"
              ],
              "type": "string"
            }
          },
          {
            "description": "Source-type filter.",
            "in": "query",
            "name": "type",
            "schema": {
              "enum": [
                "file",
                "webpage",
                "direct_response"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SourceList"
                }
              }
            },
            "description": "Paginated source list.",
            "headers": {
              "X-Total-Count": {
                "description": "Total matching sources.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "List sources",
        "tags": [
          "Sources"
        ],
        "x-required-scopes": [
          "knowledge_base:read"
        ]
      },
      "post": {
        "description": "Creates up to 100 webpage or file sources in one workspace-scoped request and queues asynchronous ingestion for each source.",
        "operationId": "createSources",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSourcesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SourceCreateResultList"
                }
              }
            },
            "description": "Sources created and queued for processing."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CapacityError"
                }
              }
            },
            "description": "Workspace knowledge-base capacity is exhausted."
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Create knowledge sources",
        "tags": [
          "Sources"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      }
    },
    "/v1/sources/{id}": {
      "delete": {
        "description": "Moves a source to the recycle bin by default. `permanent=true` irreversibly removes its stored data and metadata.",
        "operationId": "deleteSource",
        "parameters": [
          {
            "$ref": "#/components/parameters/SourceId"
          },
          {
            "description": "Permanently delete instead of moving to the recycle bin.",
            "in": "query",
            "name": "permanent",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteResult"
                }
              }
            },
            "description": "Source deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Delete a source",
        "tags": [
          "Sources"
        ],
        "x-required-scopes": [
          "knowledge_base:delete"
        ]
      },
      "get": {
        "description": "Returns one knowledge source from the authenticated workspace with processing status and type-specific metadata.",
        "operationId": "getSource",
        "parameters": [
          {
            "$ref": "#/components/parameters/SourceId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Source"
                }
              }
            },
            "description": "Source details."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Get a source",
        "tags": [
          "Sources"
        ],
        "x-required-scopes": [
          "knowledge_base:read"
        ]
      },
      "patch": {
        "description": "Renames a source, moves it to another folder, or performs both metadata changes without replacing its content.",
        "operationId": "updateSource",
        "parameters": [
          {
            "$ref": "#/components/parameters/SourceId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSourceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Source"
                }
              }
            },
            "description": "Updated source."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Update source metadata",
        "tags": [
          "Sources"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      },
      "put": {
        "description": "Replaces an uploaded source's bytes while retaining its source identifier and queues the ingestion pipeline again. Webpages must use the sync operation instead.",
        "operationId": "replaceSourceContent",
        "parameters": [
          {
            "$ref": "#/components/parameters/SourceId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceSourceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MutationStatus"
                }
              }
            },
            "description": "Replacement queued for processing."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Replace source content",
        "tags": [
          "Sources"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      }
    },
    "/v1/sources/{id}/restore": {
      "post": {
        "description": "Restores a soft-deleted source to its previous folder without changing its content or source identifier.",
        "operationId": "restoreSource",
        "parameters": [
          {
            "$ref": "#/components/parameters/SourceId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Source"
                }
              }
            },
            "description": "Restored source."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Restore a source",
        "tags": [
          "Sources"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      }
    },
    "/v1/sources/{id}/retry": {
      "post": {
        "description": "Resets a failed source to pending and enqueues the ingestion task appropriate to its source type.",
        "operationId": "retrySource",
        "parameters": [
          {
            "$ref": "#/components/parameters/SourceId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MutationStatus"
                }
              }
            },
            "description": "Source queued for retry."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Retry a failed source",
        "tags": [
          "Sources"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      }
    },
    "/v1/sources/{id}/sync": {
      "post": {
        "description": "Re-crawls a webpage source and queues fresh ingestion. Uploaded files must use the replace-content operation instead.",
        "operationId": "syncSource",
        "parameters": [
          {
            "$ref": "#/components/parameters/SourceId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MutationStatus"
                }
              }
            },
            "description": "Source queued for synchronization."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Synchronize a webpage source",
        "tags": [
          "Sources"
        ],
        "x-required-scopes": [
          "knowledge_base:write"
        ]
      }
    }
  },
  "security": [
    {
      "workspaceApiKey": []
    }
  ],
  "servers": [
    {
      "description": "Owlish production API",
      "url": "https://api.owlish.bot"
    }
  ],
  "tags": [
    {
      "description": "Organize related knowledge sources and sync schedules.",
      "name": "Folders"
    },
    {
      "description": "Create, inspect, update, synchronize, and remove knowledge sources.",
      "name": "Sources"
    }
  ]
}
