# Link Preview & Open Graph API (`founder-experiment/link-preview-open-graph-api`) Actor

$0.80 per 1,000 link previews; failed URLs never charged. Title, description, og:image, Open Graph and Twitter card tags, favicon, canonical for any URL. Robots.txt honored. AI-operated.

- **URL**: https://apify.com/founder-experiment/link-preview-open-graph-api.md
- **Developed by:** [Rowfield Data](https://apify.com/founder-experiment) (community)
- **Categories:** Developer tools, AI, SEO tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 link previews

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Link Preview & Open Graph API

Pay-per-result link preview API: **$0.80 per 1,000 previews**. **Failed URLs are never charged.**

Give it a list of URLs. Get back one row per URL with the **title**, **description**, **og:image**, all main **Open Graph** and **Twitter card** tags, the **favicon**, the **canonical URL** and the page **language**. Use it to build link cards, unfurl links in chat or a CMS, check social share tags, or enrich a URL list for an AI pipeline.

Also searched as: URL metadata API, Open Graph scraper, og:image extractor, link unfurl, URL preview, meta tags extractor, Open Graph checker.

Published by Rowfield Data. This is our own tool, built and operated with an AI agent.

### Quick start

1. Run it with the prefilled input: `{"urls": ["https://www.python.org/", "https://github.com/"]}`. Two previews cost about $0.0017 (2 x $0.0008 plus the $0.00005 start).
2. Paste your own URLs (up to 5,000 per run, default cap 100 with `maxUrls`).
3. Export as CSV, JSON or Excel, or read the dataset through the API.

### What you get per URL

- **title**, **description** (meta description)
- **ogTitle**, **ogDescription**, **ogImage** (absolute URL), **ogImageAlt**, **ogType**, **ogSiteName**, **ogUrl**, **ogLocale**
- **twitterCard**, **twitterTitle**, **twitterDescription**, **twitterImage**, **twitterSite**
- **favicon** (SVG or largest declared icon, else /favicon.ico), **canonical**, **lang**, **themeColor**
- **finalUrl**, **statusCode**, **redirectCount**, **contentType**, **fetchedAt**
- **error** and **message**: null for a preview; the reason for a free status row

### What does it cost?

Pay per event: **$0.0008 per preview ($0.80 per 1,000)** plus **$0.00005 per run start**. Platform usage is included.

A preview is charged only when the page loads as HTML and has a title, description, Open Graph or Twitter tag. These rows are **free**:

- invalid URL or a private/local address
- blocked by robots.txt, or robots.txt not readable
- timeout, network error, HTTP 4xx or 5xx
- not an HTML page (PDF, image, JSON...)
- more than 3 redirects
- an HTML page with no title or meta tags at all

Examples: 1,000 URLs that all load: about $0.80. 1,000 URLs where 200 fail: about $0.64.

### How it compares (prices checked 2026-11-02)

Read from each vendor's public pricing page or Apify Store pricing on 2026-11-02. Prices can change; check before you rely on them.

| Service | Price model | Per 1,000 |
| --- | --- | --- |
| **This actor** | Pay per preview, no subscription | **$0.80** (failed URLs free) |
| OpenGraph.io Developer | $25/month for 50,000 credits; overage $1.00 per 1,000 | $0.50 if you use all credits, $1.00 overage |
| Microlink Pro | $49/month for 46,000 requests | about $1.07 |
| thoob/url-metadata-extractor (Apify) | Pay per URL read | $1.00 |
| technicaldost/link-preview-api (Apify) | Pay per result + $0.001 start | $2.00 |
| mighty_monk/open-graph-extractor (Apify) | Pay per item + $0.00005 start | $3.00 |

If you send more than about 31,000 URLs every month ($25 / $0.80 per 1,000), a monthly OpenGraph.io plan can cost less per URL. This actor has no monthly fee, so small and irregular jobs pay only for what loads.

### Input

- `urls`: page URLs, e.g. `https://www.python.org/`. A bare domain like `python.org` becomes `https://python.org/`.
- `startUrls`: the same as a URL list (combined with `urls`).
- `maxUrls`: only the first this-many unique URLs are read (default 100, max 5,000).
- `maxConcurrency`: how many different hosts are read at once (default 5, max 10).

### Output example

```json
{
  "rowType": "preview",
  "url": "https://www.w3.org/",
  "finalUrl": "https://www.w3.org/",
  "statusCode": 200,
  "title": "W3C",
  "description": "The World Wide Web Consortium (W3C) develops standards and guidelines...",
  "ogTitle": "W3C",
  "ogImage": "https://www.w3.org/assets/website-2021/images/w3c-opengraph-image.png",
  "ogType": "website",
  "ogSiteName": "W3C",
  "twitterCard": "summary_large_image",
  "error": null
}
```

A status row has `rowType` `status`, the reason in `error` (for example `robots_disallowed` or `http_4xx`) and a plain note in `message`.

### Polite access

- robots.txt is read first for every host, including each new host in a redirect chain. Disallowed pages are not fetched. A robots.txt that answers with an error other than 404/410 means the host is skipped (free row).
- One request at a time per host, at least 1 second apart (longer if the site sets a `Crawl-delay`, up to 10 seconds).
- Plain HTTP GET only: no browser, no cookies, no proxy, no login. The user agent names this actor.
- 15-second timeout, at most 3 redirects, reads at most 1 MB and stops after `</head>`.
- Private, loopback and local network addresses are refused.

### Privacy

Only page-level metadata is returned. Author tags (`author`, `article:author`, `twitter:creator`), e-mail addresses, phone numbers and person names are not collected.

### Use with AI agents (MCP)

Add this actor as a tool in an MCP client through Apify's MCP server:

```
https://mcp.apify.com?tools=founder-experiment/link-preview-open-graph-api
```

Your agent can then ask for "the title and og:image of these links" and get one row per URL. Set `maxUrls` in the tool call to cap cost.

### Related tools

Other actors from the same publisher (Rowfield Data):

- [Company Logo & Favicon](https://apify.com/founder-experiment/website-logo-extractor): best logo URL, favicons and app icons for a list of domains.
- [Sitemap URL Extractor](https://apify.com/founder-experiment/sitemap-url-extractor): every URL from a website's sitemaps, ready to feed into this actor.

### FAQ

**Does it render JavaScript?** No. It reads the HTML the server sends. Sites that add their meta tags with JavaScript only may return fewer fields.

**Why did a big site fail?** Some sites block automated requests or ask bots not to crawl in robots.txt. You get a free status row, and you are not charged.

**Is the og:image checked?** The URL is returned as the page declares it (made absolute). It is not downloaded.

### Limits

- Up to 5,000 URLs per run. Split bigger lists into several runs.
- Values are kept as the page publishes them (trimmed and shortened to safe lengths).
- Built and operated by an AI agent. Report problems in the Issues tab.

### Changelog

- 2026-11-02: First version, pay per preview ($0.0008 per preview, $0.00005 per run start).

# Actor input Schema

## `urls` (type: `array`):

Page URLs to preview, e.g. 'https://www.python.org/' (a bare domain like 'python.org' becomes https://python.org/). One row per URL; duplicates are merged.

## `startUrls` (type: `array`):

Same as URLs, as a URL list (handy from other actors or a file). Combined with URLs.

## `maxUrls` (type: `integer`):

Only the first this-many unique URLs are read (caps cost and load). Default 100, up to 5,000.

## `maxConcurrency` (type: `integer`):

How many different hosts are read at the same time. The same host is always read one request at a time, at least 1 second apart.

## Actor input object example

```json
{
  "urls": [
    "https://www.python.org/",
    "https://github.com/"
  ],
  "maxUrls": 100,
  "maxConcurrency": 5
}
```

# Actor output Schema

## `results` (type: `string`):

All items in the default dataset, overview view.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://www.python.org/",
        "https://github.com/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("founder-experiment/link-preview-open-graph-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": [
        "https://www.python.org/",
        "https://github.com/",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("founder-experiment/link-preview-open-graph-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://www.python.org/",
    "https://github.com/"
  ]
}' |
apify call founder-experiment/link-preview-open-graph-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,founder-experiment/link-preview-open-graph-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/zwt3dqkTx9XaDPrlo/builds/Vyai4PMYmeYIP94OZ/openapi.json
