BUILD ON THE VAULT

Developer API.

Pull the approved meme feed into your own site or app, and let your community submit to the vault without ever leaving it. Reads are open. Submissions need a key, and every one of them still goes through a human moderator before it appears anywhere.

The 30-second version

Drop this on any page and you have a live meme grid:

<div data-vault-feed data-project="plank" data-limit="12"></div>
<script src="https://memes.smoothbrain.app/embed.js" defer></script>

Supported attributes: data-project, data-type (image / video), data-q (search), data-limit (max 50), and data-key if you have one. The widget ships its own styles, has no dependencies, and fails quietly if the vault is unreachable.

Base URL — check this first

Every endpoint lives under https://memes.smoothbrain.app/api/v1/. Confirm your integration is pointed there and that your key is being seen:

curl -H "Authorization: Bearer $VAULT_API_KEY" https://memes.smoothbrain.app/api/v1
{ "service": "community-meme-vault", "version": "v1",
  "authenticated": true,
  "key": { "label": "Your app", "canRead": true, "canSubmit": true },
  "endpoints": { … } }

The /v1/ matters. A pre-v1 endpoint still exists at/api/assets for this site's own pages. Calling it by mistake returns200, so it looks like it works — but it ignores your API key entirely and sends no CORS headers, so browser requests fail and your usage never registers. Ifauthenticated comes back false while you are sending a key, the key is not reaching us or is not valid.

When something is not working

  • Try without a key first. Reads are open, so dropping the auth header isolates whether the problem is authentication or something else entirely.
  • Handle non-200 responses. Every failure returns JSON in the same shape — {"error":{"code":"…","message":"…"}} — with a useful code. Proxying our response straight through without checking the status is the usual cause of a 500 on your side.
  • 401 invalid_key — the key is wrong, mistyped, or from another environment.
  • 401 revoked_key — it was revoked. Keys cannot be un-revoked; ask for a new one.
  • 403 forbidden — the key is valid but lacks that permission (usually submitting with a read-only key).
  • 400 invalid_request — a bad parameter. The message says which; unknown type values are rejected rather than silently returning nothing.
  • 429 rate_limited — slow down, or ask for a higher limit.

We record usage per key, so a vault admin can confirm from the admin panel whether your requests are arriving at all. If your key shows zero requests while your app is live, the calls are not reaching us — check the base URL above before digging further.

Attribution (required)

Displaying vault media means crediting the vault. Every response includes an attribution object so you never have to hardcode our name or URL — render attribution.html near the media and you are done. The embed widget does this for you automatically.

"attribution": {
  "text": "Community Meme Vault by Smooth Brain Labs",
  "url": "https://memes.smoothbrain.app",
  "parent": "https://smoothbrain.app",
  "required": true,
  "html": "Memes via <a href="https://memes.smoothbrain.app">Community Meme Vault</a> · <a href="https://smoothbrain.app">Smooth Brain Labs</a>"
}

Credit the individual creator too wherever you have room — every asset carries creatorName. That is the meme's author; attribution is the platform.

Authentication

Send your key as Authorization: Bearer cmv_live_… or X-API-Key: cmv_live_….

  • Reading is open. The feed is public data; no key required. A key raises your rate limit and lets us tell you before something breaks, so use one in production.
  • Submitting requires a key with the submit permission. Ask an admin in the vault to issue one.
  • Keys are secrets. Never put a submit-capable key in client-side code — anyone can read it there. Call the submit endpoint from your server.

GET /api/v1/assets

Approved media, newest first.

Query parameters: project, type (image, gif or video — plurals like gifs are accepted, but an unrecognised value returns 400 rather than an empty list), q (full-text search), page, limit (1–50, default 24).

curl "https://memes.smoothbrain.app/api/v1/assets?project=plank&limit=2"
{
  "assets": [
    {
      "id": "1f0c…",
      "title": "Orange Goose Signal",
      "project": "plank",
      "tags": ["goose", "signal"],
      "creatorName": "anon",
      "mediaType": "image",
      "mimeType": "image/png",
      "createdAt": "2026-08-01T18:22:04.000Z",
      "url": "https://memes.smoothbrain.app/asset/1f0c…",
      "mediaUrl": "https://memes.smoothbrain.app/media/1f0c…",
      "downloadUrl": "https://memes.smoothbrain.app/media/1f0c…/download",
      "projectUrl": "https://memes.smoothbrain.app/project/plank"
    }
  ],
  "page": 1,
  "hasMore": true,
  "authenticated": false
}

url is the asset's own page — link readers there, since it carries per-asset Open Graph tags and unfurls properly when shared. mediaUrl is the raw file: absolute and CORS-open, so you can hotlink it directly or proxy it, whichever suits your caching. projectUrl is that project's page in the vault.

Changed 2026-08-02: asset objects previously returned pageUrl, which pointed at the project page despite the name. It is now projectUrl, and the new url field is the meme's own page. Rename any use ofpageUrl to projectUrl, or switch to url if you meant to link the meme.

GET /api/v1/assets/:id

One approved asset. Anything pending or rejected returns 404 — the public API never confirms that an unapproved submission exists.

GET /api/v1/projects

The canonical project list, with links and any token or NFT contracts. Build your submit dropdown from this rather than hardcoding: project is validated against this exact list, so a stale hardcoded value will be rejected.

POST /api/v1/submissions

Send multipart/form-data with a media file part. The submission lands in the review queue as pending. It is not public, and it will not appear in the feed, until a moderator approves it.

Fields: media (required), title (required), project (required, must match a slug from /api/v1/projects), creatorName, description, tags (comma-separated), sourceUrl.

curl -X POST "https://memes.smoothbrain.app/api/v1/submissions" \
  -H "Authorization: Bearer $VAULT_API_KEY" \
  -F "[email protected]" \
  -F "title=Orange Goose Signal" \
  -F "project=plank" \
  -F "creatorName=anon"
{
  "asset": { "id": "…", "title": "Orange Goose Signal", … },
  "status": "pending",
  "message": "Submission received. A moderator has to approve it before it appears in the feed.",
  "duplicateOf": []
}

Accepted media: JPEG, PNG, WebP, GIF, MP4, WebM, up to 25 MB. Files are validated by their actual bytes, not their extension. If the same file already exists, duplicateOf lists it — this is informational, not a rejection, so you can tell your user before they wait on review.

Rate limits and errors

Anonymous reads are limited per IP. Keyed reads and submissions use the per-key hourly budget shown on your key. Over the limit returns 429.

{ "error": { "code": "rate_limited", "message": "Too many requests. Slow down." } }

Every error uses that shape. Codes you should handle: key_required, invalid_key, revoked_key, forbidden, invalid_request, rate_limited, not_found, server_error.

Getting a key

Keys are issued by vault admins. Tell us what you are building, where it will run, and whether you need submissions or just the feed. A key can be revoked instantly if it is abused, and revoking one never removes memes your community already got approved.

Or just submit a meme yourself →

WIDER ECOSYSTEM

More from Smooth Brain Labs