Metadata, titles and links

Paste a URL into any chat app and a card appears with a title, a description and an image. Build that card yourself, then go one level down to the links on a page and the redirects behind a short URL.

The text of a page is what people read. The metadata is what machines read about it: the title in the browser tab, the description a search engine shows, the image and headline that appear when someone shares the link. Most of the time you want the metadata, not the text, and it is a fraction of the cost to get.

This lesson builds a link preview service, the kind that turns a pasted URL into a card, and then covers the two jobs that sit next to it: listing the links on a page and finding out where a short link really goes.

What a page says about itself

Pages describe themselves in a few overlapping vocabularies:

  • HTML basics. The <title> element, <meta name="description">, <html lang>, the charset and viewport tags.
  • Open Graph. og:title, og:description, og:image, og:site_name, og:type and friends, created for Facebook shares and now read by nearly every chat and social app.
  • Twitter cards. twitter:card, twitter:title, twitter:image, used by X and as a fallback by other apps.
  • Structured data. JSON-LD blocks describing products, articles, events, with prices and authors.

Metadata Extractor returns all of these in one flat object for 2 credits. The basics (title, description, lang, charset, author, keywords, robots, viewport, googlebot) are on every plan. Open Graph, Twitter, jsonld, favicons, canonical, headings and imgTags are premium fields, so design your code to work when they are missing.

Try it liveMetadata Extractor2 credits
POSThttps://api.apiverve.com/v1/metadataextractor
curl -X POST "https://api.apiverve.com/v1/metadataextractor" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://github.com"}'
Sign in or create a free account to run this with your own key.

requestUrl is what you sent; url is where the page ended up. Open Graph keys contain colons, so read them with bracket syntax.

Four things from a real response matter more than the field list.

Missing means empty string, not null. Calling it on https://example.com, a page with no description or Open Graph tags, returned "description": "", "og:title": "", "og:image": "" and so on. In JavaScript, data['og:title'] ?? data.title therefore returns the empty string and your card shows no title. Use || for fallbacks on this API, or normalise empty strings to null once at the boundary.

Keys have colons in them. data.og:title is a syntax error. Write data['og:title'] in JavaScript and data.get("og:title") in Python.

Sites add their own tags, and they come through. The GitHub response included dozens of keys that are not in the documented list, such as route-pattern, octolytics-url and apple-itunes-app, because the API returns every <meta> it finds. Pick the keys you need. Never spread the whole object into a database row or a response to your own clients, or you will store whatever any site on the internet decides to put in its head.

url is the final address. requestUrl is exactly what you sent; url is where the page landed after redirects (https://github.com became https://github.com/). Use url as the base for resolving relative paths and as the key you deduplicate on.

Check yourself

Your preview code is `const title = data['og:title'] ?? data.title;` and pages without Open Graph tags show a blank title. Why?

Answer the check above to continue.

Run every example on your own key. Free plan, no card.

Scaling up?

Volume pricing, custom SLAs, and dedicated support for high-traffic teams.

Contact sales