# Open Graph Metadata Checker (`automation-lab/open-graph-metadata-validator`) Actor

Check supplied public web pages for Open Graph title, description, image, canonical URL and missing social-preview tags. Export one status row per page.

- **URL**: https://apify.com/automation-lab/open-graph-metadata-validator.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.49 / 1,000 page checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Open Graph Metadata Checker

Check public web pages for declared Open Graph tags and canonical links. This open graph checker exports one row per URL, including fetch status, resolved image URL, declared image dimensions, missing fields, and validation warnings. Use it to catch broken social previews before publishing or to review a recurring editorial batch.

### Who is this for?

SEO teams reviewing campaign landing pages, editors checking documentation releases, and developers validating metadata changes across multiple public URLs. Supply the exact pages you want inspected; this Actor does not discover pages or crawl a whole website.

### Why use it?

A spreadsheet of URLs is hard to audit manually. Each run produces consistent typed rows, including an explicit HTTP/non-HTML/network failure status rather than treating a blocked page as missing metadata. Relative OG image and canonical links resolve against the fetched page URL. Duplicate declarations and missing core fields are called out separately.

### What data is returned?

| Field | Meaning |
| --- | --- |
| `sourceUrl`, `finalUrl` | Requested URL and last reached URL after redirects |
| `httpStatus`, `fetchStatus` | HTTP code and `ok`, `http_error`, `non_html`, or `network_error` |
| `validationStatus` | `valid`, `warnings`, or `fetch_failed` |
| `ogTitle`, `ogDescription`, `ogImage`, `ogUrl`, `ogType` | Declared Open Graph fields; URLs resolved against the final page |
| `ogImageWidth`, `ogImageHeight` | Positive integer dimensions declared in tags, **not** measured from image bytes |
| `canonicalUrl` | Resolved HTML canonical link, if present |
| `missingFields`, `warnings` | Missing OG fields and duplicate/invalid/fetch findings |
| `checkedAt` | UTC time of the check |

Absent values are `null`. No image bytes are fetched: an `ogImage` value is a resolved URL, not proof that the image loads or meets social platform crop requirements.

### Getting started

1. Add one or more public HTTP(S) pages under **Public page URLs**.
2. Set **Maximum pages** to cap the number of distinct URLs inspected.
3. Run the Actor and open the default dataset's **Open Graph checks** view.
4. Filter `validationStatus=warnings`, inspect `missingFields`, and fix the source HTML. Schedule another run to check the same URLs after deployment.

For example:

```json
{"startUrls":[{"url":"https://github.com/"},{"url":"https://nodejs.org/en"}],"maxItems":2}
```

### Input parameters

`startUrls` is required (1–10,000 entries). Each entry is a URL object in the Console or a URL string through the API. Duplicate exact URLs are checked once in input order. `maxItems` defaults to 10 and is capped at 10,000. Private/local targets and credential-bearing URLs are rejected. A single blocked page produces a status row so the rest of the batch can proceed.

### Example output

A local run against `https://nodejs.org/en` returned an `ok` fetch, title `Node.js — Run JavaScript Everywhere`, and `missingFields` containing `og:url` and `og:type`. Actual metadata can change on the source site; a status of `warnings` means the page was fetched but one or more declared fields failed the validation checks.

### Validation rules

The core fields checked are `og:title`, `og:description`, `og:image`, `og:url`, and `og:type`. Empty tags count as missing. The first value wins when a field is repeated; duplicates add a warning. Relative image, OG URL and canonical values resolve to absolute HTTP(S) URLs. Canonical is exported independently and is not a substitute for a missing `og:url`.

### How much does it cost to check Open Graph metadata on web pages?

The Actor charges a $0.001 one-time `start` event and a per-page `item` event for successfully parsed HTML pages. At the BRONZE spend tier an item is $0.00248: one successful page costs an estimated $0.00348, five cost $0.0134, and 25 cost $0.063. FREE is $0.002852/item; SILVER $0.0019344/item; GOLD, PLATINUM and DIAMOND $0.001488/item. Spend tiers depend on your total qualifying monthly Store spend, not how many pages you submit here. A failed HTTP fetch still produces a status row but has no item charge. The active Apify Console pricing panel is authoritative. Costs and payouts are estimates and can be affected by refunds, fraud, disputes, taxes, corrections and clawbacks.

### Integrations and repeat checks

Schedule the same URL list after each content deployment. Export the default dataset to CSV for editorial review, or use the Apify API or Make/Zapier to compare `missingFields` between runs keyed by `sourceUrl`. This Actor emits point-in-time checks; it does not retain prior values, send alerts, or monitor sites between scheduled runs.

### Output automation tips

For a recurring editorial review, keep the same URL list in a scheduled Task and compare successive datasets by `sourceUrl`. Treat a `fetch_failed` row as an access diagnostic, not an OG regression. A page can declare an image URL whose content is unavailable; this checker deliberately does not verify image bytes or Facebook/LinkedIn cache state.

### Run through the API

```bash
curl -X POST 'https://api.apify.com/v2/acts/automation-lab~open-graph-metadata-validator/runs?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"startUrls":[{"url":"https://github.com/"}],"maxItems":1}'
```

JavaScript:

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/open-graph-metadata-validator').call({
  startUrls: [{ url: 'https://github.com/' }], maxItems: 1,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Python:

```python
from apify_client import ApifyClient
import os
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/open-graph-metadata-validator').call(
    run_input={'startUrls': [{'url': 'https://github.com/'}], 'maxItems': 1})
print(client.dataset(run['defaultDatasetId']).list_items().items)
```

### Use with MCP

Expose this Actor to Claude Code through Apify MCP:

```bash
claude mcp add --transport http apify \
  'https://mcp.apify.com?tools=automation-lab/open-graph-metadata-validator'
```

Claude Desktop, Cursor, and VS Code MCP clients can use an HTTP server configuration like this (supply Apify authentication through your client):

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/open-graph-metadata-validator"}}}
```

Example prompts: “Check the Open Graph title and image on github.com and list any missing tags.” “Compare the missing OG fields on the Node.js documentation and GitHub Docs homepages.”

### Legality and responsible use

Only anonymously accessible public HTML pages are supported. Some domains return 403, rate-limit automated requests, or render metadata in JavaScript after navigation; these return a fetch status or missing fields, not a guaranteed platform preview. HTML bodies over 2 MB are rejected. Redirects are capped at five; request timeouts are bounded. Respect the target's terms, robots policies, and rate limits. Do not use this Actor to probe private networks or process URLs with credentials.

### FAQ and troubleshooting

**Why is the title missing?** Inspect the original HTML response for a nonempty `<meta property="og:title" content="...">`. An ordinary `<title>` is not silently substituted.

**Why is a page marked fetch\_failed?** Inspect `httpStatus`, `fetchStatus` and `warnings`. A site may block anonymous HTTP or serve a non-HTML response. Retry after confirming the URL is publicly accessible; do not interpret a blocked response as missing OG tags.

### Data handling

The Actor reads only the supplied public URLs and writes the parsed metadata and request status to the run's default dataset. It does not request credentials or use an external AI provider. Apify storage retention follows your account settings; delete runs and datasets using the Console or API when no longer needed. Avoid submitting confidential URL paths, query tokens, or personal data in page addresses.

### Related tools

For Twitter-specific card fields, see [Twitter Card Metadata Validator](https://apify.com/automation-lab/twitter-card-metadata-validator). For sitemap syntax and location checks, see [XML Sitemap Validator](https://apify.com/automation-lab/xml-sitemap-validator). Neither substitutes for the page-level Open Graph output here.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/open-graph-metadata-validator/changelog.md

# Actor input Schema

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

HTTP(S) page URLs to check. Private hosts and credential-bearing URLs are rejected. Duplicate URLs are checked once.

## `maxItems` (type: `integer`):

Maximum number of distinct URLs to check in this run, in supplied order.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://github.com/"
    },
    {
      "url": "https://www.npmjs.com/"
    }
  ],
  "maxItems": 10
}
```

# Actor output Schema

## `overview` (type: `string`):

Default dataset of one Open Graph check per supplied URL.

# 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 = {
    "startUrls": [
        {
            "url": "https://github.com/"
        },
        {
            "url": "https://www.npmjs.com/"
        }
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/open-graph-metadata-validator").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 = {
    "startUrls": [
        { "url": "https://github.com/" },
        { "url": "https://www.npmjs.com/" },
    ],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/open-graph-metadata-validator").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 '{
  "startUrls": [
    {
      "url": "https://github.com/"
    },
    {
      "url": "https://www.npmjs.com/"
    }
  ],
  "maxItems": 10
}' |
apify call automation-lab/open-graph-metadata-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/open-graph-metadata-validator"
        }
    }
}
```

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/3pHk8ZjBaXRd0dV4m/builds/24lrClrpfGBe2x16G/openapi.json
