diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index 5dee5bb461a21e214145acb65feeb54e36554227..60d0ec9f3e6571f6c1c32f1acae185d91ea774bb 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -7,7 +7,7 @@ require Rails.root.join("app", "presenters", "post_presenter")
 class PostsController < ApplicationController
   include PostsHelper
   
-  before_filter :authenticate_user!, :except => [:show, :iframe]
+  before_filter :authenticate_user!, :except => [:show, :iframe, :oembed]
   before_filter :set_format_if_malformed_from_status_net, :only => :show
 
   layout 'post'
@@ -24,13 +24,7 @@ class PostsController < ApplicationController
   end
 
   def show
-    key = params[:id].to_s.length <= 8 ? :id : :guid
-
-    if user_signed_in?
-      @post = current_user.find_visible_shareable_by_id(Post, params[:id], :key => key)
-    else
-      @post = Post.where(key => params[:id], :public => true).includes(:author, :comments => :author).first
-    end
+    @post = find_by_guid_or_id_with_current_user(params[:id])
 
     if @post
       # @commenting_disabled = can_not_comment_on_post?
@@ -59,6 +53,17 @@ class PostsController < ApplicationController
     render :text => post_iframe_url(params[:id]), :layout => false
   end
 
+  def oembed
+    post_id = OEmbedPresenter.id_from_url(params.delete(:url))
+    post = find_by_guid_or_id_with_current_user(post_id) 
+    if post.present?
+      oembed = OEmbedPresenter.new(post, params.slice(:format, :maxheight, :minheight))
+      render :json => oembed
+    else
+      render :nothing => true, :status => 404
+    end
+  end
+
   def destroy
     @post = current_user.posts.where(:id => params[:id]).first
     if @post
@@ -76,6 +81,16 @@ class PostsController < ApplicationController
 
   private
 
+  def find_by_guid_or_id_with_current_user(id)
+    key = id.to_s.length <= 8 ? :id : :guid
+    if user_signed_in?
+      current_user.find_visible_shareable_by_id(Post, id, :key => key)
+    else
+      Post.where(key => id, :public => true).includes(:author, :comments => :author).first
+    end
+
+  end
+
   def set_format_if_malformed_from_status_net
    request.format = :html if request.format == 'application/html+xml'
   end
diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb
index 35e981a1cf6854a8869b3552c4bb01aee94023be..e12ed5901992b5af65c361768fb0780b71e50d84 100644
--- a/app/helpers/posts_helper.rb
+++ b/app/helpers/posts_helper.rb
@@ -20,6 +20,7 @@ module PostsHelper
   def post_iframe_url(post_id, opts={})
     opts[:width] ||= 516
     opts[:height] ||= 315 
-   "<iframe src='#{post_url(post_id)}' width='#{opts[:width]}px' height='#{opts[:height]}px' frameBorder='0'></iframe>".html_safe
+    host = AppConfig[:pod_uri].port ==80 ? AppConfig[:pod_uri].host : "#{AppConfig[:pod_uri].host}:#{AppConfig[:pod_uri].port}"
+   "<iframe src='#{Rails.application.routes.url_helpers.post_url(post_id, :host => host)}' width='#{opts[:width]}px' height='#{opts[:height]}px' frameBorder='0'></iframe>".html_safe
   end
 end
diff --git a/app/presenters/o_embed_presenter.rb b/app/presenters/o_embed_presenter.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0723b7df948793854bfb418f7a51e12ca9908ca6
--- /dev/null
+++ b/app/presenters/o_embed_presenter.rb
@@ -0,0 +1,49 @@
+require 'uri'
+class OEmbedPresenter
+  include PostsHelper
+  include ActionView::Helpers::TextHelper
+
+  def initialize(post, opts = {})
+    @post = post
+    @opts = opts
+  end
+
+  def to_json(opts={})
+    as_json(opts).to_json
+  end
+
+  def as_json(opts={})
+    {
+      :provider_name => "Diaspora", 
+      :provider_url => AppConfig[:pod_url],
+      :type => 'rich',
+      :version => '1.0',
+      :title => post_title,
+      :author_name => post_author,
+      :author_url => post_author_url,
+      :width => @opts.fetch(:maxwidth, 516), 
+      :height => @opts.fetch(:maxheight, 320),
+      :html => iframe_html
+    }
+  end
+
+  def self.id_from_url(url)
+    URI.parse(url).path.gsub(%r{\/posts\/|\/p\/}, '')
+  end
+
+  def post_title
+    post_page_title(@post)
+  end
+
+  def post_author
+    @post.author.name
+  end
+
+  def post_author_url
+   Rails.application.routes.url_helpers.person_url(@post.author, :host => AppConfig[:pod_uri].host)
+  end
+
+  def iframe_html
+    post_iframe_url(@post.id, :height => @opts[:maxheight], :width => @opts[:maxwidth])
+  end
+end
\ No newline at end of file
diff --git a/app/views/layouts/post.html.haml b/app/views/layouts/post.html.haml
index 75ae0cb19d6b8212adb68b4e16ea33744fe0ebd4..98f94121932d2baa5422d947ba0afb7e7cc90f5f 100644
--- a/app/views/layouts/post.html.haml
+++ b/app/views/layouts/post.html.haml
@@ -44,6 +44,8 @@
     = set_asset_host
     = translation_missing_warnings
     = current_user_atom_tag
+    - if @post.present?
+      %link{:rel => 'alternate', :type => "application/json+oembed", :href => "#{oembed_url(:url => post_url(@post))}"}
 
     = yield(:head)
     = csrf_meta_tag
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 0a01b0369f36d6cddd24ee2562b14510720a3882..1aaa3b27ab1adb60534c68079d030540af04e917 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -47,4 +47,6 @@ Diaspora::Application.configure do
   # This is necessary if your schema can't be completely dumped by the schema dumper,
   # like if you have constraints or database-specific column types
   # config.active_record.schema_format = :sql
+  
+  config.default_url_options = { :host => AppConfig[:pod_uri].host}
 end
diff --git a/config/routes.rb b/config/routes.rb
index d556997cbb651277b373cb10a78e870a50e0bc25..daee0895709571407ea4f1aa71b73d5194eee883 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -5,6 +5,7 @@
 Diaspora::Application.routes.draw do
   mount RailsAdmin::Engine => '/admin_panel', :as => 'rails_admin'
 
+  get 'oembed' => 'posts#oembed', :as => 'oembed'
   # Posting and Reading
   resources :reshares
 
diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb
index 2a53a661b941656ede0524e73f460670aee73f53..221beaca8297740bb8795cb88ff5e636d7223efe 100644
--- a/spec/controllers/posts_controller_spec.rb
+++ b/spec/controllers/posts_controller_spec.rb
@@ -120,6 +120,19 @@ describe PostsController do
     end
   end
 
+  describe 'oembed' do
+    it 'works when you can see it' do
+      sign_in alice
+      get :oembed, :url => "/posts/#{@message.id}"
+      response.body.should match /iframe/
+    end
+
+    it 'returns a 404 response when the post is not found' do
+      get :oembed, :url => "/posts/#{@message.id}"
+      response.should_not be_success
+    end
+  end
+
   describe '#destroy' do
     before do
       sign_in alice
diff --git a/spec/presenters/o_embed_presenter_spec.rb b/spec/presenters/o_embed_presenter_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7182b6a1a42cadc55934c0f091dbdb6a552d5089
--- /dev/null
+++ b/spec/presenters/o_embed_presenter_spec.rb
@@ -0,0 +1,35 @@
+require 'spec_helper'
+describe OEmbedPresenter do
+  before do
+   @oembed = OEmbedPresenter.new(Factory(:status_message))
+  end
+
+  it 'is a hash' do
+    @oembed.as_json.should be_a Hash
+  end
+
+  context 'required options from oembed spec' do
+    it 'supports maxheight + maxwidth(required)' do
+      oembed = OEmbedPresenter.new(Factory(:status_message), :maxwidth => 200, :maxheight => 300).as_json
+      oembed[:width].should  == 200
+      oembed[:height].should == 300
+    end
+  end
+
+  describe '#iframe_html' do
+    it 'passes the height options to post_iframe_url' do
+      @oembed.should_receive(:post_iframe_url).with(instance_of(Fixnum), instance_of(Hash))
+      @oembed.iframe_html
+    end
+  end
+
+  describe '.id_from_url' do
+    it 'takes a long post url and gives you the id' do
+      OEmbedPresenter.id_from_url('http://localhost:400/posts/1').should == "1"
+    end
+
+    it 'takes a short post url and gives you the id' do
+      OEmbedPresenter.id_from_url('http://localhost:400/p/1').should == "1"
+    end
+  end
+end
\ No newline at end of file