# CrowdBooks API – reference for AI assistants

CrowdBooks (https://crowdbooks.crowdware.info) publishes books for free. The chapters are Markdown files in a
public Git repository of the author; CrowdBooks reads them from there and shows them as a
book with a reading sample, buy links and PDF/EPUB export. All rights stay with the author.

This page tells an AI assistant (for example Claude Code) everything it needs to publish
or update a book for its user with one API call. Answer the user in their language.

## 1. What the author does once (by hand)

1. Register at https://crowdbooks.crowdware.info/register (login by email link, no password).
2. Open https://crowdbooks.crowdware.info/dashboard/api and click "Create token". The token (`cb_` + 64 hex
   characters) is shown only once.
3. Make it available to you as an environment variable, e.g. `CROWDBOOKS_TOKEN`.

Never write the token into the repository, a commit, a file or your answer. Creating a new
token makes the old one invalid; the author can also delete it on the same page.

## 2. The repository

- One **public** repository per book on Codeberg or GitHub (CrowdBooks cannot read private
  repositories).
- One folder per language, one file per chapter, lowercase with hyphens, numbered in reading
  order:

```
my-book/
  Book.sml          (or one Book.sml per language, e.g. de/Book.sml)
  cover.jpg
  de/00-vorwort.md
  de/01-der-anfang.md
  de/images/map.png
```

## 3. Chapter files (Markdown)

- CommonMark plus tables. Raw HTML is not rendered. Footnotes (`[^1]`) are not supported:
  write sources as a numbered "Notes" list at the end of the chapter.
- **Do not start a chapter with a `#` heading that repeats the title.** CrowdBooks shows
  the chapter title (from `Book.sml`) itself; use `##` for sections inside the chapter.
- Images: put them into the repository and link them relative to the chapter file,
  e.g. `![Map](images/map.png)`; absolute `https://` URLs work too.
- Do not link to other chapters by relative `.md` paths – they do not resolve on CrowdBooks.

## 4. Raw URLs

CrowdBooks needs the raw file URL of every chapter:

- Codeberg: `https://codeberg.org/<owner>/<repo>/raw/branch/<branch>/<path>`
- GitHub:   `https://raw.githubusercontent.com/<owner>/<repo>/<branch>/<path>`

**Commit and push before calling the API**, then check that every URL answers 200, e.g.
`curl -sfI <url> >/dev/null && echo ok`. The API loads every chapter once; a URL that fails
is still saved, but you get a `Warning` and readers see an error until the file is reachable.

## 5. Book.sml

SML: elements `Name { … }`, properties `key: value`, strings in double quotes (escape `\"`
and `\\`), numbers bare, comments `//` and `/* */`.

```
Book {
    slug: "my-book-1a2b3c"   // omit on the first upload; then copy it from the response
    title: "My Book"
    description: "What it is about – shown on the book page."
    author: "Jane Doe"       // pen name allowed
    type: "closed"           // "closed" = only the author writes (default); "open" = others may add chapters
    tag: "non-fiction"
    cover: "https://codeberg.org/jane/my-book/raw/branch/main/cover.jpg"
    sample: 4                // reading sample: only the first 4 chapters are public; 0 = all

    Buy { name: "epubli" url: "https://www.epubli.com/shop/…" }

    Chapter {
        title: "Preface"
        url: "https://codeberg.org/jane/my-book/raw/branch/main/en/00-preface.md"
    }
    Chapter {
        title: "Chapter 1: The Beginning"
        url: "https://codeberg.org/jane/my-book/raw/branch/main/en/01-the-beginning.md"
    }
}
```

| Field | Rules |
|---|---|
| `title` | required |
| `slug` | missing → a **new** book is created; present → that book is updated (must belong to the token owner) |
| `description`, `author`, `tag` | optional; missing in an update → old value stays |
| `type` | `"closed"` or `"open"`; only used when the book is created |
| `cover` | http(s) URL of a PNG, JPEG or WebP, max. 5 MB, portrait (e.g. 1280×1920); downloaded and stored |
| `sample` | number ≥ 0; missing → old value stays |
| `Buy` | `name` + http(s) `url`; if any `Buy` is given, the list replaces the old one |
| `Chapter` | `title` and `url` (http, https or ipfs) required; optional `author` (default: book author) |

- **The order of the `Chapter` elements is the reading order.**
- A chapter is identified by its URL: same URL = same chapter (title and text are updated).
  If you rename or move a file, the chapter counts as new and the old one stays (see 8.).
- Each URL may appear only once. Max. 500 chapters, max. 1 MB for `Book.sml`.

## 6. The call

```
curl -sS -X POST https://crowdbooks.crowdware.info/api/v1/books \
     -H "Authorization: Bearer $CROWDBOOKS_TOKEN" \
     --data-binary @Book.sml
```

The response is SML (`Content-Type: text/sml`):

```
Result {
    ok: true
    slug: "my-book-1a2b3c"
    url: "https://crowdbooks.crowdware.info/books/my-book-1a2b3c"
    created: true
    Chapter {
        title: "Preface"
        url: "https://crowdbooks.crowdware.info/books/my-book-1a2b3c/preface-4d5e6f"
        status: "created"        // or "updated", "rejected"
    }
    Warning {
        message: "chapter \"Old title\" is not in Book.sml; it stays online after the listed chapters"
    }
}
```

HTTP status: 201 book created, 200 updated. Errors come as
`Error { ok: false message: "…" }`:

| Status | Meaning |
|---|---|
| 400 | `Book.sml` invalid – the message says which field or chapter |
| 401 | token missing or wrong |
| 403 | a chapter URL belongs to another author's chapter |
| 404 | no book with this `slug` that the token owner may edit |
| 413 | `Book.sml` larger than 1 MB |

Warnings do not stop the upload (for example a cover that could not be loaded). Show them
to the user.

## 7. After the first upload

1. Put the `slug` from the response into `Book.sml` and commit it – otherwise the next call
   creates a second book.
2. Give the user the book URL from the response.

## 8. Updating

- **Only the text of chapters changed?** Just push; CrowdBooks picks it up within a few
  minutes. Calling the API refreshes the changed chapters immediately.
- **New chapters, new titles, new order, new cover, sample or buy links?** Update
  `Book.sml`, push, call the API again.
- **Removing a chapter:** the API never deletes. A chapter missing from `Book.sml` stays
  online, moves behind the listed chapters and is reported as a warning; the author deletes
  it in the dashboard
  (https://crowdbooks.crowdware.info/dashboard).

## 9. What the API does not do

- Delete chapters or books, change `type` afterwards.
- Create the PDF/EPUB: the author downloads them in the dashboard ("Export") and can
  sell them via epubli, Amazon KDP or tolino. Human-readable guide:
  https://crowdbooks.crowdware.info/guide/publish
