MuseCanto Docs
API

Import a document

POST a new document into an owned knowledge base from Markdown, HTML, or ProseMirror JSON.

Create a new document in a knowledge base you own. The server parses the body from Markdown, HTML, or ProseMirror JSON, creates the document, and initializes collaboration state (collabVersion starts at 0).

For authentication and the Open API prefix, see the developer documentation home. To list existing documents, use Export knowledge base documents.

Endpoint

POST /api/v1/open/books/{bookSlug}/docs/import
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
ItemValue
MethodPOST
AuthAuthorization: Bearer + full API key
Path parameterbookSlug — target knowledge base slug
Content-Typeapplication/json
OwnershipKey must belong to the knowledge base owner

Request body

FieldTypeRequiredDescription
titlestringYesDocument title, 1–150 characters after trimming
format"markdown" | "html" | "json"YesBody format
contentstring | objectYesBody. Must be a non-empty string for markdown / html; for json it can be a string or a ProseMirror doc object (type: "doc")
descriptionstringNoSummary, max 150 characters
parentIdstringNoParent node ID; placed at the library root when omitted. Must be a valid node in the same knowledge base

Format notes

formatcontent expectation
markdownNon-empty Markdown string
htmlNon-empty HTML string
jsonProseMirror document JSON ({ "type": "doc", "content": [...] }) or a JSON string of the same

Example request

Replace YOUR_API_KEY and BOOK_SLUG with your values. Use your deployment origin instead of https://your-domain.com when not running locally.

curl -sS -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "title": "Imported Doc",
        "format": "markdown",
        "content": "# Title\n\nBody paragraph."
      }' \
  "https://your-domain.com/api/v1/open/books/BOOK_SLUG/docs/import"
$headers = @{ Authorization = "Bearer YOUR_API_KEY" }
$body = @{
  title   = "Imported Doc"
  format  = "markdown"
  content = "# Title`n`nBody paragraph."
} | ConvertTo-Json
Invoke-RestMethod -Method Post `
  -Uri "https://your-domain.com/api/v1/open/books/BOOK_SLUG/docs/import" `
  -Headers $headers -ContentType "application/json" -Body $body

Success response

Status: 201 Created

{
  "success": true,
  "doc": {
    "id": "…",
    "slug": "doc-slug",
    "name": "Imported Doc",
    "type": "document",
    "collabVersion": 0
  },
  "links": {
    "editor": "/app/books/BOOK_SLUG/doc-slug"
  }
}

Response fields

FieldTypeDescription
doc.idstringNew document ID
doc.slugstringNew document slug
doc.namestringTitle
doc.typestringAlways document
doc.collabVersionnumberCollaboration version; 0 for a new document
links.editorstringRelative path to the in-browser editor

Error responses

All errors use a flat envelope:

{ "success": false, "code": "<MACHINE_CODE>", "message": "<human readable>" }
HTTPcodeWhen
400INVALID_CONTENTEmpty body, or body cannot be parsed into a valid document for the given format
400INVALID_PARENTparentId is unknown or not part of this knowledge base
401INVALID_API_KEYMissing header, invalid, expired, or revoked key
404BOOK_NOT_FOUNDUnknown slug, or library not owned by the key user
500IMPORT_FAILEDUnexpected server error (cause is logged server-side, not echoed)

404 vs 403

Non-owned slugs return 404 instead of 403 to avoid leaking whether a slug exists.

Limitations (current version)

  • Create-only: does not update or delete existing documents.
  • No per-key knowledge base allowlist (any owned slug works).
  • Does not import into public or password-protected libraries you do not own.

See also