A free, no-key REST API for the VibeKing directory of vibe-coded products.
➜ Browse the live directory: vibeking.fun · Interactive docs: vibeking.fun/api
vibeking.fun is a directory of vibe-coded products — real apps, tools and SaaS built with AI — with 2,500+ listings ranked by community upvotes. This repo documents its public read API.
No API key. No signup. Just hit the endpoints:
curl -s "https://vibeking.fun/api/products?limit=5"Where to go next
| 🌐 Live directory | vibeking.fun — browse, search, upvote |
| 📖 API docs page | vibeking.fun/api — same reference, with a live "try it" |
| 🏆 Current ranking | vibeking.fun/best |
| 📋 Awesome list | 0xvibly/awesome-vibe-coded-apps — this data as a daily-regenerated awesome-list |
| 🚀 Get listed | vibeking.fun/submit — free |
| 🏷️ Badge | BADGE.md — embed a "Featured on VibeKing" badge |
https://vibeking.fun
None. All endpoints below are public GET — no key, no header, no signup.
Machine-readable specs: /openapi.json, /.well-known/ai-plugin.json, /llms.txt.
The one you want. Returns approved products as structured JSON, ordered by upvotes descending, wrapped in an envelope that also carries the directory total and the liveness aggregate.
| Param | Type | Default | Description |
|---|---|---|---|
limit |
1–500, or all |
500 |
Rows per response. Values outside the range clamp to 500. all returns the entire directory (~3 MB). |
offset |
integer | 0 |
Rows to skip. Page with offset += count until offset >= total. |
search |
string | — | Keyword filter across name, tagline and description (case-insensitive, max 80 chars). q works as an alias. |
category |
string | — | Exact category label, case-insensitive (e.g. AI Coding). Omit or pass All for everything. |
ai_tool |
string | — | Filter by the AI tool the product was built with — substring match, e.g. cursor, claude. built_with works as an alias. |
sort |
top |
new |
top |
curl -s "https://vibeking.fun/api/products?limit=1"{
"success": true,
"total": 2583,
"count": 1,
"offset": 0,
"liveness": { "live": 2366, "at_risk": 48, "dead": 0, "unchecked": 169 },
"data": [
{
"id": 3527,
"name": "APIDot",
"tagline": "Unified AI API Platform for Image, Video, Music, and Chat Models",
"description": "APIDot is a unified AI API platform built for developers who want fast, reliable access to production-ready AI models. W…",
"url": "https://apidot.ai/",
"maker": "APIDot",
"ai_tool": "",
"category": "AI Coding",
"upvotes": 951,
"created_at": "2026-01-12 02:20:34",
"approved": 1,
"user_id": null,
"logo_data": "https://submitsaas.com/images/product-icon-ec579b53-…jpg",
"maker_x": "",
"use_cases": null,
"audience": null,
"alternative_to": null,
"live_status": "live",
"last_checked": "2026-08-05 12:00:54",
"fail_count": 0
}
]
}(description and logo_data truncated here for readability — the API returns the full values. Rows also carry backlink_* and approved_at bookkeeping fields you can ignore.)
Envelope
| Field | Notes |
|---|---|
success |
Always true on a 200 |
total |
Approved products in the whole directory, not just this page |
count |
Rows returned in this response |
offset |
Rows skipped |
filters |
Echo of the filters this response applied (search, category, ai_tool, sort); null fields mean no filter |
liveness |
Aggregate URL-health counts across the whole directory — see Liveness |
data |
The product rows |
Product fields
| Field | Type | Notes |
|---|---|---|
id |
number | Product ID — also the /product/{id} page and /badge/{id}.svg badge |
name |
string | Product name |
tagline |
string | One-line description |
description |
string | Long description |
url |
string | The product's own website |
maker |
string | Maker name |
category |
string | One of the live categories (see below) |
upvotes |
number | Community upvote count |
created_at |
string | YYYY-MM-DD HH:MM:SS |
logo_data |
string | Logo image URL (may be empty) |
live_status |
string/null | live, at_risk, dead, or null if not probed yet |
last_checked |
string/null | When the URL was last probed |
fail_count |
number | Consecutive failed probes |
ai_tool, maker_x, use_cases, audience, alternative_to |
string/null | Optional metadata, often empty/null |
Categories are data, not a fixed enum. As of 2026-08-08 the live set includes AI Coding, Dev Tools, Marketing, SaaS, Productivity, Design, Fintech, Education, Health, Search, Video, Community, E-Commerce, Game, Lifestyle, plus a few small/legacy buckets (other, Other, Developer Tools). Derive the current set from the dump itself rather than hardcoding it.
A single approved product as structured JSON. Ids come from /api/products rows or from product page URLs (/product/3527 → id 3527). Unknown ids return a JSON 404.
curl -s "https://vibeking.fun/api/products/3527"Returns one page of the directory as a pre-rendered HTML fragment plus pagination metadata. This is the endpoint the site itself uses for infinite scroll — useful if you want VibeKing's own row markup, less useful for structured data (use /api/products for that).
| Param | Type | Default | Description |
|---|---|---|---|
sort |
trending | new |
trending |
Upvotes descending, or newest first |
category |
string | — | Exact category name, case-insensitive, e.g. Game, AI%20Coding. Omit or pass All for everything |
page |
number | 1 | Page number, 30 products per page |
curl -s "https://vibeking.fun/api/list?category=Game&page=1"{
"html": "\n <div class=\"product-row\">…</div>\n",
"count": 15,
"page": 1,
"total": 15,
"hasMore": false
}(html truncated — it contains the rendered product rows)
count— products on this pagetotal— total products matching the query (2,583 with no filter, as of 2026-08-08)hasMore— whether another page exists
An unknown category simply returns zero results (count: 0, empty html).
Same response shape as /api/list, plus the echoed query. Matches against name, tagline and description; exact name matches rank first, then prefix matches, then everything else by upvotes.
| Param | Type | Default | Description |
|---|---|---|---|
q |
string | — | Search query (truncated to 80 chars). Missing/empty q returns an empty result (still 200) |
page |
number | 1 | Page number, 30 results per page |
curl -s "https://vibeking.fun/api/search?q=todo"{
"html": "\n <div class=\"product-row\">…</div>\n",
"count": 5,
"page": 1,
"total": 5,
"hasMore": false,
"q": "todo"
}No-match queries return 200 with count: 0 and empty html — there is no error state for "nothing found".
Tip: for structured search results, use /api/products?search= — the JSON endpoint filters server-side (this endpoint returns rendered HTML rows for embedding).
Live "Featured on VibeKing" SVG badge for any approved product, rendered from current data and cached for an hour. An unknown or unapproved id returns 404 — badges cannot be minted for products that are not really listed.
| Param | Type | Default | Description |
|---|---|---|---|
theme |
dark | light |
dark |
Badge colour scheme |
style |
count | rank |
count |
count shows upvotes; rank shows the product's position in its category |
Full docs and embed snippets: BADGE.md.
Directories rot. Links break, projects get abandoned, domains lapse — and most directories keep serving the corpses because nobody checks.
VibeKing re-probes every listed product URL on a schedule, and every /api/products response ships the aggregate:
"liveness": { "live": 2366, "at_risk": 48, "dead": 0, "unchecked": 169 }Per row you also get live_status, last_checked and fail_count. Bot-blocking responses (401, 403, 405, 429, 451) are deliberately not counted as failures — a site that blocks the probe is not a dead site.
If you are building anything on top of a directory — a dataset, a newsletter, a leaderboard — that field is the difference between real numbers and inherited rot.
Access-Control-Allow-Origin: * is set on all /api/* endpoints (verified on /api/products, /api/list, and /api/search), so you can call them directly from browser JavaScript on any origin.
The badge endpoint (/badge/{id}.svg) does not send a CORS header. That doesn't matter for the normal use case (<img> embeds work without CORS), but a cross-origin fetch() of the SVG or drawing it to a canvas will be blocked.
There is no API key and no published rate limit. Please be reasonable:
- Page with
limit+offsetinstead of pulling the whole dump on every request. - Cache
?limit=all— it's the whole directory (~3 MB) in one response. Once an hour is plenty; the data doesn't change faster than that. - Don't poll in tight loops; badge SVGs are already served with
Cache-Control: public, max-age=3600. - Heavy automated abuse may get blocked at the edge (the site runs behind Cloudflare).
- Using the data is fine, including commercially. Credit the makers and link back to
https://vibeking.fun/product/{id}where you display their products.
Endpoints are permissive: valid requests return 200, and "empty" cases (unknown category, no search matches, missing q) also return 200 with zero-result payloads rather than errors. Always check count / data.length instead of relying on status codes.
The exception is /badge/{id}.svg, which returns 404 for an unknown or unapproved product id.
Ready-to-run clients in examples/:
curl.sh— shell one-liners for every endpointfetch.js— Node 18+ / browserfetch, top-10 leaderboard + client-side category filterrequests.py— Pythonrequests, same idea
- vibeking.fun — the live directory this API serves
- vibeking.fun/api — the hosted docs page, with a live "try it"
- 0xvibly/awesome-vibe-coded-apps — an awesome-list built from this API, regenerated daily by GitHub Actions
Built something with AI? Submit it to VibeKing — listings are free, get community upvotes, and come with an embeddable badge. Put that badge on your own site and your listing's outbound link becomes a followed (dofollow) link — see Verified Makers. Browse the current ranking at vibeking.fun/best.
MIT — this documentation and the example code. The directory data belongs to the respective product makers.