# Markdown Share API

Turn a markdown document into a public web page that anyone can open, read,
comment on, and save as PDF — without a login. Built for agents that produce a
report and need to hand a human a link to it.

- Base URL: `https://tools.madebytle.com`
- Auth: `Authorization: Bearer <MD_SHARE_API_KEY>` on every endpoint below
- Link lifetime: 30 days from creation, renewed on every overwrite
- Reader-facing page: `https://tools.madebytle.com/md-to-pdf/share/<id>` (public, no key)

## The loop this API is for

1. **POST** the report → you get back a url. Hand that url to the human.
2. They open it, select any sentence, and leave a comment on it.
3. **GET** the document back → you read their comments.
4. Rewrite, then **PUT** over the same id → the url they already have now shows
   the corrected version. It never changes, so nothing needs re-sending.
5. **DELETE** the comments you have answered → the next round starts clean.

## POST /api/md-to-pdf/share/external

Create a link.

Two body shapes. JSON:

```bash
curl -X POST https://tools.madebytle.com/api/md-to-pdf/share/external \
  -H "Authorization: Bearer $MD_SHARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"markdown":"# Q3 Report\n\nRevenue is up.","title":"Q3 Report"}'
```

Or the raw file, under any other content type — no escaping the document into
JSON:

```bash
curl -X POST "https://tools.madebytle.com/api/md-to-pdf/share/external?title=%E0%B8%A3%E0%B8%B2%E0%B8%A2%E0%B8%87%E0%B8%B2%E0%B8%99" \
  -H "Authorization: Bearer $MD_SHARE_API_KEY" \
  -H "Content-Type: text/markdown; charset=utf-8" \
  --data-binary @report.md
```

`title` is optional; it falls back to the document's first heading. For raw
uploads pass it as `?title=` percent-encoded — the `X-Title` header also works
but is ASCII-only, so Thai titles mangle there.

```json
{
  "id": "c5fa8c57-f3e3-4b11-ad64-95a1e22431c0",
  "url": "https://tools.madebytle.com/md-to-pdf/share/c5fa8c57-f3e3-4b11-ad64-95a1e22431c0",
  "title": "Q3 Report",
  "expiresAt": "2026-09-05T09:14:00.000Z"
}
```

## GET /api/md-to-pdf/share/external

List the links this API created, newest first. Use it when you have lost the url
you printed earlier — re-uploading mints a second link to the same report.

```bash
curl "https://tools.madebytle.com/api/md-to-pdf/share/external?limit=20" \
  -H "Authorization: Bearer $MD_SHARE_API_KEY"
```

- `limit` — 1–200, default 50
- `includeExpired` — `true` to include links past their date (hidden by default)

Each entry carries `id`, `url`, `title`, `createdAt`, `updatedAt`,
`expiresAt`, `expired`, and `commentCount` — poll `commentCount` to notice
that someone has reviewed the document.

Documents created from the signed-in web tool are **not** listed; only what this
API wrote.

## GET /api/md-to-pdf/share/external/{id}

Read a document back together with its comments.

```bash
curl https://tools.madebytle.com/api/md-to-pdf/share/external/<id> \
  -H "Authorization: Bearer $MD_SHARE_API_KEY"
```

```json
{
  "id": "c5fa8c57-...",
  "url": "https://tools.madebytle.com/md-to-pdf/share/c5fa8c57-...",
  "title": "Q3 Report",
  "markdown": "# Q3 Report\n\nRevenue is up.",
  "createdAt": "2026-08-06T09:14:00.000Z",
  "updatedAt": null,
  "expiresAt": "2026-09-05T09:14:00.000Z",
  "expired": false,
  "commentCount": 1,
  "comments": [
    {
      "id": "2c2084e9-...",
      "selectedText": "Revenue is up.",
      "comment": "ใส่ตัวเลขด้วย",
      "authorName": "Tle",
      "createdAt": "2026-08-06T10:02:00.000Z",
      "quoteInDocument": true
    }
  ]
}
```

A comment anchors to the **text it quotes**, not to a line number. So
`selectedText` tells you exactly which sentence to rewrite, and
`quoteInDocument: false` means that sentence is no longer in the document —
the feedback was already applied in an earlier round, or the paragraph was cut.
Treat that flag as a hint: it compares against the markdown source, so a quote
spanning inline syntax like `**bold**` can read as missing while still being
visible on the page.

## PUT /api/md-to-pdf/share/external/{id}

Overwrite a document in place. **The url does not change** — this is how you
correct a report that has already been sent.

```bash
curl -X PUT https://tools.madebytle.com/api/md-to-pdf/share/external/<id> \
  -H "Authorization: Bearer $MD_SHARE_API_KEY" \
  -H "Content-Type: text/markdown; charset=utf-8" \
  --data-binary @report-v2.md
```

Same two body shapes as POST. Two things happen on top of the rewrite:

- `expiresAt` is pushed out a fresh 30 days. A document still
  being corrected should not die on the original clock.
- **Comments are kept.** The page marks any whose quoted sentence you rewrote
  with "ข้อความที่คอมเมนต์นี้อ้างถึงถูกแก้ไปแล้ว" instead of dropping them, so the
  person who wrote the note can still see what became of it. Clear them yourself
  when you are done with them (below).

The page also grows a "แก้ล่าสุด <date>" badge after the first overwrite, so
someone holding an old tab can tell the document moved on.

## DELETE /api/md-to-pdf/share/external/{id}/comments

Clear every comment on a document. Returns `{ id, deleted }`.

```bash
curl -X DELETE https://tools.madebytle.com/api/md-to-pdf/share/external/<id>/comments \
  -H "Authorization: Bearer $MD_SHARE_API_KEY"
```

Readers can do the same from the page itself — a trash button on each comment
and a "ล้างทั้งหมด" button in the comment panel — via the keyless
`DELETE /api/md-to-pdf/share/<id>/comments` and
`DELETE /api/md-to-pdf/share/<id>/comments/<commentId>`.

## DELETE /api/md-to-pdf/share/external/{id}

Kill a link early — an upload of the wrong file, or a report that should stop
being readable. Its comments go with it. Not reversible.

```bash
curl -X DELETE https://tools.madebytle.com/api/md-to-pdf/share/external/<id> \
  -H "Authorization: Bearer $MD_SHARE_API_KEY"
```

## Errors

| Status | Meaning |
|--------|---------|
| 400 | Body has no markdown, invalid JSON, or the id is not a uuid |
| 401 | Missing or wrong Bearer key |
| 404 | No document with that id (already deleted, or expired and swept) |
| 500 | Server or database failure — `detail` carries the reason |

Errors are always JSON with an `error` field. A 401 means the key, not the
document: retrying without fixing the header will not help.

## Worth knowing before you build on this

- **One key, no per-document owner.** Whoever holds the key can overwrite or
  delete any link this API created, not only their own. Treat it as a publishing
  credential and keep it out of anything you print back to a user.
- **Public links.** Anyone with the url can read the document and comment on it,
  and search engines are not blocked from it. Do not put anything through here
  that should not be readable by a stranger who guesses or is forwarded the url.
- **Expiry is real.** After 30 days a nightly job deletes the
  document and its comments. PUT renews the clock; nothing else does.
- **Rendering.** GitHub-flavoured markdown — tables, task lists, fenced code
  with syntax highlighting, and `mermaid` diagram blocks all render. Raw HTML
  in the document is rendered as HTML.
- **PDF.** There is no PDF endpoint. The page has a "ดาวน์โหลด PDF" button that
  prints it; the document title becomes the suggested filename.
