feat: generate image metadata and expose public search API

This commit is contained in:
smileBeda committed 2026-09-30 16:24:53 -03:00
1 parent 082f715c39
commit 137cad1d84
7 files changed
+450 -93

No files matched your search

+88 -5
View File
@@ -3,7 +3,7 @@
"info": {
"title": "The Meme Protocol API",
"version": "1.1.0",
"description": "Public API for listing approved memes and adding PNG/JPEG meme uploads. Uploads follow the same moderation, image validation, normalization, and IP quota rules as the browser form."
"description": "Public API for listing and searching approved memes by AI-generated captions and managed tags, and uploading PNG/JPEG images. Metadata editing and tag management are admin-only. Uploads follow the same moderation, validation, normalization, and IP quota rules as the browser form."
},
"servers": [
{
@@ -26,8 +26,8 @@
"tags": [
"memes"
],
"summary": "List approved memes",
"description": "Returns approved public memes only. Results are paginated and read-limited per IP to reduce abuse.",
"summary": "List or search approved memes",
"description": "Returns approved public memes only. With q, matches captions and tags using case/accent-insensitive words, prefixes, and small spelling corrections; every query word must match. Results rank by relevance, then newest first. Repeated tag filters must all match exactly. Without q results are newest first. Page numbers beyond the last page are clamped. Results are paginated and read-limited per IP.",
"parameters": [
{
"name": "page",
@@ -47,6 +47,30 @@
"maximum": 48,
"default": 12
}
},
{
"name": "q",
"in": "query",
"description": "Caption/topic search. Lexical fuzzy matching, not semantic or embedding search.",
"schema": {
"type": "string",
"maxLength": 200
}
},
{
"name": "tag",
"in": "query",
"description": "Managed tag names. Repeat tag to require all selected topics. Names are normalized to lowercase.",
"style": "form",
"explode": true,
"schema": {
"type": "array",
"maxItems": 20,
"items": {
"type": "string",
"maxLength": 60
}
}
}
],
"responses": {
@@ -80,6 +104,9 @@
},
"429": {
"$ref": "#/components/responses/RateLimited"
},
"400": {
"description": "Invalid search query or tag filters"
}
}
},
@@ -88,7 +115,7 @@
"memes"
],
"summary": "Add a meme",
"description": "Adds one PNG or JPEG image using the same path as the browser upload form. The request must be multipart/form-data with a file field named meme. The server enforces the same size, dimension, pixel, moderation, normalization, and per-IP upload limits as browser additions.",
"description": "Adds one PNG or JPEG image using the same path as the browser upload form. The request must be multipart/form-data with a file field named meme. The server enforces the same size, dimension, pixel, moderation, normalization, and per-IP upload limits as browser additions. Captions and tags are generated by the server; uploaders cannot supply or edit them.",
"requestBody": {
"required": true,
"content": {
@@ -309,6 +336,46 @@
}
}
}
},
"/api/tags": {
"get": {
"tags": [
"memes"
],
"summary": "List available tag names",
"description": "Returns the public, admin-managed tag catalog for topic filters. Uses the API read limit.",
"responses": {
"200": {
"description": "Tag catalog",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"tags",
"rateLimit"
],
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string",
"maxLength": 60
}
},
"rateLimit": {
"$ref": "#/components/schemas/RateLimit"
}
}
}
}
}
},
"429": {
"$ref": "#/components/responses/RateLimited"
}
}
}
}
},
"components": {
@@ -331,7 +398,9 @@
"originalName",
"url",
"downloadUrl",
"demo"
"demo",
"caption",
"tags"
],
"properties": {
"id": {
@@ -401,6 +470,20 @@
},
"demo": {
"type": "boolean"
},
"caption": {
"type": "string",
"maxLength": 2000,
"description": "Searchable image description. Empty for images not captioned yet; generated by AI or edited by an admin."
},
"tags": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"maxLength": 60
},
"description": "Assigned names from the admin-managed tag catalog."
}
}
},