Implementing OEmbed URL Embedded Representation Using PHP and jQuery

oEmbed is a way for third-party websites to display an embedded representation of an URL. Using this format service providers implement URL Schemes and API endpoints for third-party websites to use and display embedded representation of their content.


OEmbed URL Expand Overview

consumer(e.g Facebook) requests the service provider(e.g Youtube) with the following HTTP request(when a user posts a Youtube URL).

oEmbed API endpoint;=json


  "provider_name": "YouTube",
  "author_url": "http:\/\/\/channel\/UCxniXn78zuGzSXXo4ugZTqQ",
  "html": "<iframe width=\"480\" height=\"270\" src=\"https:\/\/\/embed\/RPHRljJ-dKU?feature=oembed\" frameborder=\"0\" allowfullscreen><\/iframe>",
  "thumbnail_height": 360,
  "thumbnail_width": 480,
  "title": "Call of Duty - Advance Warefare Sentinel Mission Gameplay Walkthrought PC",
  "version": "1.0",
  "width": 480,
  "height": 270,
  "type": "video",
  "thumbnail_url": "https:\/\/\/vi\/RPHRljJ-dKU\/hqdefault.jpg",
  "author_name": "GameDodle",
  "provider_url": "http:\/\/\/"

We can parse the response and use the details to create an embedded representation.

oEmbed Specification

There are 3 parts for this oEmbed spec,

  • consumer – The third-party website that has to show an embedded representation of the URL(e.g Facebook, Twitter).
  • provider – The service provider that has implemented the API endpoint pairs for consumers to use(e.g Flicker, Youtube, Vimeo).
  • configuration – One or more URL schemes and API endpoints given by the provider.
    • URL Scheme – Describes which URLs may have an embedded representation. e.g.
    • API endpoint – This is where the consumer may request the representation for the URL. e.g.;=json. The API must point to an HTTP endpoint URL.

Consumer Request

All requests sent to the API endpoint must be HTTP GET with the arguments urlencoded. The encoding must be in RFC 1738.

Request Format

  • url(required) – URL to which the embedded information is required for.
  • format(optional) – Format in which the response must be (JSON/XML). If not specified provider must send the response in default format or else send error.
  • maxwidth(optional) – Maximum width of the embedded representation. This only applies to specific contents.
  • maxheight(optional) – Maximum height of the embedded representation. This also applies only to specific contents.

Providers can implement custom arguments and ignore arguments it does not expect.

Providers may have the response format specified as an argument or as part of the request. For example,

  • URL scheme:*
  • API XML endpoint:
  • API JSON endpoint:

In the above cases the format argument is not need as it is part of the request.

Provider Response

The response from the provider is in either JSON or XML format which will be specified in the Content-type header of the response. Know more about JSON and XML.

There are various response params for the type of content being requested for embedding(e.g. Video, Photo, Link). To view the full list of response params available visit OEmbed Provider Response.



The Markup contains an input for providing the URL and a div element for displaying the response.

<div class="row">
      <div class="col-md-12">
        <div class="form-group">
          <label>OEmbed URL Embedded Representation</label>
          <input type="text" name="url" id="urlInput" class="form-control input-lg" id="exampleInputEmail1" placeholder="Paste any Youtube URL here" />
          <small>Click outside the textbox once you paste or enter a value.</small>
    <div class="row">
      <div class="col-md-12">
        <div class="response-container">
          <div class="loading-icon"></div>


The Javascript here is pretty simple. An change event is attached to the input, when something changes in it an ajax is called and the response is got.

// Initially hide the loading icon
var loading = $('.loading-icon').hide();

// Display the loading icon only during ajax request.
$(document).ajaxStart(function () {;
}).ajaxStop(function () {

// Attach event to the input and provide ajax
(function() {
  $('#urlInput').on('change', function(event) {
    if (this.value !== '') {
      var inputUrl = this.value;
      // Send the ajax request.
        url: 'ajax/oembed.php',
        method: 'post',
        data: {url: inputUrl},
        dataType: 'html'
      }).done(function(response, status) {
      }).error(function(response) {
          '<p class="alert alert-danger">Error sending request..!</p>'


This code shows only how to expand Youtube URL’s. This implements only the Youtube API Endpoint.

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['url'])) {

    // Request params
    $params = array();
    $params['url'] = rawurlencode($_POST['url']);
    $params['format'] = 'json';

    // Request params string
    $params_string = 'url=' . $params['url'] . '&format;=' . $params['format'];

    // Request URL
    $request_url = '' . $params_string;
    // Get cURL resource
    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => $request_url,

    // Send the request
    $response = curl_exec($curl);
    // Close request to clear up some resources

    $response = @json_decode($response, true);
    if (!empty($response) && isset($response['title'])) {
      $html =<<<html
      <div class="panel panel-default">
          <div class="panel-heading">
            <h3 class="panel-title">{$response['title']}</h3>
          <div class="panel-body">
            <div class="row">
                <div class="col-md-3">
                    <p>Author: <a href="{$response['author_url']}" target="_blank">{$response['author_name']}</a></p>
                    <p><img class="img-responsive" src="{$response['thumbnail_url']}" width="{$response['thumbnail_width']}" height="{$response['thumbnail_height']}" /></p>
                <div class="col-md-9">
        echo $html;
    } else {
        echo '<p class="alert alert-warning">Awww snap..! Try another URL.</p>';
} else {
    echo '<p class="alert alert-warning">Could not process the request. Try again later.</p>';