MDX.md
REST API for MDXLD documents
MDX.md
MDX.md is the REST API for MDXLD documents - GET, POST, PUT, DELETE operations for MDX content over HTTP.
What is MDX.md?
MDX.md provides a text-only HTTP API for MDXLD documents:
- GET: Retrieve MDX documents as plain text
- POST: Create new MDX documents
- PUT: Update existing MDX documents
- DELETE: Delete MDX documents
- Content-Type:
text/markdownortext/mdx - No UI: Pure API, no visual interface
- Authentication: OAuth via OAuth.do
URL Patterns
Database Structure: mdx.md/:domain/:type/:id
Access documents using the platform database structure:
Where:
:domain- The domain/namespace (e.g.,blog.do,docs.do,landing.do):type- Document$type(e.g.,BlogPost,Article,LandingPage):id- Document$idfrom platform database
Custom URL: mdx.md/:url
Access documents with custom URLs stored in the database:
The platform resolves the URL to the correct document in the database.
HTTP Methods
GET - Retrieve Document
Retrieve MDX document as plain text:
Response:
---
$id: my-first-post
$type: BlogPost
$context: https://schema.org
title: My First Post
author: Jane Doe
datePublished: 2024-01-15
---
# My First Post
This is my first blog post...Response Headers:
Content-Type: text/markdown; charset=utf-8X-MDX-Type: BlogPostX-MDX-ID: my-first-postX-MDX-Domain: blog.do
POST - Create Document
Create a new MDX document:
curl -X POST https://mdx.md/blog.do/BlogPost/new-post \
-H "Content-Type: text/markdown" \
-H "Authorization: Bearer $TOKEN" \
--data-binary @new-post.mdxRequest Body:
---
$type: BlogPost
$context: https://schema.org
title: New Blog Post
---
# New Blog Post
Content here...Response:
201 CreatedLocation: https://mdx.md/blog.do/BlogPost/new-post
PUT - Update Document
Update an existing MDX document:
curl -X PUT https://mdx.md/blog.do/BlogPost/my-first-post \
-H "Content-Type: text/markdown" \
-H "Authorization: Bearer $TOKEN" \
--data-binary @updated-post.mdxResponse:
200 OK
DELETE - Delete Document
Delete an MDX document:
curl -X DELETE https://mdx.md/blog.do/BlogPost/my-first-post \
-H "Authorization: Bearer $TOKEN"Response:
204 No Content
Query Parameters
Format
Specify output format:
# Get raw MDX
curl "https://mdx.md/blog.do/BlogPost/my-post"
# Get JSON (frontmatter + content)
curl "https://mdx.md/blog.do/BlogPost/my-post?format=json"
# Get only frontmatter
curl "https://mdx.md/blog.do/BlogPost/my-post?format=frontmatter"
# Get only content
curl "https://mdx.md/blog.do/BlogPost/my-post?format=content"Revision
Get specific revision:
Fields
Select specific fields:
List Documents
List documents by type:
# List all BlogPost documents
curl "https://mdx.md/blog.do/BlogPost"
# List with pagination
curl "https://mdx.md/blog.do/BlogPost?limit=10&offset=20"
# List with filters
curl "https://mdx.md/blog.do/BlogPost?author=jane-doe&published=true"
# List with sorting
curl "https://mdx.md/blog.do/BlogPost?sort=-datePublished"Authentication
Use OAuth tokens for authenticated requests:
# Get OAuth token
TOKEN=$(curl -X POST https://oauth.do/token \
-d "grant_type=client_credentials" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
| jq -r .access_token)
# Use token
curl https://mdx.md/blog.do/BlogPost/my-post \
-H "Authorization: Bearer $TOKEN"Content Negotiation
MDX.md supports content negotiation via Accept header:
# Get as Markdown
curl https://mdx.md/blog.do/BlogPost/my-post \
-H "Accept: text/markdown"
# Get as JSON
curl https://mdx.md/blog.do/BlogPost/my-post \
-H "Accept: application/json"
# Get as HTML (rendered)
curl https://mdx.md/blog.do/BlogPost/my-post \
-H "Accept: text/html"
# Get as XML (Atom/RSS)
curl https://mdx.md/blog.do/BlogPost \
-H "Accept: application/atom+xml"Response Formats
Markdown (default)
Raw MDX document:
---
$type: BlogPost
title: My Post
---
# My Post
Content...JSON
Structured format:
{
"$id": "my-post",
"$type": "BlogPost",
"$context": "https://schema.org",
"data": {
"title": "My Post",
"author": "Jane Doe",
"datePublished": "2024-01-15"
},
"content": "# My Post\n\nContent...",
"metadata": {
"created": "2024-01-15T10:00:00Z",
"modified": "2024-01-15T12:00:00Z",
"revision": 3
}
}HTML
Rendered output:
<!DOCTYPE html>
<html>
<head>
<title>My Post</title>
<meta property="og:type" content="article">
</head>
<body>
<article>
<h1>My Post</h1>
<p>Content...</p>
</article>
</body>
</html>Batch Operations
Batch GET
Retrieve multiple documents:
curl -X POST https://mdx.md/_batch \
-H "Content-Type: application/json" \
-d '{
"operations": [
{"method": "GET", "path": "/blog.do/BlogPost/post-1"},
{"method": "GET", "path": "/blog.do/BlogPost/post-2"},
{"method": "GET", "path": "/blog.do/BlogPost/post-3"}
]
}'Batch POST/PUT
Create or update multiple documents:
curl -X POST https://mdx.md/_batch \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"operations": [
{
"method": "POST",
"path": "/blog.do/BlogPost/new-post-1",
"body": "---\n$type: BlogPost\n---\n\n# Post 1"
},
{
"method": "PUT",
"path": "/blog.do/BlogPost/existing-post",
"body": "---\n$type: BlogPost\n---\n\n# Updated"
}
]
}'Webhooks
Subscribe to document changes:
# Register webhook
curl -X POST https://mdx.md/_webhooks \
-H "Authorization: Bearer $TOKEN" \
-d '{
"url": "https://myapp.com/webhook",
"events": ["created", "updated", "deleted"],
"filter": {
"type": "BlogPost",
"domain": "blog.do"
}
}'Webhook payload:
{
"event": "updated",
"document": {
"$id": "my-post",
"$type": "BlogPost",
"domain": "blog.do"
},
"changes": {
"title": {
"old": "Old Title",
"new": "New Title"
}
},
"timestamp": "2024-01-15T12:00:00Z"
}Integration Examples
Git Sync
Sync MDX documents to Git:
#!/bin/bash
# Fetch all documents
curl "https://mdx.md/blog.do/BlogPost?format=json" | \
jq -r '.[] | "\(.data.path) \(.$id)"' | \
while read path id; do
curl "https://mdx.md/blog.do/BlogPost/$id" > "$path"
done
git add .
git commit -m "Sync from MDX.md"
git pushCI/CD Integration
Deploy on document update:
# .github/workflows/deploy.yml
name: Deploy on MDX Update
on:
repository_dispatch:
types: [mdx-updated]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Fetch updated MDX
run: |
curl "https://mdx.md/${{ github.event.client_payload.path }}" \
-o "${{ github.event.client_payload.local_path }}"
- name: Deploy
run: npm run deployCMS Integration
Use as headless CMS:
import { MDXClient } from '@dotdo/mdx-client'
const mdx = new MDXClient({
baseURL: 'https://mdx.md',
token: process.env.MDX_TOKEN
})
// Fetch all blog posts
const posts = await mdx.list('blog.do', 'BlogPost', {
sort: '-datePublished',
limit: 10
})
// Fetch single post
const post = await mdx.get('blog.do', 'BlogPost', 'my-post')
// Create new post
await mdx.create('blog.do', 'BlogPost', 'new-post', {
frontmatter: {
title: 'New Post',
author: 'Jane Doe'
},
content: '# New Post\n\nContent...'
})
// Update post
await mdx.update('blog.do', 'BlogPost', 'my-post', {
frontmatter: {
title: 'Updated Title'
}
})
// Delete post
await mdx.delete('blog.do', 'BlogPost', 'my-post')Error Responses
404 Not Found
{
"error": "not_found",
"message": "Document not found",
"path": "/blog.do/BlogPost/nonexistent"
}401 Unauthorized
{
"error": "unauthorized",
"message": "Authentication required"
}403 Forbidden
{
"error": "forbidden",
"message": "Insufficient permissions"
}422 Unprocessable Entity
{
"error": "validation_error",
"message": "Invalid frontmatter",
"details": [
{
"field": "datePublished",
"message": "Must be a valid ISO 8601 date"
}
]
}Rate Limits
- Free tier: 100 requests/hour
- Pro tier: 1,000 requests/hour
- Enterprise: Unlimited
Rate limit headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642262400Best Practices
- Use authentication: Always use OAuth tokens for write operations
- Handle rate limits: Implement exponential backoff
- Cache responses: Use ETags for conditional requests
- Batch operations: Use batch API for multiple requests
- Subscribe to webhooks: Get real-time updates instead of polling
- Validate frontmatter: Ensure valid YAML before POST/PUT
- Version documents: Use revision parameter for history
Resources
- API Reference: api.mdx.md
- SDK: @dotdo/mdx-client
- Status: status.mdx.md
- Support: [email protected]