Link Preview API - Open Graph, Meta Tags, URL Metadata avatar

Link Preview API - Open Graph, Meta Tags, URL Metadata

Pricing

from $0.70 / 1,000 results

Go to Apify Store
Link Preview API - Open Graph, Meta Tags, URL Metadata

Link Preview API - Open Graph, Meta Tags, URL Metadata

No API key, no login. Send up to 50 URLs and get a clean link preview row for each: title, description, image, site name, favicon, type, language, canonical, author, published time, Twitter card, oEmbed endpoint and JSON-LD types. Image, PDF and video URLs get a header preview. Every failure is a ro

Pricing

from $0.70 / 1,000 results

Rating

0.0

(0)

Developer

Martin Petrov

Martin Petrov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

Features

Limited permissions

Share

Problem: your chat, CMS, newsletter, bookmark or AI agent needs a card for a pasted URL, and every site hides its title, image and description in different tags. Parsing them yourself means redirects, charsets, relative image paths and sites that point at private addresses.

This API: up to 50 URLs per call, fetched in parallel, one clean row per URL:

  • Card fields: title (og:title, then twitter:title, then the page title), description, image (absolute URL, og:image, then twitter:image, then the first large image), imageWidth / imageHeight when the page declares them, siteName, favicon (absolute URL).
  • Page details: type, locale, lang, canonical, author, publishedTime, modifiedTime when the page declares them (meta tags or schema.org JSON-LD), themeColor, twitterCard, twitterSite, twitterCreator.
  • Discovery: oembedUrl (the oEmbed endpoint the page declares) and jsonLdTypes (schema.org types such as Article, Product, Organization).
  • Redirects: finalUrl after up to 5 redirects, redirected flag, httpStatus, contentType.
  • Non-HTML URLs: an image URL previews as the image itself, a PDF, video or audio URL gets a title from the file name and a type from the headers.

Why it is different

  • Every failure is a row, never a silent empty result. status is ok, partial (page fetched, no title found) or error, and error is a code: http_403, http_404, timeout, dns_error, tls_error, connection_failed, blocked_by_robots, blocked_private_address, blocked_port, unsupported_scheme, too_many_redirects, empty_response, invalid_url.
  • Safe to expose to your users. Only http and https on ports 80, 443, 8080 and 8443. The host is resolved and every address must be public; private, loopback, link-local, carrier-grade NAT, multicast, reserved and IPv6-local addresses are refused, the check is repeated on every redirect hop, and the connection goes to the address that was checked.
  • Fast. URLs are fetched in parallel; at most each page is read up to 128 KB past its head tag (1 MB hard cap) with 8 second timeouts.
  • Honest crawler. Identifies itself as RadarLinkPreview/1.0, respects robots.txt, no proxies, no logins.
  • Monitor mode: onlyNew: true + monitorId returns only URLs whose preview is new or changed.

Example (API)

curl -X POST "https://api.apify.com/v2/acts/martin10291~link-preview-open-graph/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls": ["https://example.com", "https://en.wikipedia.org/wiki/Bulgaria"]}'

Output row (trimmed):

{"url": "https://en.wikipedia.org/wiki/Bulgaria", "finalUrl": "https://en.wikipedia.org/wiki/Bulgaria",
"status": "ok", "httpStatus": 200, "title": "Bulgaria - Wikipedia",
"description": "Bulgaria is a country in Southeast Europe.",
"image": "https://upload.wikimedia.org/wikipedia/commons/example.png", "siteName": "Wikipedia",
"favicon": "https://en.wikipedia.org/static/favicon/wikipedia.ico", "type": "website", "lang": "en",
"canonical": "https://en.wikipedia.org/wiki/Bulgaria", "jsonLdTypes": ["Article"],
"contentType": "text/html", "redirected": false, "error": null, "checkedAt": "2026-11-12T10:00:00Z"}

A blocked URL looks like this:

{"url": "http://169.254.169.254/latest/meta-data/", "status": "error", "error": "blocked_private_address", "title": null}

Schedule and monitor

Run it on a schedule (hourly or daily) with onlyNew: true and a monitorId such as my-links. The first run returns every URL; later runs return one row per URL whose title, description, image, canonical or type changed, with change set to first_check or changed. Errors are always returned (change: error). Chain it with a webhook to refresh the cards in your app only when a page changed.

Use from agents (MCP)

Add the Apify MCP server (https://mcp.apify.com?tools=martin10291/link-preview-open-graph) to Claude, Cursor or any MCP client and ask: "Give me the title, description and image of these links: ...".

Input

FieldWhat it does
urlsURLs to preview, up to 50 (a single url also works)
onlyNew / monitorIdReturn only URLs whose preview is new or changed for this Monitor ID

Honest limits

  • No JavaScript rendering. A single-page app that writes its tags with JavaScript returns what the server sends; those pages can come back partial.
  • Pages that block automated requests (login walls, bot checks, HTTP 403) return an error row. We do not use proxies or evade bot checks.
  • robots.txt is respected. A URL disallowed for our user agent returns blocked_by_robots.
  • The page is read up to 128 KB past the end of its head section (hard cap 1 MB); tags placed after that are not seen.
  • Favicon falls back to /favicon.ico of the site when the page declares none; that file is not fetched to confirm it exists.
  • author and publishedTime are returned only when the page declares them.

FAQ

Pricing? $1.00 per 1,000 result rows (one row per URL, or per new or changed URL in monitor mode). Do I need a key? No. What happens with localhost or an internal IP? The row comes back with blocked_private_address; nothing is fetched. Is the data cached? No. Every call fetches the page live.