Developer Reference

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.

24 documented endpoints
Available at / and /api
Examples include request and response shapes

Authentication Overview

Auth and Account

GET /api/meme/login

Redirects the browser to Auth0 login.

Authentication: None

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

POST /api/meme/sync

Bulk syncs meme metadata into the durable object store.

Authentication: None

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": []
}
GET /api/meme

Fetches a single meme by filename.

Authentication: None

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"
  }
}
GET /api/meme/latest

Returns the most recently added memes.

Authentication: None

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": []
}
GET /api/meme/top

Returns the current top memes.

Authentication: None

Parameters

  • No request parameters.

Notes

  • No pagination is exposed by this route.

Example Request

GET /api/meme/top

Example Response

{
  "success": true,
  "memes": []
}
GET /api/meme/random

Returns a random batch of memes.

Authentication: None

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": []
}
GET /api/meme/search

Searches memes by keyword, creator, sort mode, and date range.

Authentication: Optional. User context is read if available, but liked-filter joining is currently disabled in code.

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": []
}
GET /api/meme/creator/:creator

Lists memes uploaded by a specific creator.

Authentication: None

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": []
}
POST /api/meme/upload

Creates a meme metadata entry.

Authentication: Required. Accepts bearer token or API key through auth middleware.

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
}
PUT /api/meme

Creates or updates meme metadata with richer fields.

Authentication: Required. Accepts bearer token or API key through auth middleware.

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
}
GET /api/meme/remove

Removes a meme by filename.

Authentication: Required. Accepts bearer token or API key through auth middleware.

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
}
GET /api/meme/total

Returns the total meme count.

Authentication: None

Parameters

  • No request parameters.

Notes

  • None.

Example Request

GET /api/meme/total

Example Response

{
  "success": true,
  "total": 1234
}

Voting and Ranking

POST /api/meme/vote

Casts an upvote or downvote for a meme hash.

Authentication: Optional. Votes can be anonymous; verified users attach their account name automatically.

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
}
GET /api/meme/user-votes

Returns all votes for the authenticated user.

Authentication: Required in practice. The route expects `verifiedUser` and returns `401` without it.

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": []
}
GET /api/meme/votes/daily

Returns daily vote totals over a rolling period.

Authentication: None

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": []
}
GET /api/meme/voters/active

Returns the number of voters active in the recent time window.

Authentication: None

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
}
GET /api/meme/creators/top

Returns top meme creators.

Authentication: None

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": []
}
GET /api/meme/creators/total

Returns the total number of distinct creators.

Authentication: None

Parameters

  • No request parameters.

Notes

  • None.

Example Request

GET /api/meme/creators/total

Example Response

{
  "success": true,
  "total": 321
}
GET /api/meme/trending-tags

Returns trending tags using a fixed 30-day window.

Authentication: None

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

GET /api/meme/uploads/generate-signed-url

Generates a signed upload URL for object storage.

Authentication: None at the route level.

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"
}
GET /api/meme/uploads/generate-signed-url-delete

Generates a signed delete URL for object storage.

Authentication: None at the route level.

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"
}