Link Preview API - Open Graph, Meta Tags & URL Metadata
Pricing
from $1.60 / 1,000 url previews
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
What does Link Preview API do?
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
sourcesobject that says where each value came from (og,twitter,htmlorjsonld) - 👥 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?
| Event | Price |
|---|---|
| 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 previewevent per URL that returns a preview (success: true,charged: true). - Free (
success: false,charged: false, theerrorends with "(not charged)"):- invalid lines (
errorType: "invalid_input"), one row per line (an empty list, a private/local address such aslocalhostor169.254.169.254also gives a freeinvalid_inputrow 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).
- invalid lines (
- 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
costPlanin theSUMMARYrecord. - When the maximum is reached, the run stops cleanly: the status message says so,
SUMMARY.statusisLIMIT_REACHEDandSUMMARY.notProcessedlists 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)
| Actor | Price per 1,000 URLs (free plan) | URLs per run |
|---|---|---|
| Link Preview & URL Metadata Extractor (this Actor) | $2, no start fee | Up to 100,000 |
| njoylab/url-summary-scraper | $10 | 1 |
| easyapi/url-metadata-crawler | $3 + $0.09 start fee + platform usage | 1 |
| 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-checker | Free (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
- 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 witherrorType: "invalid_input"(not charged). To upload or link a text or CSV file of links, use the URL list files or request list field (everyhttp(s)URL in the file is read; a file of bare domains is read one per line). - Click Start.
- 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 withTidyTools/1.0added) and, when a page has no preview or shows a login page, asks again asfacebookexternalhitfrom Apify's network. You can also sendfacebookexternalhitorTwitterbotfirst, 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/httpspages. Sites that show a login page instead of a preview (e.g. many Instagram profiles) return a freelogin_wallrow. - 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
unsupportedrow ("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 freeblockedrow 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.
Related Actors
More tools by TidyTools that work well with this one:
- Sitemap URL Extractor: list every URL a site publishes in its sitemaps
- SEO Audit Crawler: audit titles, links, speed and structured data across a whole site
- Broken Link Checker: find 404 and dead links on any website
- Bulk URL Status Checker: check HTTP status and redirects for a list of URLs
Support
Open an issue in the Issues tab with the URL. Issues are checked regularly.