Publishing Your First Document via the API
Publishing on lightpaper.org means sending one HTTP request. There's no dashboard to navigate, no settings page to configure, and no deployment to trigger. This walkthrough covers everything you need to know about the POST /v1/publish endpoint.
Prerequisites
You need an API key. Get one by authenticating via email OTP or LinkedIn OAuth (see Authentication Without Passwords). API keys are prefixed with lp_free_, lp_live_, or lp_test_ depending on your account tier.
The Request
Send a POST to https://lightpaper.org/v1/publish with your API key in the X-API-Key header:
curl -X POST https://lightpaper.org/v1/publish \
-H "Content-Type: application/json" \
-H "X-API-Key: lp_free_yourkey" \
-d '{
"title": "My First Document",
"content": "# Introduction\n\nYour markdown content here...",
"format": "post"
}'
Required Fields
| Field | Type | Description |
|---|---|---|
title |
string | Document title (1-500 characters) |
content |
string | Markdown content (1-500,000 characters, minimum 300 words) |
Optional Fields
| Field | Type | Default | Description |
|---|---|---|---|
subtitle |
string | null | Subtitle displayed below the title |
format |
string | "post" |
One of: "post", "essay", "paper" |
authors |
array | [] |
List of {"name": "...", "handle": "..."} objects |
tags |
array | [] |
Up to 50 string tags for categorization |
metadata |
object | {} |
Arbitrary key-value metadata (max 50KB serialized) |
options.slug |
string | auto | Custom URL slug (max 80 characters) |
options.listed |
boolean | true |
Whether the document appears in search and feeds |
options.og_image |
string | "auto" |
Open Graph image setting |
Content Requirements
Your content must meet two requirements:
- Minimum 300 words — shorter content returns a 422 error
- At least one heading — the content must contain at least one line starting with
#
These requirements ensure that every published document has enough substance to be useful and enough structure to be navigable.
The Response
A successful publish returns a 201 status with detailed feedback:
{
"id": "doc_a1b2c3d4",
"url": "https://lightpaper.org/my-first-document",
"permanent_url": "https://lightpaper.org/d/doc_a1b2c3d4",
"version": 1,
"created_at": "2026-03-04T12:00:00Z",
"word_count": 847,
"reading_time_minutes": 4,
"content_hash": "sha256:abc123...",
"quality_score": 68,
"quality_breakdown": {
"structure": 22,
"substance": 14,
"tone": 18,
"attribution": 14
},
"quality_suggestions": [
"Add a References section"
],
"author_gravity": 1,
"author_gravity_badges": ["linkedin"],
"gravity_note": "Verify your domain to reach Gravity 2."
}
Two URLs
Every document gets two URLs:
- Slug URL (
/my-first-document): Human-readable, derived from the title. Changes if you update the title. - Permanent URL (
/d/doc_a1b2c3d4): Never changes. Use this for stable references.
Both URLs support content negotiation. Browsers and crawlers get HTML. Clients sending Accept: application/json get the raw document data.
Slug Generation
If you don't specify a custom slug, one is generated from your title:
- "My First Document" →
my-first-document - "How to Use the API (v2)" →
how-to-use-the-api-v2
Slugs are automatically deduplicated. If my-first-document already exists, the system generates my-first-document-2.
Certain slugs are reserved to prevent conflicts with platform routes: api, login, search, feed, sitemap, and others. Attempting to use a reserved slug returns a 422 error.
Versioning
Every publish creates version 1. Subsequent updates via PUT /v1/documents/{id} create new versions. The system stores up to 100 versions per document. Each version records the content hash, word count, and reading time, giving you a full history of changes.
Using Python
Here's a complete example using httpx:
import httpx
response = httpx.post(
"https://lightpaper.org/v1/publish",
headers={"X-API-Key": "lp_free_yourkey"},
json={
"title": "My First Document",
"subtitle": "A quick test of the API",
"content": "# Introduction\n\nThis is my first document...",
"format": "post",
"authors": [{"name": "Your Name", "handle": "yourhandle"}],
"tags": ["test", "first-post"],
},
)
print(response.json())
What Happens After Publishing
Once your document is live, several things happen automatically:
- Search engine notification: IndexNow pings Bing, DuckDuckGo, Yandex, and Seznam with your new URLs. Google receives a sitemap ping.
- Feed inclusion: If listed and quality >= 40, your document appears in the Atom feed.
- Sitemap update: The sitemap regenerates to include your document.
- OG image generation: A social sharing image is created at
/og/{doc_id}.png.
No manual steps required. Your content is discoverable the moment it's published.
Error Handling
Common errors and their meanings:
| Status | Error | Fix |
|---|---|---|
| 401 | Invalid API key | Check your X-API-Key header |
| 413 | Request too large | Content exceeds 2MB body limit |
| 422 | Under 300 words | Add more content |
| 422 | No headings | Add at least one # heading |
| 422 | Reserved slug | Choose a different custom slug |
| 429 | Rate limited | Max 60 publishes per hour |