For editors & no-backend apps · Editor.js, Tiptap, BlockNote

Link previews from the browser. No backend, no CORS errors.

Call one GET from your frontend with a publishable pk_ key and get title, description, image, favicon and oEmbed as JSON. YouTube works too: we fetch server-side with oEmbed, so you don't hit the bot walls that block scrapers on cloud servers. Free 500 requests/month, commercial use OK.

const r = await fetch("https://unfurlr.onrender.com/v1/metadata?key=pk_YOUR_KEY&url=" + encodeURIComponent("https://github.com")); const { title, images, favicon } = await r.json();
{ "title": "GitHub · Build and ship software",
  "images": ["https://github.githubassets.com/…/og.png"],
  "favicon": "https://github.com/favicon.ico" }

pk_ keys only work from the origins you allow. curl, Python and Next.js are in the Quickstart.

Why this exists: browsers block fetching other sites (CORS) · Editor.js LinkTool needs a backend endpoint · YouTube returns empty tags to cloud servers

No credit card · CORS enabled · GET /v1/metadata?url=…

Live · no signup

Try it on any URL

Paste any URL and see the preview card plus the raw JSON.

Built forReactNext.jsVueSvelteEditor.jsNodePythonany HTTP client
Free tool

See how your link looks on X, Slack and iMessage

Paste a URL and see the three preview cards side by side, before you post it. No signup.

Open the link checker →

Get a free API key

500 requests/month. Commercial use OK. No credit card. One click, key shown right away.

How it works

URL in. Preview out.

One request: we fetch the page server-side, parse it, and hand back JSON you can render as a card.

Quickstart

Quickstart

Authenticate with Authorization: Bearer $KEY or X-API-Key: $KEY.

curl "https://unfurlr.onrender.com/v1/metadata?url=https://github.com" -H "Authorization: Bearer $KEY"
# or -H "X-API-Key: $KEY"
curl -X POST https://unfurlr.onrender.com/v1/metadata/batch -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" -d '{"urls":["https://a.com","https://b.com"]}'
Features

Why unfurlr

The boring parts of link previews, handled.

500free requests / month
10URLs per batch call
24hresult cache
1GET request per preview

Works from the browser

CORS stops your frontend from fetching other sites. We fetch server-side, and this API allows CORS.

Handles messy HTML

Falls back from OG to Twitter tags to plain HTML. Relative image paths come back absolute. oEmbed is discovered automatically.

Batch built in

POST /v1/metadata/batch takes up to 10 URLs.

Predictable

One URL = one request. Hard monthly cap, so no surprise bills.

Safe

Private and internal addresses are blocked (SSRF protection). Errors are clear: timeout, blocked, non-HTML, upstream 4xx/5xx.

Usage at a glance

Check GET /v1/usage, or read the X-Quota-Remaining response header.

v1 reads server-rendered HTML and does not run JavaScript.

Pricing

Pricing

One plan while we're early. It's free.

Free: 500 requests/month

$0 / month
  • 500 requests/month
  • Commercial use is OK
  • No card needed
  • Batch requests included; each URL counts as one request
  • Failed fetches don't count
Get a free API key

Status: checking…

Need always-on or higher limits?

Leave your email and we'll let you know if we add them. Interest list only: no account, no payment, nothing charged. The free plan stays free.

FAQ

FAQ

Does it run JavaScript on the page?

No. v1 reads server-rendered HTML and does not run JavaScript.

What counts as a request?

One URL = one request, including each URL in a batch. Failed fetches don't count.

What happens when I hit the limit?

There's a hard monthly cap, so no surprise bills. Check GET /v1/usage or the X-Quota-Remaining header.

Can I call it from my frontend?

Yes. The API allows CORS, so you can call it directly from the browser.

Can my site opt out of being fetched?

Yes. See About our crawler for how to opt out.

How does this stay free / will it disappear like other free proxies?

unfurlr is built and run by one person, Smaranjeet. It runs on a free hosting tier with a monthly bandwidth cap. When the cap is reached, the API shows an at-capacity message instead of going down, and URLs that are already cached keep working. The server sleeps when idle, so the first request after a quiet period can take about a minute. The current state is on the status endpoint.

How do I give feedback?

This is an early launch. Tell us what breaks, what's missing, or what you'd pay for: smaran+unfurlr@mail.grokbot.com.

Ship link previews today.

Free key in one click. No card, no SDK, just JSON.