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

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

Pricing

from $1.60 / 1,000 url previews

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

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

Get title, description, preview image, favicon, site name, author, dates and Open Graph / Twitter tags for any list of URLs. JavaScript pages too. $2 per 1,000 URLs.

Pricing

from $1.60 / 1,000 url previews

Rating

0.0

(0)

Developer

Yukai Lin

Yukai Lin

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Give it URLs (as many as you like, in one run) and get the information you need to show a rich link preview or to catalogue pages:

  • 🏷️ Title and description (Open Graph first, then Twitter Card tags, then the HTML title and meta description)
  • 🖼️ Preview image (og:image / twitter:image, then schema.org JSON-LD) as an absolute URL
  • 🌐 Site name, page type, favicon, language, theme color, charset
  • ✍️ Author, published and modified time, publisher and logo, with a JSON-LD fallback when Open Graph tags are missing, and a sources object that says where each value came from (og, twitter, html or jsonld)
  • 👥 Social profiles: Facebook, X, LinkedIn, Instagram, YouTube, TikTok, GitHub, Pinterest, Threads, Trustpilot and Discord links found on the page (share buttons and posts are ignored)
  • 📰 RSS/Atom feeds, oEmbed endpoint, web app manifest, all icons (with sizes) and email addresses (mailto: links)
  • 🔗 Canonical URL, keywords, Twitter card type, JSON-LD types, and optionally the raw JSON-LD
  • 📦 All Open Graph and Twitter tags in one object

It works on protected sites too: pages are read over plain HTTP first (from a second network if a site blocks the first), with automatic fallback to a real browser when the request is refused. Choose Page fetching: Browser for pages whose preview tags are only added by JavaScript. When a page comes back without any preview, it is read again as a link-sharing crawler (facebookexternalhit), the way chat apps unfurl links. Requests identify themselves as TidyTools. Each URL you paste is read once, the way a chat app unfurls a link you share; nothing is crawled or followed, so robots.txt (a rule for crawlers) is not checked.

Use cases

  • Link previews in chat apps, CMSs, newsletters and bookmarking tools
  • Content curation: turn a list of links into cards with image, title, author, date and summary
  • Lead research: collect a company's social profiles, contact email and RSS feed from its home page
  • SEO and social checks: find pages with missing preview images or descriptions
  • AI agents: quickly understand what a URL is about without reading the whole page

How much does it cost?

EventPrice
URL preview$2.00 / 1,000 URLs

Example: 5,000 URLs that all return a preview cost 5,000 × $0.002 = $10.00 on the Free plan.

No start fee. Higher Apify plans get volume discounts (see the Pricing tab). URLs that fail, are blocked or are not HTML pages are not charged; they carry an errorType (not_found, blocked, timeout…).

Control your cost

  • Charged: one URL preview event per URL that returns a preview (success: true, charged: true).
  • Free (success: false, charged: false, the error ends with "(not charged)"):
    • invalid lines (errorType: "invalid_input"), one row per line (an empty list, a private/local address such as localhost or 169.254.169.254 also gives a free invalid_input row and the run still ends normally), and duplicate URLs (read once),
    • sites with an invalid or expired HTTPS certificate (errorType: "tls_error"),
    • login walls (login_wall: the site sent its login page instead of the content, e.g. Instagram),
    • pages with no preview metadata (no_metadata: no Open Graph title, description or image, and the title is missing or only the site name on a deep link, e.g. "Reddit" or "TikTok - Make Your Day"),
    • failed, blocked, timed-out and non-HTML URLs (blocked: the site refuses automated visitors with HTTP 401/403 or a bot check; we do not get around that).
  • Before it starts, the run logs its plan (number of URLs × price = the most it can cost) and compares it with your maximum charge per run (set in the run options). The plan is saved as costPlan in the SUMMARY record.
  • When the maximum is reached, the run stops cleanly: the status message says so, SUMMARY.status is LIMIT_REACHED and SUMMARY.notProcessed lists how many URLs were not read (and the first 100 of them), so you can run them again.
  • If Apify restarts the run (server migration or Resurrect), items already finished are skipped and not charged again (SUMMARY.resumedSkipped).

Price comparison (checked September 2026)

ActorPrice per 1,000 URLs (free plan)URLs per run
Link Preview & URL Metadata Extractor (this Actor)$2, no start feeUp to 100,000
njoylab/url-summary-scraper$101
easyapi/url-metadata-crawler$3 + $0.09 start fee + platform usage1
technicaldost/link-preview-api$2 + $0.001 start fee; the max charge per run must be set to at least $1—
ntriqpro/metascraper-actor$1 + $0.01 start fee + platform usage; the max charge per run must be set to at least $0.10—
dataquarry/website-seo-metadata-checkerFree (SEO-focused meta tag checks)—

"—" = not stated in the listing we checked. "Platform usage" means you also pay the Apify compute the run uses; with this Actor it is included in the event price.

vs Apify Web Fetch: Web Fetch returns the whole page (Markdown, HTML or links) for an agent to read. This Actor returns small, structured preview fields (title, image, author, dates, logo, social profiles, feeds) with a sources object, which is cheaper in tokens when you only need to know what a link is.

How to use it

  1. Paste your links into URLs or domains, one per line: full URLs or bare domains like stripe.com. A bad line never stops the run: it becomes a row with errorType: "invalid_input" (not charged). To upload or link a text or CSV file of links, use the URL list files or request list field (every http(s) URL in the file is read; a file of bare domains is read one per line).
  2. Click Start.
  3. Export the results as JSON, CSV or Excel, or call the Actor from the API.

Input example

This is the input the form is prefilled with; a run with it takes about a minute and costs only cents:

{
"urlList": [
"https://github.com/apify/crawlee",
"https://www.bbc.com/news"
]
}

Output example (real result, September 2026)

A news article whose Open Graph tags have no dates: publishedTime, modifiedTime, publisher and logo come from its JSON-LD, and the X profile from its twitter:site tag.

{
"input": "https://www.theverge.com/tech/1001797/nothings-headphone-1-pro-review",
"inputUrl": "https://www.theverge.com/tech/1001797/nothings-headphone-1-pro-review",
"inputIndex": 0,
"url": "https://www.theverge.com/tech/1001797/nothings-headphone-1-pro-review",
"success": true,
"title": "The Nothing Headphone 1 Pro put you in the studio",
"description": "Nothing’s new flagship headphones surprised me.",
"image": "https://platform.theverge.com/wp-content/uploads/sites/2/2026/09/268785_Nothing_pro_1_headphones_JHIGGINS_1.jpg?quality=90&strip=all&...",
"siteName": "The Verge",
"type": "article",
"author": "John Higgins",
"publishedTime": "2026-09-29T01:00:00+00:00",
"modifiedTime": "2026-09-29T01:00:00+00:00",
"publisher": "The Verge",
"logo": "https://platform.theverge.com/wp-content/uploads/sites/2/2025/01/verge-placeholder_f212b3.png?...",
"lang": "en-US",
"twitterCard": "summary_large_image",
"structuredDataTypes": ["NewsArticle", "BreadcrumbList"],
"socialProfiles": {
"tiktok": "https://www.tiktok.com/@verge",
"youtube": "https://www.youtube.com/theverge",
"instagram": "https://www.instagram.com/verge",
"facebook": "https://www.facebook.com/verge",
"threads": "https://www.threads.net/@verge",
"x": "https://x.com/verge"
},
"feeds": [{ "url": "https://www.theverge.com/rss/index.xml", "type": "application/rss+xml", "title": "The Verge" }],
"oembedUrl": null,
"icons": [{ "href": "https://www.theverge.com/static-assets/icons/apple-touch-icon.png", "rel": "apple-touch-icon", "sizes": "180x180" }, "..."],
"charset": "utf-8",
"emails": [],
"sources": { "title": "og", "description": "og", "image": "og", "author": "html", "publishedTime": "jsonld", "modifiedTime": "jsonld", "siteName": "og", "publisher": "jsonld", "logo": "jsonld" },
"httpStatus": 200,
"mode": "fast",
"via": "backend",
"charged": true
}

A login wall (real result, September 2026). It is not charged:

{
"input": "https://www.instagram.com/nasa/",
"inputUrl": "https://www.instagram.com/nasa/",
"url": "https://www.instagram.com/nasa/",
"finalUrl": "https://www.instagram.com/accounts/login/",
"title": "Login • Instagram",
"success": false,
"errorType": "login_wall",
"error": "the site sent a login page instead of the content (https://www.instagram.com/accounts/login/) (not charged)",
"charged": false
}

A product page also returns its oEmbed endpoint and contact email, e.g. Allbirds: "oembedUrl": "https://www.allbirds.com/products/mens-tree-runners.oembed", "emails": ["help@allbirds.com"].

Fields the page does not provide are null (or empty lists). Every row keeps your original line in input / inputUrl (and its position in inputIndex), so you can match results back to a spreadsheet; url is the address that was read (bare domains get https://). When the same URL appears more than once it is read and charged once, and the row lists every original line in inputs. via tells you where the page was read from: backend (our servers), direct (Apify's network), direct-unfurl (Apify's network as a link-sharing crawler) or browser. A SUMMARY record in the key-value store has the run status (SUCCESS, PARTIAL_RESULTS, FAILED, NO_RESULTS, LIMIT_REACHED), failure counts by errorType, invalidInputs, duplicatesMerged, costPlan and, when the run stopped at your limit, notProcessed.

Use with AI agents (MCP)

Connect Apify's MCP server (https://mcp.apify.com?tools=tidytools/link-preview-metadata) to Claude, Cursor or any MCP client, then ask e.g. "Get the title, image, author and social profiles for these 20 links."

{ "urlList": ["https://github.com/apify/crawlee", "stripe.com"] }

Failed URLs are not charged and carry an errorType.

Use it from code

curl -X POST "https://api.apify.com/v2/acts/tidytools~link-preview-metadata/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urlList":["https://github.com/apify/crawlee","stripe.com"]}'

Use urlList (a plain list of strings). The older urls field ([{"url": "https://…"}]) still works, but Apify rejects the whole request with HTTP 400 if one of its entries is a bare domain or a blank line; urlList accepts anything and reports bad lines as rows instead.

Schedules and integrations: run it daily or weekly with Apify Schedules, get a webhook when a run finishes, or send the results to Zapier, Make, n8n, Google Sheets, Slack and other apps with Apify integrations. Results can be exported as JSON, CSV, Excel or XML.

Advanced settings

  • Plain HTTP requests from: Auto (recommended) reads pages from our servers and retries from Apify's network when a site blocks data-center requests, before falling back to a browser.
  • Read social links as a link-sharing crawler: Auto (recommended) reads pages with our own user agent (TidyToolsFetch/1.0; in browser mode a real browser's user agent with TidyTools/1.0 added) and, when a page has no preview or shows a login page, asks again as facebookexternalhit from Apify's network. You can also send facebookexternalhit or Twitterbot first, or turn the retry off. No extra charge.
  • Time limit per URL: default 120 seconds, all retries included. Slower URLs get errorType: "timeout" and are not charged. 0 = no limit.
  • HTTP 429 (Too Many Requests): a URL that is rate-limited on every route is read once more after a short wait, inside the time limit. If it still answers 429, the row has errorType: "rate_limited" and is not charged.
  • Proxy: optional Apify Proxy for requests sent from Apify's network (billed to your Apify account).

Limitations

  • Only public http/https pages. Sites that show a login page instead of a preview (e.g. many Instagram profiles) return a free login_wall row.
  • Some sites show their login page to data-center networks whatever the user agent. Instagram profiles are inconsistent: in our September 2026 test they returned the login page from Apify's network (reported as login_wall, not charged), while a test run in October 2026 got the public profile preview (title, picture); expect either result. We have not tested this with a residential proxy.
  • Only HTML pages are previewed: PDFs, images and JSON endpoints return a free unsupported row ("not an HTML page"). Sites that refuse automated visitors on every route (HTTP 401/403 or a bot check, e.g. some Chinese portals) return a free blocked row that says so; the Actor identifies itself honestly and does not bypass bot protection.
  • The image URL of some sites (Instagram, X) is a signed or size-limited CDN link that can expire; download it soon if you need to keep it. A TikTok profile returned a full preview through the crawler retry.
  • Values come from what the page declares (meta tags, links and JSON-LD); pages without them have fewer fields.
  • Social profiles are the links the page shows; a site that links to someone else's profile (e.g. an embedded post author) can appear too.

Responsible use

  • The Actor reads only the public metadata of a page you give it (title, description, image, and the author or byline the page itself publishes). It does not log in and does not build profiles of people.
  • An author byline is the name the publisher shows on the page; keep it only when you need it (for example to credit an article) and follow the data-protection laws that apply to you.

FAQ

Does the Actor collect usage data? The Actor sends one anonymous usage counter per run (input type, item count range, outcome) to improve the tool; no URLs, content or account data.

Which Open Graph and meta tags does it read, and how is the OG image found? Title and description come from Open Graph first, then the Twitter Card tags, then the HTML title and meta description. The preview image comes from og:image / twitter:image, then schema.org JSON-LD, and is returned as an absolute URL. All Open Graph and Twitter tags are also returned in one object, and a sources object says where each value came from (og, twitter, html or jsonld).

Does it work on JavaScript-heavy or protected sites? Yes. Pages are read over plain HTTP first (from a second network if a site blocks the first), with automatic fallback to a real browser when the request is refused (preview tags that only JavaScript adds need Browser); Page fetching (HTTP or browser) lets you choose Auto, HTTP only or Browser. When a page has no preview or shows a login page, Read social links as a link-sharing crawler reads it again as facebookexternalhit at no extra charge, but some sites (e.g. Instagram profiles) still return a login page, reported as login_wall and not charged.

Does it check robots.txt? No. robots.txt is a rule for crawlers, and this Actor does not crawl: it reads only the URLs you paste, once each, like a chat app showing a link preview, and it never follows links. Every request names TidyTools in its user agent, except the optional link-sharing crawler retry described above.

What is charged and what is free? You pay $2.00 per 1,000 URLs, one URL preview event per URL that returns a preview, with no start fee. Invalid lines, duplicate URLs, login walls, pages with no preview metadata (no_metadata), and failed, blocked, timed-out, bad-certificate or non-HTML URLs (PDFs, images) are free; every row has charged: true or false. A page with only an HTML title (e.g. example.com) still counts as a preview and is charged; a page with nothing usable is no_metadata and free.

Can I use it as a link preview API or run it on a schedule? Yes. Call it from code through the Apify API (run-sync-get-dataset-items) with your Apify API token and a plain urlList of URLs or bare domains, or connect it to AI agents through Apify's MCP server. You can also run it daily or weekly with Apify Schedules, get a webhook when a run finishes, or send results to Zapier, Make, n8n, Google Sheets or Slack.

More tools by TidyTools that work well with this one:

Support

Open an issue in the Issues tab with the URL. Issues are checked regularly.