Validate Open Graph
The first time most people discover their Open Graph tags are broken is after pasting a link into a chat and watching a blank gray box appear where a preview card should be. This endpoint checks the tags before that happens, showing exactly what title, description and image a share will render with, and flagging what is missing or malformed.
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
Why the preview and the page rarely match on the first try
Open Graph tags live in the page head, invisible to anyone reading the rendered page, which means they are easy to forget, easy to leave with placeholder values from a template, and easy to break silently when a CMS update changes how meta tags get injected. Nobody notices until a link gets shared somewhere that renders a card, and by then the bad preview has already been seen.
What the check actually inspects
The task fetches the URL, reads the og:title, og:description, og:image, og:type and related tags, and checks each against the practical constraints that consuming platforms enforce — image dimensions and aspect ratio, description length before truncation, whether the image URL actually resolves to a real, publicly reachable image rather than a broken path. It returns the parsed values alongside a rendered preview description and a list of specific issues, not just a pass or fail.
Where Open Graph came from
The protocol was introduced in 2010 to let any web page become a rich object inside a social graph, and it was deliberately built as plain meta tags so it required no special server support. That simplicity is also why it is fragile: there is no browser warning for a missing og:image the way there is for a broken link, so problems accumulate invisibly until someone checks.
Checking more than one page at once
Because the check is priced per request, it fits naturally into a pre-publish step for a single article or a periodic sweep across a whole set of URLs, run as separate requests through the same endpoint to catch tags that degraded after a template change or a CMS migration.
Getting the result
Submit the URL and receive a task_id right away; the validation report arrives through your webhook or a signed link valid for 24 hours once the check completes. An unreachable URL retries up to three times before returning a clear error, and you are never charged for that failed attempt, so a temporary network blip on the target server never turns into a wasted request on your side.
What you can do with it
Pre-publish checks for editorial teams
Validate an article's Open Graph tags in the staging environment before it goes live, catching a missing og:image before readers do.
Debugging a broken share card
Diagnose exactly which tag is missing or malformed when a page that used to preview correctly suddenly shows a blank card.
CMS or template migration checks
Re-validate a sample of URLs after a site redesign to confirm the new templates still emit correct og:title and og:image values.
Landing page QA before a campaign
Confirm the exact title, description and image a paid campaign's landing page will show when shared, before traffic starts.
FAQ
What does this open graph validator api actually check?
It fetches the URL, reads og:title, og:description, og:image, og:type and related tags, verifies the image is reachable and correctly sized, and flags anything missing or malformed.
Does it show me how the card will actually look?
Yes, it returns the parsed tag values along with a rendered preview description of the title, description and image as a sharing platform would show them.
Can it check Twitter Card tags too?
The check focuses on Open Graph tags; where a page relies on Twitter Card fallbacks, the report notes which og: equivalents are missing.
Is there a free trial to test the validator?
The tool above runs free in your browser. The API is paid — each call draws from your prepaid ForHosting KIT balance: top up from $10.00 (it never expires), pay each request's published price, and a call with no balance returns HTTP 402. No subscription, no tokens, and a failed task is never charged.
What does the open graph validator api cost per check?
A flat $0.002 per request, whether the page passes cleanly or comes back with a list of issues.
Can I validate many URLs at once?
Each URL is one request at the same flat price; submit them individually to check a whole set of pages.
How do I get the validation report?
Via a signed webhook when the check completes, or a signed link that stays valid for 24 hours.
What happens if the page is temporarily unreachable?
The task retries up to three times automatically; if it still cannot reach the page, it fails with a clear error and is not charged.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/seo/og-validate \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://ejemplo.com"}'const res = await fetch("https://api.kit.forhosting.com/seo/og-validate", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"url": "https://ejemplo.com"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/seo/og-validate",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"url": "https://ejemplo.com"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/seo/og-validate", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"url":"https://ejemplo.com"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"url":"https://ejemplo.com"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/seo/og-validate", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"url": "https://ejemplo.com"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "seo.og_validate",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |