API Documentation
Programmatic access to f0ck.org. All endpoints return JSON. Rate limits apply per IP or API key.
Authentication & Content Ratings
Safe content is public. Sketchy and unsafe content requires a login — a browser session or the X-API-Key header — for fetching, uploading, and editing. Without one you get a 401 with a clear message.
| Content rating | Anonymous | Session (logged in) | API key (X-API-Key) |
|---|---|---|---|
| safe | 200 ✓ | 200 ✓ | 200 ✓ |
| sketchy | 401 ✗ | 200 ✓ | 200 ✓ |
| unsafe | 401 ✗ | 200 ✓ | 200 ✓ |
- Anonymous feeds return safe posts only — an anonymous
contentRatingfilter acceptssafeand returns 401 for anything else. - Uploads and rating edits:
safeworks for everyone, sketchy/unsafe require a login. - An API key is a full login equivalent — no browser session needed for scripts and bots.
{
"error": "Sign in to view sketchy or unsafe content",
"code": "AUTH_REQUIRED_FOR_RESTRICTED_CONTENT",
"rating": "sketchy"
}{
"error": "Sign in to upload sketchy or unsafe content",
"code": "AUTH_REQUIRED_FOR_RESTRICTED_CONTENT",
"rating": "unsafe"
}Getting Started
The f0ck.org API is a RESTful interface for interacting with the platform. Safe content is public — read it, upload it, and comment without an account. Sketchy and unsafe content (viewing, uploading, editing) requires a login: a session cookie or the X-API-Key header. For scripts and bots, create an API key in Settings → API Keys and send it via the X-API-Key header. All endpoints return JSON.
https://f0ck.orgJSON (application/json)Public: safe · Login: sketchy/unsafeTry it live
Run a real read-only request against the public API. Safe presets work anonymously — rating presets for sketchy/unsafe show a clean “Sign in required” until you log in. Only /api/* paths are allowed here.
No response yet — pick a preset and hit “Send request”.
API Key Authentication
API keys provide programmatic access with higher rate limits. Create keys at Settings → API Keys. Include the key in the X-API-Key header.
A valid key counts as a login: it unlocks sketchy and unsafe content (viewing, uploading, editing) without a browser session — the same access a logged-in user has. Read-only keys (scope: read) are limited to GET requests and therefore to read access.
# The X-API-Key header satisfies the login gate for rating content
curl "https://f0ck.org/api/posts?limit=5&contentRating=sketchy" \
-H "X-API-Key: f0ck_...YOUR_KEY"| Tier | Rate Limit | Max Keys | Price |
|---|---|---|---|
| Free | 30 req/hour | 0 (session only) | Free |
| Basic | 200 req/hour | 1 | $3/mo |
| Pro | 1,000 req/hour | 3 | $7/mo |
| Enterprise | 5,000 req/hour | 5 | $15/mo |
Moderators and admins automatically use Enterprise limits. Keys can be created with scope read (GET requests only) or full (default). Listed keys are always masked (first8...last4) — the full key is shown only once at creation.
Anonymous access is limited to safe posts — contentRating=sketchy or unsafe returns 401 without a session or API key.
Query Parameters
| Name | Type | Description |
|---|---|---|
| offset | number | Pagination offset |
| limit | number | Results per page (max 100) |
| search | string | Text search in title and tags |
| uploader | string | Filter by uploader username |
| tag | string | Filter by tag (can be repeated) |
| sortBy | string | Sort order |
| contentRating | string | Filter by rating: safe, sketchy, unsafe — anonymous calls accept safe only |
| minLikes | number | Minimum likes threshold |
| dateFrom | string | ISO date start range |
| dateTo | string | ISO date end range |
Response
{
"posts": [
{
"id": "64f1a2b3c4d5e6f7a8b9c0d1",
"title": "My Post",
"thumbnail": "/uploads/thumb.jpg",
"imageUrl": "/uploads/full.jpg",
"likes": 42,
"comments": 7,
"contentRating": "safe",
"author": { "username": "user123" },
"tags": ["funny", "cat"]
}
],
"totalPosts": 150,
"currentPage": 1,
"totalPages": 6
}Example
curl "https://f0ck.org/api/posts?limit=10&sortBy=most_liked&tag=cat"
# Rating filter — anonymous: contentRating=safe only.
# sketchy/unsafe require login (session cookie or X-API-Key header):
curl -H "X-API-Key: f0ck_...YOUR_KEY" "https://f0ck.org/api/posts?limit=10&contentRating=sketchy"Safe posts are public. Fetching a sketchy or unsafe post returns 401 without a session or API key.
Response
{
"id": "64f1a2b3c4d5e6f7a8b9c0d1",
"title": "My Post",
"content": "Post description text",
"imageUrl": "/uploads/full.jpg",
"mediaType": "image",
"stats": { "likes": 42, "comments": 7, "favorites": 3 },
"contentRating": "safe",
"author": {
"id": "64f1a2b3c4d5e6f7a8b9c0d2",
"username": "user123",
"avatar": "/avatars/user123.jpg"
},
"tags": ["funny", "cat"],
"createdAt": "2024-01-15T10:30:00.000Z"
}Example
curl "https://f0ck.org/api/posts/64f1a2b3c4d5e6f7a8b9c0d1"Query Parameters
| Name | Type | Description |
|---|---|---|
| search | string | Search tag names |
| page | number | Page number |
| limit | number | Results per page |
| sortBy | string | Sort: most_used, newest, alphabetical, trending |
| author | string | Filter by author's posts |
| timeRange | string | Time filter: day, week, month, year, all |
Response
{
"tags": [
{
"_id": "64f1a2b3c4d5e6f7a8b9c0d3",
"name": "cat",
"postsCount": 1523,
"newPostsToday": 12,
"newPostsThisWeek": 67
}
],
"pagination": {
"total": 340,
"page": 1,
"perPage": 20,
"totalPages": 17
}
}Example
curl "https://f0ck.org/api/tags?search=cat&sortBy=most_used"Response
{
"pools": [
{
"_id": "64f1a2b3c4d5e6f7a8b9c0d4",
"name": "Best Cats 2024",
"description": "Curated collection of cat posts",
"postCount": 45,
"isPublic": true,
"creator": { "username": "user123" }
}
],
"totalPools": 28,
"page": 1,
"totalPages": 3
}Example
curl "https://f0ck.org/api/pools?page=1&limit=20"Response
{
"activeUsers24h": 142,
"newPosts24h": 89,
"newComments24h": 234,
"totalPosts": 15230,
"totalComments": 89210,
"totalUsers": 5678,
"totalTags": 340,
"serverStatus": "healthy",
"version": "5.6.0"
}Example
curl "https://f0ck.org/api/public/status"Response
{
"username": "user123",
"bio": "I love cats",
"avatar": "/avatars/user123.jpg",
"createdAt": "2023-06-15T08:00:00.000Z",
"stats": {
"uploads": 156,
"comments": 89,
"favorites": 42,
"likes": 234
}
}Example
curl "https://f0ck.org/api/users/user123"Safe uploads work anonymously. contentRating=sketchy or unsafe requires a session or API key — otherwise 401.
Request Body
{
"file": <binary>,
"title": "My upload",
"tags": "funny,cat",
"contentRating": "safe", // "safe" works anonymously; sketchy/unsafe require login
"isNSFW": false
}Response
{
"message": "Upload successful",
"post": {
"id": "64f1a2b3c4d5e6f7a8b9c0d5",
"title": "My upload",
"imageUrl": "/uploads/full.jpg",
"thumbnailUrl": "/uploads/thumb.jpg",
"mediaType": "image"
}
}Example
curl -X POST "https://f0ck.org/api/upload" \
-H "Cookie: next-auth.session-token=<session-token>" \
-F "[email protected]" \
-F "title=My upload" \
-F "tags=funny,cat" \
-F "contentRating=safe"Request Body
{
"postId": "64f1a2b3c4d5e6f7a8b9c0d1",
"content": "Great post!",
"parentId": null
}Response
{
"message": "Comment posted",
"comment": {
"id": "64f1a2b3c4d5e6f7a8b9c0d6",
"content": "Great post!",
"author": {
"username": "user123",
"avatar": "/avatars/user123.jpg"
},
"createdAt": "2024-01-15T10:30:00.000Z"
}
}Example
curl -X POST "https://f0ck.org/api/comments" \
-H "Content-Type: application/json" \
-H "Cookie: next-auth.session-token=<session-token>" \
-d '{
"postId": "64f1a2b3c4d5e6f7a8b9c0d1",
"content": "Great post!"
}'Request Body
{
"name": "My integration",
"scope": "read" // "read" (GET only) or "full" (default)
}Response
{
"id": "64f1a2b3c4d5e6f7a8b9c0d7",
"key": "f0ck_9f2c...a1b2 (full key, shown once)",
"name": "My integration",
"scope": "read",
"rateLimit": 200,
"createdAt": "2024-01-15T10:30:00.000Z"
}Example
curl -X POST "https://f0ck.org/api/user/api-keys" \
-H "Content-Type: application/json" \
-H "Cookie: next-auth.session-token=<session-token>" \
-d '{"name": "My integration", "scope": "read"}'Response
{
"keys": [
{
"id": "64f1a2b3c4d5e6f7a8b9c0d7",
"key": "f0ck_9f2c...a1b2",
"name": "My integration",
"scope": "read",
"lastUsed": "2024-01-15T10:00:00.000Z",
"createdAt": "2024-01-15T10:30:00.000Z",
"isActive": true,
"rateLimit": 200
}
]
}Example
curl "https://f0ck.org/api/user/api-keys" \
-H "Cookie: next-auth.session-token=<session-token>"Request Body
{
"keyId": "64f1a2b3c4d5e6f7a8b9c0d7"
}Response
{
"message": "API key revoked successfully"
}Example
curl -X DELETE "https://f0ck.org/api/user/api-keys" \
-H "Content-Type: application/json" \
-H "Cookie: next-auth.session-token=<session-token>" \
-d '{"keyId": "64f1a2b3c4d5e6f7a8b9c0d7"}'Query Parameters
| Name | Type | Description |
|---|---|---|
| postId | string | Post ID (ObjectId or numeric ID) to list comments for |
| page | number | Page number |
| limit | number | Results per page |
| username | string | Filter by comment author |
| searchText | string | Full-text search in comment content |
Response
{
"comments": [
{
"id": "64f1a2b3c4d5e6f7a8b9c0d6",
"content": "Great post!",
"author": { "username": "user123" },
"likes": 5,
"createdAt": "2024-01-15T10:30:00.000Z"
}
],
"pagination": { "total": 42, "pages": 5, "current": 1, "limit": 10 }
}Example
curl "https://f0ck.org/api/comments?postId=64f1a2b3c4d5e6f7a8b9c0d1&limit=10"Query Parameters
| Name | Type | Description |
|---|---|---|
| page | number | Page number |
| limit | number | Results per page (max 50) |
| action | string | Filter: delete, approve, reject, feature, pin, unpin, ban, unban |
| type | string | Target type: post, comment, user, tag |
Response
{
"activities": [
{
"id": "64f1a2b3c4d5e6f7a8b9c0d8",
"action": "feature",
"targetType": "post",
"targetInfo": "My Post",
"moderator": "mod_jane",
"createdAt": "2024-01-15T10:30:00.000Z"
}
],
"pagination": { "total": 320, "pages": 16, "current": 1, "limit": 20 }
}Example
curl "https://f0ck.org/api/moderation/public-activity?action=feature&limit=5"Same rating gate as /api/upload: safe works anonymously, sketchy/unsafe require a session or API key.
Request Body
// 1. Upload chunks (repeat per chunk)
{
"fileId": "550e8400-e29b-41d4-a716-446655440000", // client-generated UUID
"chunkIndex": 0,
"totalChunks": 12,
"totalFileSize": 52428800,
"chunk": <binary>,
"tags": "funny,cat",
"contentRating": "safe" // sketchy/unsafe require login
}
// 2. Assemble (application/json)
{
"fileId": "550e8400-e29b-41d4-a716-446655440000",
"fileName": "video.mp4",
"tags": "funny,cat",
"contentRating": "safe"
}Response
{
"message": "Upload successful",
"post": {
"id": "64f1a2b3c4d5e6f7a8b9c0d5",
"title": "video.mp4",
"imageUrl": "/uploads/full.mp4",
"mediaType": "video"
}
}Example
curl -X POST "https://f0ck.org/api/upload/chunk" \
-H "Cookie: next-auth.session-token=<session-token>" \
-F "fileId=550e8400-e29b-41d4-a716-446655440000" \
-F "chunkIndex=0" -F "totalChunks=12" \
-F "[email protected]"
curl -X POST "https://f0ck.org/api/upload/assemble-chunks" \
-H "Content-Type: application/json" \
-H "Cookie: next-auth.session-token=<session-token>" \
-d '{"fileId": "550e8400-e29b-41d4-a716-446655440000", "fileName": "video.mp4"}'Pagination & Filtering
List endpoints share the same conventions. Repeatable filters (e.g. tag) can be passed multiple times.
# Offset style (posts)
GET /api/posts?offset=28&limit=28&sortBy=newest&tag=cat&tag=funny
# Page style (comments, tags, moderation activity)
GET /api/comments?postId=<id>&page=2&limit=10
GET /api/moderation/public-activity?action=feature&type=post&page=1&limit=20limitis capped per endpoint (posts: 100, activity: 50)- Date ranges use ISO strings via
dateFrom/dateTo - Responses include
pagination: { total, pages, current, limit }ortotalPosts / totalPages
CORS & Headers
- Send
Accept: application/jsonwith every request - Programmatic auth:
X-API-Key: f0ck_... (your key)— allowed as a CORS header on/api/* - Browser uploads rely on session cookies with
credentials: "include" - Media under
/uploads/*and/api/images/*allow cross-origin GET
// Public read with API key (bots, scripts)
const res = await fetch("https://f0ck.org/api/posts?limit=5", {
headers: {
Accept: "application/json",
"X-API-Key": "f0ck_...YOUR_KEY", // placeholder — never commit real keys
},
});Error Handling
Errors return HTTP status codes with a JSON body. Rate-limited requests include a Retry-After header. Rating-gated endpoints answer anonymous requests with 401 “Sign in required” — see the access matrix at the top of this page.
{
"error": "Post not found",
"status": 404
}{
"error": "Rate limit exceeded. Try again in 32 seconds.",
"retryAfter": 32
}{
"error": "Invalid API key"
}{
"error": "Sign in to view sketchy or unsafe content",
"code": "AUTH_REQUIRED_FOR_RESTRICTED_CONTENT",
"rating": "sketchy"
}Rate Limits
- IP-based limits apply when no API key is provided
- API key limits are per-user and based on your premium tier
- Rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
- 429 responses include Retry-After header
- Read endpoints have higher limits than write endpoints
Showing 14 of 14 endpoints