{ "openapi": "3.1.0", "info": { "title": "Scholia API", "description": "", "license": { "name": "" }, "version": "0.1.0" }, "paths": { "/api/article-quotations": { "get": { "tags": ["article-quotations"], "summary": "List current user's article quotations", "operationId": "list_article_quotations", "responses": { "200": { "description": "User's article quotations", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleQuotationListResponse" } } } }, "401": { "description": "Not authenticated" } } }, "post": { "tags": ["article-quotations"], "summary": "Save a quotation from an article (returns existing if duplicate)", "operationId": "create_article_quotation", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateArticleQuotationRequest" } } }, "required": true }, "responses": { "200": { "description": "Article quotation saved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateArticleQuotationResponse" } } } }, "400": { "description": "Invalid input" }, "401": { "description": "Not authenticated" } } } }, "/api/article-quotations/{id}": { "get": { "tags": ["article-quotations"], "summary": "Get a single article quotation (for directive hydration)", "operationId": "get_article_quotation", "parameters": [ { "name": "id", "in": "path", "description": "Article quotation ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Article quotation detail", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleQuotationResponse" } } } }, "404": { "description": "Not found" } } }, "delete": { "tags": ["article-quotations"], "summary": "Delete an article quotation", "operationId": "delete_article_quotation", "parameters": [ { "name": "id", "in": "path", "description": "Article quotation ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Article quotation deleted" }, "401": { "description": "Not authenticated" }, "404": { "description": "Not found" } } } }, "/api/articles": { "get": { "tags": ["articles"], "summary": "List published articles", "operationId": "list_published_articles", "parameters": [ { "name": "topic_slug", "in": "query", "required": false, "schema": { "type": ["string", "null"] } }, { "name": "page", "in": "query", "required": false, "schema": { "type": ["integer", "null"], "format": "int32" } }, { "name": "per_page", "in": "query", "required": false, "schema": { "type": ["integer", "null"], "format": "int32" } } ], "responses": { "200": { "description": "Published articles", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PublishedArticleListResponse" } } } } } }, "post": { "tags": ["articles"], "summary": "Create a new article", "operationId": "create_article", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateArticleRequest" } } }, "required": true }, "responses": { "200": { "description": "Article created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleDetailResponse" } } } }, "400": { "description": "Invalid input or limit reached" }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } } }, "/api/articles/by-id/{id}": { "get": { "tags": ["articles"], "summary": "Get a published/archived article by UUID (stable URL)", "operationId": "get_article_by_id", "parameters": [ { "name": "id", "in": "path", "description": "Article UUID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Article detail", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleDetailResponse" } } } }, "404": { "description": "Article not found" } } } }, "/api/articles/{slug}": { "get": { "tags": ["articles"], "summary": "Get a published article by slug", "operationId": "get_published_article", "parameters": [ { "name": "slug", "in": "path", "description": "Article slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Published article", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleDetailResponse" } } } }, "404": { "description": "Article not found" } } } }, "/api/books": { "get": { "tags": ["books"], "summary": "List all books", "operationId": "list_books", "responses": { "200": { "description": "List of books", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/BookSummary" } } } } } } } }, "/api/books/{slug}": { "get": { "tags": ["books"], "summary": "Get a book by slug", "operationId": "get_book", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Book details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BookDetail" } } } }, "404": { "description": "Book not found" } } } }, "/api/books/{slug}/nodes": { "get": { "tags": ["nodes"], "summary": "Get paginated nodes for infinite scroll", "operationId": "get_node_page", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "after", "in": "query", "description": "sort_order cursor — fetch nodes after this value", "required": false, "schema": { "type": ["integer", "null"], "format": "int32" } }, { "name": "before", "in": "query", "description": "sort_order cursor — fetch nodes before this value", "required": false, "schema": { "type": ["integer", "null"], "format": "int32" } }, { "name": "limit", "in": "query", "description": "page size, default 20, max 50", "required": false, "schema": { "type": ["integer", "null"], "format": "int32" } }, { "name": "original", "in": "query", "description": "include original_text/original_html fields", "required": false, "schema": { "type": ["boolean", "null"] } }, { "name": "source_nodes", "in": "query", "description": "Comma-separated source node UUIDs — fetch nodes whose source_node_id matches", "required": false, "schema": { "type": ["string", "null"] } }, { "name": "node_ids", "in": "query", "description": "Comma-separated node UUIDs — fetch nodes by their own ID", "required": false, "schema": { "type": ["string", "null"] } } ], "responses": { "200": { "description": "Page of nodes with content", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NodePage" } } } }, "404": { "description": "Book not found" } } } }, "/api/books/{slug}/nodes/{node_slug}": { "get": { "tags": ["nodes"], "summary": "Get node content (blocks + sentences)", "operationId": "get_node", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "node_slug", "in": "path", "description": "Node slug", "required": true, "schema": { "type": "string" } }, { "name": "original", "in": "query", "description": "include original_text/original_html fields", "required": false, "schema": { "type": ["boolean", "null"] } } ], "responses": { "200": { "description": "Node with content blocks and sentences", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NodeDetail" } } } }, "404": { "description": "Node not found" } } } }, "/api/books/{slug}/quotations": { "get": { "tags": ["quotations"], "summary": "List quotations for a node (authenticated user only)", "operationId": "list_quotations", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "node_id", "in": "query", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "User's quotations for the node", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QuotationListResponse" } } } }, "401": { "description": "Not authenticated" }, "404": { "description": "Book not found" } } }, "post": { "tags": ["quotations"], "summary": "Save a quotation (returns existing if duplicate)", "operationId": "create_quotation", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateQuotationRequest" } } }, "required": true }, "responses": { "200": { "description": "Quotation saved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateQuotationResponse" } } } }, "400": { "description": "Invalid input" }, "401": { "description": "Not authenticated" } } } }, "/api/books/{slug}/quotations/{id}": { "delete": { "tags": ["quotations"], "summary": "Delete a quotation (cascade-deletes notes)", "operationId": "delete_quotation", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "description": "Quotation ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Quotation deleted" }, "401": { "description": "Not authenticated" }, "404": { "description": "Quotation not found" } } } }, "/api/books/{slug}/quotations/{id}/notes": { "get": { "tags": ["quotations"], "summary": "List notes for a quotation", "operationId": "list_notes", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "description": "Quotation ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Notes for the quotation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NoteListResponse" } } } }, "401": { "description": "Not authenticated" }, "404": { "description": "Quotation not found" } } }, "post": { "tags": ["quotations"], "summary": "Create a note on a quotation", "operationId": "create_note", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "description": "Quotation ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateNoteRequest" } } }, "required": true }, "responses": { "200": { "description": "Note created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NoteResponse" } } } }, "400": { "description": "Invalid input" }, "401": { "description": "Not authenticated" }, "404": { "description": "Quotation not found" } } } }, "/api/books/{slug}/quotations/{id}/notes/{note_id}": { "put": { "tags": ["quotations"], "summary": "Update a note", "operationId": "update_note", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "description": "Quotation ID", "required": true, "schema": { "type": "string" } }, { "name": "note_id", "in": "path", "description": "Note ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateNoteRequest" } } }, "required": true }, "responses": { "200": { "description": "Note updated" }, "400": { "description": "Invalid input" }, "401": { "description": "Not authenticated" }, "404": { "description": "Note not found" } } }, "delete": { "tags": ["quotations"], "summary": "Delete a note", "operationId": "delete_note", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "description": "Quotation ID", "required": true, "schema": { "type": "string" } }, { "name": "note_id", "in": "path", "description": "Note ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Note deleted" }, "401": { "description": "Not authenticated" }, "404": { "description": "Note not found" } } } }, "/api/books/{slug}/resources": { "get": { "tags": ["resources"], "summary": "List resources for a sentence range (public)", "operationId": "list_resources", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "start", "in": "query", "required": true, "schema": { "type": "integer", "format": "int32" } }, { "name": "end", "in": "query", "required": true, "schema": { "type": "integer", "format": "int32" } }, { "name": "kind", "in": "query", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Resources for the sentence range", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResourceListResponse" } } } }, "404": { "description": "Book not found" } } }, "post": { "tags": ["resources"], "summary": "Create a new resource (editor only)", "operationId": "create_resource", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateResourceRequest" } } }, "required": true }, "responses": { "200": { "description": "Resource created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResourceListResponse" } } } }, "400": { "description": "Invalid input" }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } } }, "/api/books/{slug}/resources/{id}": { "put": { "tags": ["resources"], "summary": "Update an existing resource (editor only)", "operationId": "update_resource", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "description": "Resource ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateResourceRequest" } } }, "required": true }, "responses": { "200": { "description": "Resource updated" }, "400": { "description": "Invalid input" }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Resource not found" } } }, "delete": { "tags": ["resources"], "summary": "Soft-delete a resource (editor only)", "operationId": "delete_resource", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "description": "Resource ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Resource archived" }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Resource not found" } } } }, "/api/books/{slug}/toc": { "get": { "tags": ["toc"], "summary": "Get the full TOC tree for a book", "operationId": "get_toc", "parameters": [ { "name": "slug", "in": "path", "description": "Book slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "TOC tree", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TocNodeResponse" } } } } }, "404": { "description": "Book not found" } } } }, "/api/library": { "get": { "tags": ["books"], "summary": "Get the grouped library tree (authors → works → versions) with stats.", "operationId": "get_library", "responses": { "200": { "description": "Library tree", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LibraryResponse" } } } } } } }, "/api/notes": { "get": { "tags": ["quotations"], "summary": "List all notes for the authenticated user (across all books)", "operationId": "list_all_notes", "parameters": [ { "name": "book_slug", "in": "query", "required": false, "schema": { "type": ["string", "null"] } } ], "responses": { "200": { "description": "User's notes across books", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NoteWithContextListResponse" } } } }, "401": { "description": "Not authenticated" } } } }, "/api/persons": { "get": { "tags": ["persons"], "summary": "Search persons by name", "operationId": "search_persons", "parameters": [ { "name": "q", "in": "query", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of matching persons", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PersonResponse" } } } } }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } }, "post": { "tags": ["persons"], "summary": "Create a new person", "operationId": "create_person", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatePersonRequest" } } }, "required": true }, "responses": { "200": { "description": "Person created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PersonResponse" } } } }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } } }, "/api/persons/{id}": { "put": { "tags": ["persons"], "summary": "Update an existing person", "operationId": "update_person", "parameters": [ { "name": "id", "in": "path", "description": "Person ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdatePersonRequest" } } }, "required": true }, "responses": { "200": { "description": "Person updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PersonResponse" } } } }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Person not found" } } } }, "/api/quotations": { "get": { "tags": ["quotations"], "summary": "List all quotations for the authenticated user (books + articles, unified)", "operationId": "list_all_quotations", "parameters": [ { "name": "book_slug", "in": "query", "required": false, "schema": { "type": ["string", "null"] } }, { "name": "source_type", "in": "query", "required": false, "schema": { "type": ["string", "null"] } } ], "responses": { "200": { "description": "User's quotations across books and articles", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UnifiedQuotationListResponse" } } } }, "401": { "description": "Not authenticated" } } } }, "/api/sentences/batch": { "post": { "tags": ["sentences"], "summary": "Batch fetch sentences for quotation card hydration", "operationId": "batch_sentences", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BatchSentencesRequest" } } }, "required": true }, "responses": { "200": { "description": "Sentence data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BatchSentencesResponse" } } } } } } }, "/api/sources": { "get": { "tags": ["sources"], "summary": "Search sources by title", "operationId": "search_sources", "parameters": [ { "name": "q", "in": "query", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of matching sources", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/SourceSearchResponse" } } } } }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } }, "post": { "tags": ["sources"], "summary": "Create a new source", "operationId": "create_source", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSourceRequest" } } }, "required": true }, "responses": { "200": { "description": "Source created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SourceResponse" } } } }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } } }, "/api/sources/browse": { "get": { "tags": ["sources"], "summary": "Browse sources (paginated, with filters)", "operationId": "browse_sources", "parameters": [ { "name": "q", "in": "query", "required": false, "schema": { "type": ["string", "null"] } }, { "name": "source_type", "in": "query", "required": false, "schema": { "type": ["string", "null"] } }, { "name": "created_by_me", "in": "query", "required": false, "schema": { "type": ["boolean", "null"] } }, { "name": "protected", "in": "query", "required": false, "schema": { "type": ["boolean", "null"] } }, { "name": "page", "in": "query", "required": false, "schema": { "type": ["integer", "null"], "format": "int32" } }, { "name": "per_page", "in": "query", "required": false, "schema": { "type": ["integer", "null"], "format": "int32" } } ], "responses": { "200": { "description": "Paginated sources", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SourceBrowseResponse" } } } }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } } }, "/api/sources/{id}": { "get": { "tags": ["sources"], "summary": "Get a source by ID", "operationId": "get_source", "parameters": [ { "name": "id", "in": "path", "description": "Source ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Source details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SourceResponse" } } } }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Source not found" } } }, "put": { "tags": ["sources"], "summary": "Update an existing source", "operationId": "update_source", "parameters": [ { "name": "id", "in": "path", "description": "Source ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateSourceRequest" } } }, "required": true }, "responses": { "200": { "description": "Source updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SourceResponse" } } } }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Source not found" } } }, "delete": { "tags": ["sources"], "summary": "Delete a source. Blocks when any references exist (resources, child\nsources, or article citations). Creator-only for non-editors.", "operationId": "delete_source", "parameters": [ { "name": "id", "in": "path", "description": "Source ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Source deleted" }, "400": { "description": "Source has active references" }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" }, "404": { "description": "Source not found" } } } }, "/api/sources/{id}/persons": { "post": { "tags": ["sources"], "summary": "Link a person to a source with a role", "operationId": "add_source_person", "parameters": [ { "name": "id", "in": "path", "description": "Source ID", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LinkSourcePersonRequest" } } }, "required": true }, "responses": { "200": { "description": "Person linked to source" }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } } }, "/api/sources/{id}/persons/{person_id}/{role}": { "delete": { "tags": ["sources"], "summary": "Remove a person from a source", "operationId": "remove_source_person", "parameters": [ { "name": "id", "in": "path", "description": "Source ID", "required": true, "schema": { "type": "string" } }, { "name": "person_id", "in": "path", "description": "Person ID", "required": true, "schema": { "type": "string" } }, { "name": "role", "in": "path", "description": "Role to remove", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Person unlinked from source" }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } } }, "/api/sources/{id}/references": { "get": { "tags": ["sources"], "summary": "Check if a source can be deleted (has active references)", "operationId": "check_source_references", "parameters": [ { "name": "id", "in": "path", "description": "Source ID", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Reference check result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReferenceCheckResponse" } } } }, "401": { "description": "Not authenticated" }, "403": { "description": "Insufficient permissions" } } } }, "/api/tags": { "get": { "tags": ["tags"], "summary": "List all tags for the authenticated user", "operationId": "list_tags", "responses": { "200": { "description": "User's tags", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TagListResponse" } } } }, "401": { "description": "Not authenticated" } } } }, "/api/topics": { "get": { "tags": ["topics"], "summary": "List all topics", "operationId": "list_topics", "responses": { "200": { "description": "All topics", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TopicListResponse" } } } } } } }, "/api/user/articles": { "get": { "tags": ["articles"], "summary": "List current user's articles", "operationId": "list_user_articles", "parameters": [ { "name": "status", "in": "query", "required": false, "schema": { "type": ["string", "null"] } } ], "responses": { "200": { "description": "User's articles", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleListResponse" } } } }, "401": { "description": "Not authenticated" } } } }, "/api/user/articles/{slug}": { "get": { "tags": ["articles"], "summary": "Get a specific article for editing (owner only)", "operationId": "get_user_article", "parameters": [ { "name": "slug", "in": "path", "description": "Article slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Article detail", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleDetailResponse" } } } }, "401": { "description": "Not authenticated" }, "404": { "description": "Article not found" } } }, "put": { "tags": ["articles"], "summary": "Update an article (owner only)", "operationId": "update_article", "parameters": [ { "name": "slug", "in": "path", "description": "Article slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateArticleRequest" } } }, "required": true }, "responses": { "200": { "description": "Article updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleDetailResponse" } } } }, "400": { "description": "Invalid input" }, "401": { "description": "Not authenticated" }, "404": { "description": "Article not found" } } } }, "/api/user/articles/{slug}/archive": { "post": { "tags": ["articles"], "summary": "Archive an article (one-way from published)", "operationId": "archive_article", "parameters": [ { "name": "slug", "in": "path", "description": "Article slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Article archived" }, "401": { "description": "Not authenticated" }, "404": { "description": "Article not found" } } } }, "/api/user/articles/{slug}/publish": { "post": { "tags": ["articles"], "summary": "Publish an article", "operationId": "publish_article", "parameters": [ { "name": "slug", "in": "path", "description": "Article slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Article published" }, "400": { "description": "Publish limit reached" }, "401": { "description": "Not authenticated" }, "404": { "description": "Article not found" } } } }, "/auth/forgot-password": { "post": { "tags": ["auth"], "summary": "Request a password reset email", "operationId": "forgot_password", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ForgotPasswordRequest" } } }, "required": true }, "responses": { "200": { "description": "If the email exists, a reset link was sent", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageResponse" } } } } } } }, "/auth/github": { "get": { "tags": ["auth"], "summary": "Redirect to GitHub OAuth", "operationId": "github_login", "responses": { "302": { "description": "Redirect to GitHub" } } } }, "/auth/github/callback": { "get": { "tags": ["auth"], "summary": "Handle GitHub OAuth callback", "operationId": "github_callback", "parameters": [ { "name": "code", "in": "query", "description": "Authorization code", "required": true, "schema": { "type": "string" } }, { "name": "state", "in": "query", "description": "CSRF state", "required": true, "schema": { "type": "string" } } ], "responses": { "302": { "description": "Redirect to frontend" } } } }, "/auth/login": { "post": { "tags": ["auth"], "summary": "Log in with email and password", "operationId": "login", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginRequest" } } }, "required": true }, "responses": { "200": { "description": "Logged in", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponse" } } } }, "401": { "description": "Invalid credentials" }, "403": { "description": "Email not verified" } } } }, "/auth/logout": { "post": { "tags": ["auth"], "summary": "Log out (destroy session)", "operationId": "logout", "responses": { "200": { "description": "Logged out", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageResponse" } } } } } } }, "/auth/me": { "get": { "tags": ["auth"], "summary": "Get current authenticated user", "operationId": "me", "responses": { "200": { "description": "Current user", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponse" } } } }, "401": { "description": "Not authenticated" } } } }, "/auth/profile": { "get": { "tags": ["auth"], "summary": "Get current user's profile with linked providers", "operationId": "get_profile", "responses": { "200": { "description": "User profile", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProfileResponse" } } } }, "401": { "description": "Not authenticated" } } }, "put": { "tags": ["auth"], "summary": "Update display name", "operationId": "update_profile", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateProfileRequest" } } }, "required": true }, "responses": { "200": { "description": "Profile updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageResponse" } } } }, "400": { "description": "Invalid input" }, "401": { "description": "Not authenticated" } } } }, "/auth/register": { "post": { "tags": ["auth"], "summary": "Register a new user with email and password", "operationId": "register", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterRequest" } } }, "required": true }, "responses": { "201": { "description": "User created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageResponse" } } } }, "400": { "description": "Invalid input" }, "409": { "description": "Email already exists" } } } }, "/auth/request-password-change": { "post": { "tags": ["auth"], "summary": "Request a password change email (for authenticated users)", "operationId": "request_password_change", "responses": { "200": { "description": "Password change email sent", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageResponse" } } } }, "401": { "description": "Not authenticated" } } } }, "/auth/reset-password": { "post": { "tags": ["auth"], "summary": "Reset password using a token", "operationId": "reset_password", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResetPasswordRequest" } } }, "required": true }, "responses": { "200": { "description": "Password reset", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageResponse" } } } }, "400": { "description": "Invalid or expired token" } } } }, "/auth/verify-email": { "get": { "tags": ["auth"], "summary": "Verify email using a token", "operationId": "verify_email", "parameters": [ { "name": "token", "in": "query", "description": "Verification token", "required": true, "schema": { "type": "string" } } ], "responses": { "302": { "description": "Redirects to frontend" } } } } }, "components": { "schemas": { "ArticleDetailResponse": { "type": "object", "required": [ "id", "title", "slug", "markdown", "html", "status", "author_display_name", "topics", "created_at", "updated_at" ], "properties": { "author_display_name": { "type": "string" }, "created_at": { "type": "string" }, "description": { "type": ["string", "null"] }, "html": { "type": "string" }, "id": { "type": "string" }, "markdown": { "type": "string" }, "published_at": { "type": ["string", "null"] }, "slug": { "type": "string" }, "status": { "type": "string" }, "title": { "type": "string" }, "topics": { "type": "array", "items": { "$ref": "#/components/schemas/TopicResponse" } }, "updated_at": { "type": "string" } } }, "ArticleLimitsResponse": { "type": "object", "required": [ "max_active", "current_active", "max_archive", "current_archive" ], "properties": { "current_active": { "type": "integer", "format": "int64" }, "current_archive": { "type": "integer", "format": "int64" }, "max_active": { "type": "integer", "format": "int32" }, "max_archive": { "type": "integer", "format": "int32" } } }, "ArticleListResponse": { "type": "object", "required": ["articles", "limits"], "properties": { "articles": { "type": "array", "items": { "$ref": "#/components/schemas/ArticleResponse" } }, "limits": { "$ref": "#/components/schemas/ArticleLimitsResponse" } } }, "ArticleQuotationListResponse": { "type": "object", "required": ["article_quotations"], "properties": { "article_quotations": { "type": "array", "items": { "$ref": "#/components/schemas/ArticleQuotationResponse" } } } }, "ArticleQuotationResponse": { "type": "object", "required": [ "id", "article_title", "author_display_name", "text", "html", "note_count", "created_at" ], "properties": { "article_id": { "type": ["string", "null"] }, "article_title": { "type": "string" }, "author_display_name": { "type": "string" }, "created_at": { "type": "string" }, "html": { "type": "string" }, "id": { "type": "string" }, "note_count": { "type": "integer", "format": "int64" }, "text": { "type": "string" } } }, "ArticleResponse": { "type": "object", "required": [ "id", "title", "slug", "status", "author_display_name", "topics", "created_at", "updated_at" ], "properties": { "author_display_name": { "type": "string" }, "created_at": { "type": "string" }, "description": { "type": ["string", "null"] }, "id": { "type": "string" }, "published_at": { "type": ["string", "null"] }, "slug": { "type": "string" }, "status": { "type": "string" }, "title": { "type": "string" }, "topics": { "type": "array", "items": { "$ref": "#/components/schemas/TopicResponse" } }, "updated_at": { "type": "string" } } }, "AuthResponse": { "type": "object", "required": [ "id", "email", "display_name", "roles", "permissions" ], "properties": { "avatar_url": { "type": ["string", "null"] }, "display_name": { "type": "string" }, "email": { "type": "string" }, "id": { "type": "string" }, "permissions": { "type": "array", "items": { "type": "string" } }, "roles": { "type": "array", "items": { "type": "string" } } } }, "BatchSentenceRequest": { "type": "object", "required": ["book_slug", "node_slug", "start_number", "kind"], "properties": { "book_slug": { "type": "string" }, "end_number": { "type": ["integer", "null"], "format": "int32" }, "kind": { "type": "string" }, "node_slug": { "type": "string" }, "start_number": { "type": "integer", "format": "int32" } } }, "BatchSentenceResponseItem": { "type": "object", "required": [ "book_slug", "book_title", "node_slug", "node_label", "sentences" ], "properties": { "book_slug": { "type": "string" }, "book_title": { "type": "string" }, "node_label": { "type": "string" }, "node_slug": { "type": "string" }, "sentences": { "type": "array", "items": { "$ref": "#/components/schemas/SentenceData" } }, "source": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SourceContext" } ] } } }, "BatchSentencesRequest": { "type": "object", "required": ["items"], "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/BatchSentenceRequest" } } } }, "BatchSentencesResponse": { "type": "object", "required": ["items"], "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/BatchSentenceResponseItem" } } } }, "BookDetail": { "type": "object", "required": [ "id", "slug", "title", "author", "language", "source_id", "translations" ], "properties": { "author": { "type": "string" }, "id": { "type": "string" }, "language": { "type": "string" }, "publication_year": { "type": ["integer", "null"], "format": "int32" }, "publisher": { "type": ["string", "null"] }, "slug": { "type": "string" }, "source_book_slug": { "type": ["string", "null"] }, "source_id": { "type": "string" }, "title": { "type": "string" }, "translations": { "type": "array", "items": { "$ref": "#/components/schemas/BookSummary" } } } }, "BookSummary": { "type": "object", "required": ["id", "slug", "title", "author", "language"], "properties": { "author": { "type": "string" }, "id": { "type": "string" }, "language": { "type": "string" }, "slug": { "type": "string" }, "title": { "type": "string" } } }, "ContentBlockResponse": { "type": "object", "required": [ "id", "position", "block_type", "html", "sentences" ], "properties": { "block_type": { "type": "string" }, "html": { "type": "string" }, "id": { "type": "string" }, "original_html": { "type": ["string", "null"] }, "paragraph_number": { "type": ["integer", "null"], "format": "int32" }, "position": { "type": "integer", "format": "int32" }, "sentences": { "type": "array", "items": { "$ref": "#/components/schemas/SentenceResponse" } } } }, "CreateArticleQuotationRequest": { "type": "object", "required": ["article_id", "text", "html"], "properties": { "article_id": { "type": "string" }, "html": { "type": "string" }, "text": { "type": "string" } } }, "CreateArticleQuotationResponse": { "type": "object", "required": ["article_quotation", "created"], "properties": { "article_quotation": { "$ref": "#/components/schemas/ArticleQuotationResponse" }, "created": { "type": "boolean" } } }, "CreateArticleRequest": { "type": "object", "required": ["title"], "properties": { "title": { "type": "string" } } }, "CreateNoteRequest": { "type": "object", "required": ["body"], "properties": { "body": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } } } }, "CreatePersonRequest": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string" }, "sort_name": { "type": ["string", "null"] } } }, "CreateQuotationRequest": { "type": "object", "required": ["sentence_start", "sentence_kind"], "properties": { "sentence_end": { "type": ["integer", "null"], "format": "int32" }, "sentence_kind": { "type": "string" }, "sentence_start": { "type": "integer", "format": "int32" } } }, "CreateQuotationResponse": { "type": "object", "required": ["quotation", "created"], "properties": { "created": { "type": "boolean" }, "quotation": { "$ref": "#/components/schemas/QuotationResponse" } } }, "CreateResourceRequest": { "type": "object", "required": [ "resource_type", "sentence_start", "sentence_kind" ], "properties": { "admin_notes": { "type": ["string", "null"] }, "editor_note": { "type": ["string", "null"] }, "is_featured": { "type": ["boolean", "null"] }, "quoted_text": { "type": ["string", "null"] }, "resource_type": { "type": "string" }, "sentence_end": { "type": ["integer", "null"], "format": "int32" }, "sentence_kind": { "type": "string" }, "sentence_start": { "type": "integer", "format": "int32" }, "source_id": { "type": ["string", "null"] }, "source_location_freeform": { "type": ["string", "null"] }, "source_page_end": { "type": ["integer", "null"], "format": "int32" }, "source_page_start": { "type": ["integer", "null"], "format": "int32" }, "verbatim_kind": { "type": ["string", "null"] } } }, "CreateSourceRequest": { "type": "object", "required": ["source_type", "title"], "properties": { "doi": { "type": ["string", "null"] }, "edition": { "type": ["string", "null"] }, "isbn": { "type": ["array", "null"], "items": { "type": "string" } }, "journal_name": { "type": ["string", "null"] }, "page_end": { "type": ["integer", "null"], "format": "int32" }, "page_start": { "type": ["integer", "null"], "format": "int32" }, "parent_source_id": { "type": ["string", "null"] }, "publication_year": { "type": ["integer", "null"], "format": "int32" }, "publisher": { "type": ["string", "null"] }, "source_type": { "type": "string" }, "title": { "type": "string" }, "title_display": { "type": ["string", "null"] }, "translation_of_id": { "type": ["string", "null"] }, "url": { "type": ["string", "null"] }, "volume": { "type": ["string", "null"] } } }, "FootnoteResponse": { "type": "object", "required": ["id", "number", "sentences"], "properties": { "id": { "type": "string" }, "number": { "type": "integer", "format": "int32" }, "sentences": { "type": "array", "items": { "$ref": "#/components/schemas/FootnoteSentenceResponse" } } } }, "FootnoteSentenceResponse": { "type": "object", "required": ["id", "position", "text", "html"], "properties": { "html": { "type": "string" }, "id": { "type": "string" }, "original_html": { "type": ["string", "null"] }, "original_text": { "type": ["string", "null"] }, "position": { "type": "integer", "format": "int32" }, "sentence_number": { "type": ["integer", "null"], "format": "int32" }, "text": { "type": "string" } } }, "ForgotPasswordRequest": { "type": "object", "required": ["email"], "properties": { "email": { "type": "string" } } }, "LibraryAuthor": { "type": "object", "required": ["id", "name", "sort_name", "books"], "properties": { "books": { "type": "array", "items": { "$ref": "#/components/schemas/LibraryWork" } }, "id": { "type": "string" }, "name": { "type": "string" }, "sort_name": { "type": "string" } } }, "LibraryResponse": { "type": "object", "required": ["authors", "stats"], "properties": { "authors": { "type": "array", "items": { "$ref": "#/components/schemas/LibraryAuthor" } }, "stats": { "$ref": "#/components/schemas/LibraryStats" } } }, "LibraryStats": { "type": "object", "required": ["works", "authors", "languages"], "properties": { "authors": { "type": "integer", "format": "int64" }, "languages": { "type": "integer", "format": "int64" }, "works": { "type": "integer", "format": "int64" } } }, "LibraryVersion": { "type": "object", "required": [ "book_slug", "language", "is_original", "translator_names" ], "properties": { "book_slug": { "type": "string" }, "is_original": { "type": "boolean" }, "language": { "type": "string" }, "publication_year": { "type": ["integer", "null"], "format": "int32" }, "publisher": { "type": ["string", "null"] }, "translator_names": { "type": "array", "items": { "type": "string" } } } }, "LibraryWork": { "type": "object", "required": ["work_id", "title", "co_authors", "versions"], "properties": { "co_authors": { "type": "array", "items": { "type": "string" } }, "editor_names": { "type": ["array", "null"], "items": { "type": "string" } }, "publication_year": { "type": ["integer", "null"], "format": "int32" }, "title": { "type": "string" }, "versions": { "type": "array", "items": { "$ref": "#/components/schemas/LibraryVersion" } }, "work_id": { "type": "string" } } }, "LinkSourcePersonRequest": { "type": "object", "required": ["person_id", "role"], "properties": { "person_id": { "type": "string" }, "position": { "type": ["integer", "null"], "format": "int32" }, "role": { "type": "string" } } }, "LinkedProvider": { "type": "object", "required": ["provider"], "properties": { "email": { "type": ["string", "null"] }, "provider": { "type": "string" } } }, "LoginRequest": { "type": "object", "required": ["email", "password"], "properties": { "email": { "type": "string" }, "password": { "type": "string" } } }, "MessageResponse": { "type": "object", "required": ["message"], "properties": { "message": { "type": "string" } } }, "NodeDetail": { "type": "object", "required": [ "id", "source_ref", "slug", "label", "depth", "sort_order", "blocks" ], "properties": { "blocks": { "type": "array", "items": { "$ref": "#/components/schemas/ContentBlockResponse" } }, "depth": { "type": "integer", "format": "int32" }, "id": { "type": "string" }, "label": { "type": "string" }, "slug": { "type": "string" }, "sort_order": { "type": "integer", "format": "int32" }, "source_node_id": { "type": ["string", "null"] }, "source_ref": { "type": "string" } } }, "NodePage": { "type": "object", "required": ["nodes", "has_more", "has_previous"], "properties": { "has_more": { "type": "boolean" }, "has_previous": { "type": "boolean" }, "nodes": { "type": "array", "items": { "$ref": "#/components/schemas/NodeDetail" } } } }, "NoteLimitsResponse": { "type": "object", "required": ["max", "current"], "properties": { "current": { "type": "integer", "format": "int64" }, "max": { "type": "integer", "format": "int32" } } }, "NoteListResponse": { "type": "object", "required": ["notes"], "properties": { "notes": { "type": "array", "items": { "$ref": "#/components/schemas/NoteResponse" } } } }, "NoteResponse": { "type": "object", "required": ["id", "body", "tags", "created_at", "updated_at"], "properties": { "body": { "type": "string" }, "created_at": { "type": "string" }, "id": { "type": "string" }, "tags": { "type": "array", "items": { "$ref": "#/components/schemas/TagResponse" } }, "updated_at": { "type": "string" } } }, "NoteWithContextListResponse": { "type": "object", "required": ["notes", "limits"], "properties": { "limits": { "$ref": "#/components/schemas/NoteLimitsResponse" }, "notes": { "type": "array", "items": { "$ref": "#/components/schemas/NoteWithContextResponse" } } } }, "NoteWithContextResponse": { "type": "object", "required": [ "id", "body", "tags", "book_slug", "book_title", "node_label", "node_slug", "anchor_sentence_start_number", "sentence_kind", "quotation_id", "created_at", "updated_at" ], "properties": { "anchor_main_sentence_number": { "type": ["integer", "null"], "format": "int32", "description": "For footnote-kind anchors: the body sentence number the footnote is\nattached to. None for body-kind anchors." }, "anchor_sentence_end_number": { "type": ["integer", "null"], "format": "int32" }, "anchor_sentence_start_number": { "type": "integer", "format": "int32" }, "body": { "type": "string" }, "book_slug": { "type": "string" }, "book_title": { "type": "string" }, "created_at": { "type": "string" }, "id": { "type": "string" }, "node_label": { "type": "string" }, "node_slug": { "type": "string" }, "quotation_id": { "type": "string" }, "sentence_kind": { "type": "string" }, "tags": { "type": "array", "items": { "$ref": "#/components/schemas/TagResponse" } }, "updated_at": { "type": "string" } } }, "PageMarkerResponse": { "type": "object", "required": ["system_slug", "ref_value", "sort_order"], "properties": { "char_offset": { "type": ["integer", "null"], "format": "int32" }, "ref_value": { "type": "string" }, "sort_order": { "type": "integer", "format": "int32" }, "system_slug": { "type": "string" } } }, "ParentSourceResponse": { "type": "object", "required": ["id", "source_type", "title", "persons"], "properties": { "id": { "type": "string" }, "persons": { "type": "array", "items": { "$ref": "#/components/schemas/SourcePersonResponse" } }, "publication_year": { "type": ["integer", "null"], "format": "int32" }, "publisher": { "type": ["string", "null"] }, "source_type": { "type": "string" }, "title": { "type": "string" } } }, "PersonResponse": { "type": "object", "required": ["id", "name", "created_by", "protected"], "properties": { "created_by": { "type": "string" }, "id": { "type": "string" }, "name": { "type": "string" }, "protected": { "type": "boolean" }, "sort_name": { "type": ["string", "null"] } } }, "ProfileResponse": { "type": "object", "required": [ "id", "email", "display_name", "has_password", "roles", "providers" ], "properties": { "avatar_url": { "type": ["string", "null"] }, "display_name": { "type": "string" }, "email": { "type": "string" }, "has_password": { "type": "boolean" }, "id": { "type": "string" }, "providers": { "type": "array", "items": { "$ref": "#/components/schemas/LinkedProvider" } }, "roles": { "type": "array", "items": { "type": "string" } } } }, "PublishedArticleListResponse": { "type": "object", "required": ["articles", "total"], "properties": { "articles": { "type": "array", "items": { "$ref": "#/components/schemas/ArticleResponse" } }, "total": { "type": "integer", "format": "int64" } } }, "QuotationLimitsResponse": { "type": "object", "required": ["max", "current"], "properties": { "current": { "type": "integer", "format": "int64" }, "max": { "type": "integer", "format": "int32" } } }, "QuotationListResponse": { "type": "object", "required": ["quotations"], "properties": { "quotations": { "type": "array", "items": { "$ref": "#/components/schemas/QuotationResponse" } } } }, "QuotationResponse": { "type": "object", "required": [ "id", "anchor_sentence_start_number", "sentence_kind", "note_count", "created_at" ], "properties": { "anchor_sentence_end_number": { "type": ["integer", "null"], "format": "int32" }, "anchor_sentence_start_number": { "type": "integer", "format": "int32" }, "created_at": { "type": "string" }, "id": { "type": "string" }, "note_count": { "type": "integer", "format": "int64" }, "sentence_kind": { "type": "string" } } }, "QuotationWithContextListResponse": { "type": "object", "required": ["quotations"], "properties": { "quotations": { "type": "array", "items": { "$ref": "#/components/schemas/QuotationWithContextResponse" } } } }, "QuotationWithContextResponse": { "type": "object", "required": [ "id", "book_slug", "book_title", "node_label", "node_slug", "anchor_sentence_start_number", "sentence_kind", "note_count", "created_at" ], "properties": { "anchor_main_sentence_number": { "type": ["integer", "null"], "format": "int32", "description": "For footnote-kind anchors: the body sentence number the footnote is\nattached to. None for body-kind anchors." }, "anchor_sentence_end_number": { "type": ["integer", "null"], "format": "int32" }, "anchor_sentence_start_number": { "type": "integer", "format": "int32" }, "book_slug": { "type": "string" }, "book_title": { "type": "string" }, "created_at": { "type": "string" }, "end_text_snippet": { "type": ["string", "null"] }, "id": { "type": "string" }, "node_label": { "type": "string" }, "node_slug": { "type": "string" }, "note_count": { "type": "integer", "format": "int64" }, "sentence_kind": { "type": "string" }, "start_text_snippet": { "type": ["string", "null"] } } }, "ReferenceCheckResponse": { "type": "object", "required": ["total", "resources", "child_sources", "articles"], "properties": { "articles": { "$ref": "#/components/schemas/ReferencedArticles" }, "child_sources": { "$ref": "#/components/schemas/ReferencedChildSources" }, "resources": { "$ref": "#/components/schemas/ReferencedResources" }, "total": { "type": "integer", "format": "int64", "description": "Total count across all categories." } } }, "ReferencedArticle": { "type": "object", "required": ["id", "title", "slug", "status", "is_mine"], "properties": { "id": { "type": "string" }, "is_mine": { "type": "boolean" }, "slug": { "type": "string" }, "status": { "type": "string" }, "title": { "type": "string" } } }, "ReferencedArticles": { "type": "object", "required": ["count", "items"], "properties": { "count": { "type": "integer", "format": "int64" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/ReferencedArticle" } } } }, "ReferencedChildSource": { "type": "object", "required": ["id", "title", "relation"], "properties": { "id": { "type": "string" }, "relation": { "type": "string" }, "title": { "type": "string" } } }, "ReferencedChildSources": { "type": "object", "required": ["count", "items"], "properties": { "count": { "type": "integer", "format": "int64" }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/ReferencedChildSource" } } } }, "ReferencedResources": { "type": "object", "required": ["count", "ids"], "properties": { "count": { "type": "integer", "format": "int64" }, "ids": { "type": "array", "items": { "type": "string" } } } }, "RegisterRequest": { "type": "object", "required": ["email", "display_name", "password"], "properties": { "display_name": { "type": "string" }, "email": { "type": "string" }, "password": { "type": "string" } } }, "ResetPasswordRequest": { "type": "object", "required": ["token", "password"], "properties": { "password": { "type": "string" }, "token": { "type": "string" } } }, "ResourceListResponse": { "type": "object", "required": ["resources"], "properties": { "resources": { "type": "array", "items": { "$ref": "#/components/schemas/ResourceResponse" } } } }, "ResourceResponse": { "type": "object", "required": [ "id", "resource_type", "anchor_sentence_start_number", "sentence_kind", "is_featured", "created_at" ], "properties": { "admin_notes": { "type": ["string", "null"] }, "anchor_sentence_end_number": { "type": ["integer", "null"], "format": "int32" }, "anchor_sentence_start_number": { "type": "integer", "format": "int32" }, "created_at": { "type": "string" }, "editor_note": { "type": ["string", "null"] }, "id": { "type": "string" }, "is_featured": { "type": "boolean" }, "quoted_text": { "type": ["string", "null"] }, "resource_type": { "type": "string" }, "sentence_kind": { "type": "string" }, "source": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SourceResponse" } ] }, "source_location_freeform": { "type": ["string", "null"] }, "source_page_end": { "type": ["integer", "null"], "format": "int32" }, "source_page_start": { "type": ["integer", "null"], "format": "int32" }, "verbatim_kind": { "type": ["string", "null"] } } }, "SentenceData": { "type": "object", "required": ["sentence_number", "html"], "properties": { "html": { "type": "string" }, "original_html": { "type": ["string", "null"] }, "sentence_number": { "type": "integer", "format": "int32" } } }, "SentenceResponse": { "type": "object", "required": ["id", "position", "text", "html", "page_markers"], "properties": { "footnotes": { "type": "array", "items": { "$ref": "#/components/schemas/FootnoteResponse" } }, "html": { "type": "string" }, "id": { "type": "string" }, "original_html": { "type": ["string", "null"] }, "original_text": { "type": ["string", "null"] }, "page_markers": { "type": "array", "items": { "$ref": "#/components/schemas/PageMarkerResponse" } }, "position": { "type": "integer", "format": "int32" }, "sentence_number": { "type": ["integer", "null"], "format": "int32" }, "source_sentence_end_id": { "type": ["string", "null"] }, "source_sentence_start_id": { "type": ["string", "null"] }, "text": { "type": "string" } } }, "SourceBrowseResponse": { "type": "object", "required": ["sources", "total"], "properties": { "sources": { "type": "array", "items": { "$ref": "#/components/schemas/SourceSearchResponse" } }, "total": { "type": "integer", "format": "int64" } } }, "SourceContext": { "type": "object", "required": [ "book_slug", "book_title", "node_slug", "node_label" ], "properties": { "book_slug": { "type": "string" }, "book_title": { "type": "string" }, "node_label": { "type": "string" }, "node_slug": { "type": "string" } } }, "SourcePersonResponse": { "type": "object", "required": [ "person_id", "name", "role", "position", "created_by", "protected" ], "properties": { "created_by": { "type": "string" }, "name": { "type": "string" }, "person_id": { "type": "string" }, "position": { "type": "integer", "format": "int32" }, "protected": { "type": "boolean" }, "role": { "type": "string" }, "sort_name": { "type": ["string", "null"] } } }, "SourceResponse": { "type": "object", "required": [ "id", "source_type", "title", "created_by", "protected", "persons" ], "properties": { "created_by": { "type": "string" }, "doi": { "type": ["string", "null"] }, "edition": { "type": ["string", "null"] }, "id": { "type": "string" }, "isbn": { "type": ["array", "null"], "items": { "type": "string" } }, "journal_name": { "type": ["string", "null"] }, "page_end": { "type": ["integer", "null"], "format": "int32" }, "page_start": { "type": ["integer", "null"], "format": "int32" }, "parent": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ParentSourceResponse" } ] }, "persons": { "type": "array", "items": { "$ref": "#/components/schemas/SourcePersonResponse" } }, "protected": { "type": "boolean" }, "publication_year": { "type": ["integer", "null"], "format": "int32" }, "publisher": { "type": ["string", "null"] }, "source_type": { "type": "string" }, "title": { "type": "string" }, "title_display": { "type": ["string", "null"] }, "translation_of_id": { "type": ["string", "null"] }, "url": { "type": ["string", "null"] }, "volume": { "type": ["string", "null"] } } }, "SourceSearchResponse": { "type": "object", "required": [ "id", "source_type", "title", "created_by", "protected", "persons" ], "properties": { "created_by": { "type": "string" }, "id": { "type": "string" }, "persons": { "type": "array", "items": { "$ref": "#/components/schemas/SourcePersonResponse" } }, "protected": { "type": "boolean" }, "publication_year": { "type": ["integer", "null"], "format": "int32" }, "source_type": { "type": "string" }, "title": { "type": "string" } } }, "TagListResponse": { "type": "object", "required": ["tags"], "properties": { "tags": { "type": "array", "items": { "$ref": "#/components/schemas/TagResponse" } } } }, "TagResponse": { "type": "object", "required": ["id", "name"], "properties": { "id": { "type": "string" }, "name": { "type": "string" } } }, "TocNodeResponse": { "type": "object", "required": [ "id", "source_ref", "slug", "label", "depth", "sort_order", "has_content", "children" ], "properties": { "children": { "type": "array", "items": { "$ref": "#/components/schemas/TocNodeResponse" } }, "depth": { "type": "integer" }, "has_content": { "type": "boolean" }, "id": { "type": "string" }, "label": { "type": "string" }, "label_html": { "type": "string" }, "slug": { "type": "string" }, "sort_order": { "type": "integer" }, "source_node_id": { "type": "string" }, "source_ref": { "type": "string" } } }, "TopicListResponse": { "type": "object", "required": ["topics"], "properties": { "topics": { "type": "array", "items": { "$ref": "#/components/schemas/TopicResponse" } } } }, "TopicResponse": { "type": "object", "required": ["id", "name", "slug"], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "slug": { "type": "string" } } }, "UnifiedQuotationListResponse": { "type": "object", "required": ["quotations", "limits"], "properties": { "limits": { "$ref": "#/components/schemas/QuotationLimitsResponse" }, "quotations": { "type": "array", "items": { "$ref": "#/components/schemas/UnifiedQuotationResponse" } } } }, "UnifiedQuotationResponse": { "oneOf": [ { "type": "object", "required": [ "id", "book_slug", "book_title", "node_label", "node_slug", "anchor_sentence_start_number", "sentence_kind", "note_count", "created_at", "source_type" ], "properties": { "anchor_main_sentence_number": { "type": ["integer", "null"], "format": "int32", "description": "For footnote-kind anchors: the body sentence number the footnote\nis attached to. None for body-kind anchors." }, "anchor_sentence_end_number": { "type": ["integer", "null"], "format": "int32" }, "anchor_sentence_start_number": { "type": "integer", "format": "int32" }, "book_slug": { "type": "string" }, "book_title": { "type": "string" }, "created_at": { "type": "string" }, "end_text_snippet": { "type": ["string", "null"] }, "id": { "type": "string" }, "node_label": { "type": "string" }, "node_slug": { "type": "string" }, "note_count": { "type": "integer", "format": "int64" }, "sentence_kind": { "type": "string" }, "source_type": { "type": "string", "enum": ["book"] }, "start_text_snippet": { "type": ["string", "null"] } } }, { "type": "object", "required": [ "id", "article_title", "author_display_name", "text_snippet", "note_count", "created_at", "source_type" ], "properties": { "article_id": { "type": ["string", "null"] }, "article_title": { "type": "string" }, "author_display_name": { "type": "string" }, "created_at": { "type": "string" }, "id": { "type": "string" }, "note_count": { "type": "integer", "format": "int64" }, "source_type": { "type": "string", "enum": ["article"] }, "text_snippet": { "type": "string" } } } ] }, "UpdateArticleRequest": { "type": "object", "properties": { "description": { "type": ["string", "null"] }, "markdown": { "type": ["string", "null"] }, "title": { "type": ["string", "null"] }, "topic_ids": { "type": ["array", "null"], "items": { "type": "string" } } } }, "UpdateNoteRequest": { "type": "object", "properties": { "body": { "type": ["string", "null"] }, "tags": { "type": ["array", "null"], "items": { "type": "string" } } } }, "UpdatePersonRequest": { "type": "object", "properties": { "name": { "type": ["string", "null"] }, "sort_name": { "type": ["string", "null"] } } }, "UpdateProfileRequest": { "type": "object", "required": ["display_name"], "properties": { "display_name": { "type": "string" } } }, "UpdateResourceRequest": { "type": "object", "properties": { "admin_notes": { "type": ["string", "null"] }, "editor_note": { "type": ["string", "null"] }, "is_featured": { "type": ["boolean", "null"] }, "quoted_text": { "type": ["string", "null"] }, "resource_type": { "type": ["string", "null"] }, "sentence_end": { "type": ["integer", "null"], "format": "int32" }, "sentence_kind": { "type": ["string", "null"] }, "sentence_start": { "type": ["integer", "null"], "format": "int32" }, "source_id": { "type": ["string", "null"] }, "source_location_freeform": { "type": ["string", "null"] }, "source_page_end": { "type": ["integer", "null"], "format": "int32" }, "source_page_start": { "type": ["integer", "null"], "format": "int32" }, "verbatim_kind": { "type": ["string", "null"] } } }, "UpdateSourceRequest": { "type": "object", "properties": { "doi": { "type": ["string", "null"] }, "edition": { "type": ["string", "null"] }, "isbn": { "type": ["array", "null"], "items": { "type": "string" } }, "journal_name": { "type": ["string", "null"] }, "page_end": { "type": ["integer", "null"], "format": "int32" }, "page_start": { "type": ["integer", "null"], "format": "int32" }, "parent_source_id": { "type": ["string", "null"] }, "protected": { "type": ["boolean", "null"] }, "publication_year": { "type": ["integer", "null"], "format": "int32" }, "publisher": { "type": ["string", "null"] }, "source_type": { "type": ["string", "null"] }, "title": { "type": ["string", "null"] }, "title_display": { "type": ["string", "null"] }, "translation_of_id": { "type": ["string", "null"] }, "url": { "type": ["string", "null"] }, "volume": { "type": ["string", "null"] } } } } } }