oEmbed API
Get embeddable representations of URLs following the oEmbed specification. Generate iframe embeds and rich content previews for any URL.
v3.0 enables smart defaults — auto_proxy, auto_render, and retry are all on by default. The best proxy and rendering strategy is chosen automatically for each target domain.
Quickstart
Pass a URL, get back embeddable HTML. Render the html field and you are done — it is populated whether the URL resolved to a native provider embed or to a hosted fallback card, so there is no branching to write.
curl "https://opengraph.io/api/3.0/oembed?url=https://example.com/article&app_id=YOUR_APP_ID"That is the whole integration. Every response carries a source field (native, discovery, or og_frame) if you want to label or style embeds differently by tier, but you do not need to read it to render the embed. See How Resolution Works for what each tier means.
Endpoint
The target URL can be passed either as a path segment or as a url query parameter. Both forms are supported on v1.1 and v3.0 and return identical responses.
GET https://opengraph.io/api/3.0/oembed?url={encoded_url}&app_id=YOUR_APP_IDGET https://opengraph.io/api/3.0/oembed/{encoded_url}?app_id=YOUR_APP_IDWhich to use: the query form is usually easier, since you are not percent-encoding a URL into a path segment. The path form exists for parity with the other OpenGraph.io endpoints and for oEmbed clients that build paths. Pick one; do not send both.
Parameters
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| encoded_url | string | Required. URL-encoded target URL |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| app_id | string | - | Required. Your API key |
| orientation | string | vertical | Frame orientation: vertical (800x600) or horizontal (400x150) |
| always_og_frame | boolean | false | Force OG frame generation even if native oEmbed exists |
| url | string | - | URL-encoded target URL. Alternative to the path segment; use either the path form or this query parameter. |
| maxwidth | integer | - | Maximum embed width in pixels. Forwarded to native providers when supported and applied to the fallback frame dimensions. |
| maxheight | integer | - | Maximum embed height in pixels. Forwarded to native providers when supported and applied to the fallback frame dimensions. |
| theme | string | auto | Color scheme for hosted fallback cards: light, dark, or auto (follow system preference). Only applies when the response uses an OpenGraph fallback frame. |
| template | string | - | Layout preset for fallback cards: default (vertical card, 800×600), compact or horizontal (banner, 400×150). When set, takes precedence over orientation. |
| cache_ok | boolean | true | When false, bypasses cached page metadata and re-fetches the target URL. Useful for refreshing stale fallback cards. |
| max_cache_age | integer | 432000000 | Maximum age of cached page metadata in milliseconds before a re-fetch is required (when cache_ok is true). |
| full_render | boolean | false | Enable JavaScript rendering before reading page metadata. Only affects the fallback frame tier, where metadata is scraped from the target page. Native and discovery embeds come from the provider, so rendering does not apply. |
| use_proxy | boolean | false | Use standard proxy when fetching the target page |
| use_premium | boolean | false | Use residential proxy |
| use_superior | boolean | false | Use mobile proxy (highest success rate) |
| proxy_country | string | - | Specify proxy country code (e.g., US, GB, DE) |
| auto_proxy | boolean | true | Automatically select optimal proxy |
| auto_render | boolean | true | Automatically enable JS rendering when needed |
| retry | boolean | true | Auto-retry failed requests with proxy escalation |
Proxy and rendering options only affect the fallback tier. Native and discovery embeds are fetched from the provider's own oEmbed endpoint, which does not need a proxy or a browser. These options apply when we scrape the target page to build a hosted card. On v3.0, auto_proxy and auto_render already pick a strategy per domain, so set these explicitly only when you need to override that.
camelCase accepted: maxWidth and maxHeight work as aliases for maxwidth and maxheight. The lowercase spelling is what the oEmbed spec defines and takes precedence if both are sent.
Note: By default embed dimensions follow orientation — vertical produces 800x600, horizontal produces 400x150. Supplyingmaxwidth and/or maxheight overrides these defaults. Fallback cards also support theme and template for appearance control. Free-tier plans include an “OpenGraph.io” badge on fallback frames; paid plans omit it.
How Resolution Works
OpenGraph.io resolves an embed for any URL using a three-tier strategy. The tier that produced the result is reported in the response source field.
| Tier | source | When it is used |
|---|---|---|
| Native provider | native | The URL matches a known oEmbed provider (YouTube, Vimeo, etc.) |
| oEmbed discovery | discovery | The page advertises an oEmbed endpoint via a discovery link tag |
| OpenGraph fallback frame | og_frame | No native embed exists — a hosted card is generated from page metadata |
OpenGraph.io first checks for a native oEmbed provider, then looks for an oEmbed discovery link, and finally generates a hosted fallback card from the page's OpenGraph metadata when no native embed is available. If a native provider is unreachable or returns an unusable response, the request gracefully degrades to the fallback frame rather than failing.
Example Request
# Path form
curl "https://opengraph.io/api/3.0/oembed/https%3A%2F%2Fyoutube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ?app_id=YOUR_APP_ID"
# Query form with sizing hints
curl "https://opengraph.io/api/3.0/oembed?url=https%3A%2F%2Fyoutube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ&maxwidth=640&maxheight=480&app_id=YOUR_APP_ID"
# Fallback frame styling (when source is og_frame)
curl "https://opengraph.io/api/3.0/oembed?url=https%3A%2F%2Fexample.com%2Farticle&theme=dark&template=compact&always_og_frame=true&app_id=YOUR_APP_ID"Examples by Resolution Path
One request per tier, plus the sizing and layout controls, so you can see what changes between a native provider embed and a hosted fallback card.
# A registry provider (YouTube) resolves natively and its own player HTML
# is passed through untouched. Response: source = "native"
curl "https://opengraph.io/api/3.0/oembed?url=https%3A%2F%2Fyoutube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ&app_id=YOUR_APP_ID"Example Response
{
"type": "hybridEmbed",
"version": "1.0",
"provider_name": "Example Site",
"width": 800,
"height": 600,
"source": "og_frame",
"embed_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"frame_url": "https://frames.opengraph.io/oembed/{customerIdHash}/{apiParamsHash}",
"html": "<iframe src=\"...\" width=\"800\" height=\"600\"></iframe>"
}Response Fields
| Field | Description |
|---|---|
| type | The oEmbed type (usually "hybridEmbed") |
| version | oEmbed version (1.0) |
| provider_name | Name of the content provider |
| width | Width of the embed in pixels |
| height | Height of the embed in pixels |
| source | Which resolver tier produced the embed: native,discovery, or og_frame |
| embed_id | Stable content ID for hosted fallback frames (source: og_frame). Use with the Frame Management API to refresh or delete the embed. |
| frame_url | Direct URL to the hosted fallback frame iframe (present when source is og_frame) |
| html | HTML snippet to embed the content (usually an iframe) |
Note: The html field contains ready-to-use HTML that can be directly inserted into your page.
Frame Management API
Hosted fallback frames (source: og_frame) receive a stable embed_id. Use the Frame Management API to list, refresh, or delete embeds without re-supplying the original URL and options.
| Endpoint | Method | Description |
|---|---|---|
/api/v1/frames | GET | List all hosted frames for your organization |
/api/v1/frames/:id | GET | Get a single frame by embed_id |
/api/v1/frames/:id/refresh | POST | Re-fetch page metadata (cache_ok=false) and regenerate the hosted frame HTML |
/api/v1/frames/:id | DELETE | Delete a hosted frame record |
Authenticate with your API key via the api-key header or app_id query parameter. The Frame Management API is served from the frame host (e.g. frames.opengraph.io).
curl -X POST "https://frames.opengraph.io/api/v1/frames/YOUR_EMBED_ID/refresh?app_id=YOUR_APP_ID"Errors
When an embed cannot be resolved, the API returns a structured error with a machine readable code and the stage at which resolution failed.
{
"success": false,
"error": {
"code": "oembed_resolution_failed",
"message": "Unable to resolve an embed for this URL.",
"stage": "fallback",
"details": null
}
}| code | HTTP | Meaning |
|---|---|---|
| invalid_request | 400 | The request was missing required context to resolve the embed |
| oembed_resolution_failed | 422 | No native embed and no OpenGraph metadata available to build a card |
| frame_generation_failed | 502 | The fallback frame could not be generated by the frame service |
Reading errors: stage tells you how far resolution got — validation means the URL was rejected before any fetch, so retrying will not help, while fallback means we tried and the frame service failed, which is worth a retry. Unexpected server-side failures return 5xx rather than 400, so client mistakes and our outages are distinguishable. For status codes, rate limiting, and retry strategy across all endpoints, see the Error Handling guide.
Credits & Billing
Every response carries an X-BILLING-REQUESTS header with the number of credits the request actually consumed. That header is authoritative — read it rather than inferring cost from the parameters you sent.
| Request | Credits | Notes |
|---|---|---|
/api/1.1/oembed | 10 | Flat rate, regardless of which tier resolves the embed |
/api/3.0/oembed | 1 + add-ons | Billed on the standard model: one credit for the request, plus add-ons for proxy and rendering features when they are used |
What does and does not add cost. The resolution tier itself is free: a native provider embed, a discovery fetch, and a hosted fallback card all cost the same. Cached responses are not cheaper, so leave cache_ok on for latency rather than for billing. What does add cost on v3.0 is fetching the target page through a proxy or a browser, which only happens on the fallback tier — see Credits for the per-feature amounts.
Use Cases
- Embedding rich content previews in CMS platforms
- Creating link preview cards with interactive elements
- Building content aggregation tools
- Social media management dashboards