Meme Server API
This page documents every active route defined under src/routes. It is intended to be a fast reference for developers integrating with the API without reading the backend source first.
/ and /apiAuthentication Overview
- Public routes can be called without credentials.
- Protected routes use `authMiddleware` and accept `Authorization: Bearer <token>`, `meme-api-key` header, or `api_key` query string.
- When auth middleware rejects a request, it returns `401 Unauthorized - Invalid or expired token` for invalid or missing protected credentials.
- Admin-only actions in this routes folder rely on a JSON body field named `adminKey`.
Auth and Account
/api/meme/login
Redirects the browser to Auth0 login.
Parameters
- No request parameters.
- Uses server-side Auth0 configuration for redirect URI, client ID, and domain.
Notes
- This endpoint returns an HTTP redirect instead of JSON.
- Best used from a browser or frontend login button.
Example Request
GET /api/meme/login
Example Response
302 Redirect
Location: https://<auth0-domain>/authorize?...
Meme Catalog
/api/meme/sync
Bulk syncs meme metadata into the durable object store.
Parameters
- Body JSON: `memes` (array, required).
Notes
- Returns `400` with `{"error":"memes_must_be_array"}` when `memes` is not an array.
Example Request
POST /api/meme/sync
Content-Type: application/json
{
"memes": [
{
"filename": "doge.png",
"checksum": "abc123",
"creator": "alice"
}
]
}
Example Response
{
"success": true,
"memes": []
}
/api/meme
Fetches a single meme by filename.
Parameters
- Query: `filename` (required).
Notes
- Returns `400` with `{"error":"missing_filename"}` when missing.
- Returns `404` with `{"error":"Meme not found"}` when no record matches.
Example Request
GET /api/meme?filename=doge.png
Example Response
{
"success": true,
"meme": {
"filename": "doge.png"
}
}
/api/meme/latest
Returns the most recently added memes.
Parameters
- Query: `limit` (optional, default `100`).
- Query: `offset` (optional, default `0`).
Notes
- Useful for infinite scroll or newest-first views.
Example Request
GET /api/meme/latest?limit=20&offset=0
Example Response
{
"success": true,
"memes": []
}
/api/meme/top
Returns the current top memes.
Parameters
- No request parameters.
Notes
- No pagination is exposed by this route.
Example Request
GET /api/meme/top
Example Response
{
"success": true,
"memes": []
}
/api/meme/random
Returns a random batch of memes.
Parameters
- No request parameters.
Notes
- The route internally picks a random offset and returns up to 10 memes.
Example Request
GET /api/meme/random
Example Response
{
"success": true,
"memes": []
}
/api/meme/search
Searches memes by keyword, creator, sort mode, and date range.
Parameters
- Query: `q` search text (optional, defaults to empty string).
- Query: `c` creator filter (optional).
- Query: `limit` (optional, default `10`).
- Query: `offset` (optional, default `0`).
- Query: `s` sort mode (optional, default `top`).
- Query: `d` date range (optional, default `all`).
- Query: `filter` currently ignored for liked-vote joins.
Notes
- The route always accepts an empty search and still returns a result set.
Example Request
GET /api/meme/search?q=cat&c=alice&limit=10&offset=0&s=top&d=30d
Example Response
{
"success": true,
"memes": []
}
/api/meme/creator/:creator
Lists memes uploaded by a specific creator.
Parameters
- Path: `creator` (required).
- Query: `limit` (optional, default `100`).
- Query: `offset` (optional, default `0`).
Notes
- Returns `400` with `{"error":"missing_creator"}` if the path parameter is empty.
Example Request
GET /api/meme/creator/alice?limit=25&offset=0
Example Response
{
"success": true,
"creator": "alice",
"memes": []
}
/api/meme/upload
Creates a meme metadata entry.
Parameters
- Body JSON: `filename` (required).
- Body JSON: `checksum` (required).
- Body JSON: `size` (optional, default `0`).
- Body JSON: `extension` (optional, default empty string).
- Body JSON: `creator` (optional, default `Marak`).
- Body JSON: `tags` (optional array, default `[]`).
Notes
- Returns `400` with `{"error":"missing_filename_or_checksum"}` when required fields are absent.
Example Request
POST /api/meme/upload
Content-Type: application/json
Authorization: Bearer <token>
{
"filename": "doge.png",
"checksum": "abc123",
"size": 2048,
"extension": "png",
"creator": "alice",
"tags": ["doge", "classic"]
}
Example Response
{
"success": true
}
/api/meme
Creates or updates meme metadata with richer fields.
Parameters
- Body JSON: `filename` (required).
- Body JSON: `checksum` (required).
- Body JSON: `size` (optional, default `0`).
- Body JSON: `extension` (optional, default empty string).
- Body JSON: `title` (optional).
- Body JSON: `description` (optional).
- Body JSON: `tags` (optional array).
- Body JSON: `creator` is only used as a fallback when no verified user is present.
Notes
- The authenticated user becomes the creator when available.
Example Request
PUT /api/meme
Content-Type: application/json
Authorization: Bearer <token>
{
"filename": "doge.png",
"checksum": "abc123",
"title": "Classic Doge",
"description": "Much wow",
"tags": ["doge", "wow"]
}
Example Response
{
"success": true
}
/api/meme/remove
Removes a meme by filename.
Parameters
- Query: `filename` (required).
Notes
- Returns `400` with `{"error":"missing_filename"}` when missing.
Example Request
GET /api/meme/remove?filename=doge.png
Example Response
{
"success": true
}
/api/meme/total
Returns the total meme count.
Parameters
- No request parameters.
Notes
- None.
Example Request
GET /api/meme/total
Example Response
{
"success": true,
"total": 1234
}
Voting and Ranking
/api/meme/vote
Casts an upvote or downvote for a meme hash.
Parameters
- Body JSON: `hash` (required).
- Body JSON: `value` (optional, any negative number becomes `-1`, all other values become `1`).
- Body JSON: `adminKey` (optional, only for admin testing behavior).
- Body JSON: `ip` (optional, only used when valid `adminKey` is provided).
Notes
- IP is inferred from `CF-Connecting-IP` or `X-Forwarded-For`.
- Returns `400` with `{"error":"missing_hash"}` when `hash` is absent.
Example Request
POST /api/meme/vote
Content-Type: application/json
{
"hash": "demo-hash",
"value": 1
}
Example Response
{
"success": true
}
/api/meme/user-votes
Returns all votes for the authenticated user.
Parameters
- No request parameters.
Notes
- This endpoint is intended for profile and account views.
Example Request
GET /api/meme/user-votes
Example Response
{
"success": true,
"username": "alice",
"votes": []
}
/api/meme/votes/daily
Returns daily vote totals over a rolling period.
Parameters
- Query: `days` (optional, default `7`).
Notes
- Response field is named `total` even though it contains per-day data.
Example Request
GET /api/meme/votes/daily?days=14
Example Response
{
"success": true,
"days": 14,
"total": []
}
/api/meme/voters/active
Returns the number of voters active in the recent time window.
Parameters
- Query: `minutes` (optional, default `120`).
Notes
- None.
Example Request
GET /api/meme/voters/active?minutes=60
Example Response
{
"success": true,
"minutes": 60,
"total": 42
}
/api/meme/creators/top
Returns top meme creators.
Parameters
- Query: `limit` (optional, default `10`).
- Query: `offset` (optional, default `0`).
Notes
- None.
Example Request
GET /api/meme/creators/top?limit=10&offset=0
Example Response
{
"success": true,
"creators": []
}
/api/meme/creators/total
Returns the total number of distinct creators.
Parameters
- No request parameters.
Notes
- None.
Example Request
GET /api/meme/creators/total
Example Response
{
"success": true,
"total": 321
}
/api/meme/trending-tags
Returns trending tags using a fixed 30-day window.
Parameters
- Query: `limit` (optional, default `10`).
Notes
- The time window is hardcoded to `30d` in the route.
Example Request
GET /api/meme/trending-tags?limit=10
Example Response
{
"success": true,
"tags": []
}
Upload Helpers
/api/meme/uploads/generate-signed-url
Generates a signed upload URL for object storage.
Parameters
- Query: `fileName` (required).
- Query: `userFolder` (required).
- Query: `me` (required).
- Query: `qtokenid` (optional).
- Header: `Authorization: Bearer <token>` can supply `qtokenid` when query value is absent.
- Query: `format` (optional, `json` or `text`, default `json`).
Notes
- Returns plain text when `format=text`.
- Returns `400` with plain text if required query params are missing.
Example Request
GET /api/meme/uploads/generate-signed-url?fileName=doge.png&userFolder=alice&me=alice&format=json
Example Response
{
"signedUrl": "https://storage.example/upload",
"remoteFilePath": "alice/doge.png"
}
/api/meme/uploads/generate-signed-url-delete
Generates a signed delete URL for object storage.
Parameters
- Query: `fileName` (required).
- Query: `userFolder` (required).
Notes
- Returns plain text errors instead of JSON for failure cases.
Example Request
GET /api/meme/uploads/generate-signed-url-delete?fileName=doge.png&userFolder=alice
Example Response
{
"signedUrl": "https://storage.example/delete"
}