This tutorial will guide you through the key steps to build, test, and publish your first Open Graph app. We will build a sample recipe app that allows users to publish stories about cooking recipes. Before starting, please review the Open Graph Checklist which will not only help in your app design and planning, but will also help speed up the app review process.
If you're having issues publishing Open Graph actions, visit the Debug and Troubleshoot section. To help you get started quickly, we've also included sample code for download.
To create a Facebook app, go to the App Dashboard, click the 'Create New App' button, and enter your app name and a namespace to get started.

Once you have entered the initial information you will land on the Basic Settings page.
Once you have set up the basic information you can add the Add to Timeline plugin for your website and define your Open Graph objects and actions.
In order to publish Open Graph Actions, your app needs to prompt users for the publish_actions permission. You can use the Login Button plugin and set the 'scope' parameter to prompt for this permission.
Here is some code, using the JavaScript SDK, to help you get started right way. Remember to replace [YOUR_APP_ID] with your own app information.
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"
xmlns:fb="https://www.facebook.com/2008/fbml">
<head>
<title>OG Tutorial App</title>
</head>
<body>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '[YOUR_APP_ID]', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
<fb:login-button show-faces="true" width="200" max-rows="1" scope="publish_actions">
</fb:login-button>
<h3>Stuffed Cookies</h3>
<p>
<img title="Stuffed Cookies"
src="http://fbwerks.com:8000/zhen/cookie.jpg"
width="550"/>
</p>
</body>
</html>
The Open Graph tab of the App Dashboard shows the "Getting Started" subtab of the tool:
The Getting Started wizard walks you through the process of defining your initial object type and action type.
In this tutorial, you will set up your app so that users will be able to Cook a Recipe. In order to do so, we will define an action (or verb) type called Cook and define an object (or noun) type called Recipe.
The next step in the wizard allows you to further define your custom action type, Cook, with custom properties and sample data. We will use the default configuration in this tutorial, so click on the Save Changes and Next button.
Now, you are able to further define your custom object type, Recipe, with custom properties and sample data. We will again use the default configuration in this tutorial, so click on the Save Changes and Next button.
Finally, after defining both an initial custom action type and custom object type, you are now able to define an aggregation.
When a user interacts with your app in a meaningful way, we will also highlight these actions on the user's Timeline with an aggregation.
Let's create an aggregation to highlight a list of recipes that were cooked:
Click the Save and Finish button to save all your changes and return to the Open Graph dashboard. You are now done with defining your initial object types, action types and aggregations. The Dashboard view of your Open Graph app settings will show a summary of these configurations.
The next section will walk you through on how to get your app to publish its first Open Graph action and display an aggregation on a user's Timeline.
Before being able to publish an Open Graph action for a user and having define its corresponding connected object type in Step 3, you will now need to create a publicly accessible web page that represents this object using Open Graph metatags. Once this object page is created, you can use the Graph API to publish an action.
The Open Graph Dashboard page has a 'Get Code' link next to Recipe object type. This contains the Open Graph meta tags describing the object that you'll need to include on your web page.
Here is an object page with the <meta> tags added. Remember to replace [YOUR_APP_NAMESPACE] and [YOUR_APP_ID] with your own app information.
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"
xmlns:fb="https://www.facebook.com/2008/fbml">
<head prefix="og: http://ogp.me/ns# [YOUR_APP_NAMESPACE]:
http://ogp.me/ns/apps/[YOUR_APP_NAMESPACE]#">
<title>OG Tutorial App</title>
<meta property="fb:app_id" content="[YOUR_APP_ID]" />
<meta property="og:type" content="[YOUR_APP_NAMESPACE]:recipe" />
<meta property="og:title" content="Stuffed Cookies" />
<meta property="og:image" content="http://fbwerks.com:8000/zhen/cookie.jpg" />
<meta property="og:description" content="The Turducken of Cookies" />
<meta property="og:url" content="http://fbwerks.com:8000/zhen/cookie.html">
</head>
<body>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '[YOUR_APP_ID]', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
<fb:add-to-timeline></fb:add-to-timeline>
<h3>Stuffed Cookies</h3>
<p>
<img title="Stuffed Cookies"
src="http://fbwerks.com:8000/zhen/cookie.jpg"
width="550"/>
</p>
</body>
</html>
Publishing an action connects the user to the object you created. The Open Graph Dashboard page has a 'Get Code' link next to your action. This contains curl code snippets that you can copy into terminal and run directly.
Publishing an action involves making an HTTP POST to the me/[app_namespace]:[action_type] Graph API endpoint with the following parameters:
[object_type]: a link to a web page representing an object.access_token: a valid user access_token with publish_actions permissions.For example, sending a POST to:
POST https://graph.facebook.com/me/[YOUR_APP_NAMESPACE]:cook
?recipe=OBJECT_URL&access_token=ACCESS_TOKEN
This will publish a Cook action for the Recipe corresponding to the provided OBJECT_URL. Replace OBJECT_URL with your object web page URL.
Here is the updated sample app with the Cook action creation enabled when clicking the "Cook" button:
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"
xmlns:fb="https://www.facebook.com/2008/fbml">
<head prefix="og: http://ogp.me/ns# [YOUR_APP_NAMESPACE]:
http://ogp.me/ns/apps/[YOUR_APP_NAMESPACE]#">
<title>OG Tutorial App</title>
<meta property="fb:app_id" content="[YOUR_APP_ID]" />
<meta property="og:type" content="[YOUR_APP_NAMESPACE]:recipe" />
<meta property="og:title" content="Stuffed Cookies" />
<meta property="og:image" content="http://fbwerks.com:8000/zhen/cookie.jpg" />
<meta property="og:description" content="The Turducken of Cookies" />
<meta property="og:url" content="http://fbwerks.com:8000/zhen/cookie.html">
<script type="text/javascript">
function postCook()
{
FB.api(
'/me/[YOUR_APP_NAMESPACE]:cook',
'post',
{ recipe: 'http://fbwerks.com:8000/zhen/cookie.html' },
function(response) {
if (!response || response.error) {
alert('Error occured');
} else {
alert('Cook was successful! Action ID: ' + response.id);
}
});
}
</script>
</head>
<body>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '[YOUR_APP_ID]', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
<fb:add-to-timeline></fb:add-to-timeline>
<h3>Stuffed Cookies</h3>
<p>
<img title="Stuffed Cookies"
src="http://fbwerks.com:8000/zhen/cookie.jpg"
width="550"/>
</p>
<br>
<form>
<input type="button" value="Cook" onclick="postCook()" />
</form>
</body>
</html>
Now click the "Cook" button! If the publish to Open Graph is successful, an id will be returned that represents the newly published action. Congratulations! You have now published an action and completed the basic steps in getting your Open Graph app up and running.
In order to view an aggregation on a user's Timeline, your app will need to publish a few more actions to Open Graph on behalf of the user. Define a few more objects through the earlier steps and publish a few more actions. Your app will need to publish actions for at least 5 times before an aggregation is surfaced on a user's Timeline.
Go to Timeline on Facebook to view the aggregation of your app:

You can preview News Feed stories created when publishing actions by going to https://www.facebook.com/USER_ID/activity/STORY_ID, where USER_ID is the user's Facebook ID or username, and STORY_ID is the action-instance-id as described below. For example:
https://www.facebook.com/dhirenp/activity/10100657260775943
The user must have appropriate permissions in order to see the preview.
Open Graph also provides the ability to publish a user's past actions and objects. Please refer to our developer documentation on Publishing Past Actions.
Add one or more Social Plugins that are available for Open Graph apps.
On your object web page, you can add any of these plugins to highlight Open Graph actions. For the purposes of this tutorial, let's add the new Activity Plugin.
The Activity Plugin has been updated to highlight the Open Graph actions published by an app.
To add an Activity Plugin, include the following code on your web page:
<fb:activity actions="[YOUR_APP_NAMESPACE]:ACTION-TYPE"/></fb:activity>
Here is the entire code of the tutorial that includes rendering the "Add to Timeline" button, publishing an Open action, and including the Activity Plugin, all within a single page:
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"
xmlns:fb="https://www.facebook.com/2008/fbml">
<head prefix="og: http://ogp.me/ns# [YOUR_APP_NAMESPACE]:
http://ogp.me/ns/apps/[YOUR_APP_NAMESPACE]#">
<title>OG Tutorial App</title>
<meta property="fb:app_id" content="[YOUR_APP_ID]" />
<meta property="og:type" content="[YOUR_APP_NAMESPACE]:recipe" />
<meta property="og:title" content="Stuffed Cookies" />
<meta property="og:image" content="http://fbwerks.com:8000/zhen/cookie.jpg" />
<meta property="og:description" content="The Turducken of Cookies" />
<meta property="og:url" content="http://fbwerks.com:8000/zhen/cookie.html">
<script type="text/javascript">
function postCook()
{
FB.api(
'/me/[YOUR_APP_NAMESPACE]:cook?recipe',
'post',
{ recipe: 'http://fbwerks.com:8000/zhen/cookie.html' },
function(response) {
if (!response || response.error) {
alert('Error occured');
} else {
alert('Cook was successful! Action ID: ' + response.id);
}
});
}
</script>
</head>
<body>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '[YOUR_APP_ID]', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
<fb:add-to-timeline></fb:add-to-timeline>
<h3>Stuffed Cookies</h3>
<p>
<img title="Stuffed Cookies"
src="http://fbwerks.com:8000/zhen/cookie.jpg"
width="550"/>
</p>
<br>
<form>
<input type="button" value="Cook" onclick="postCook()" />
</form>
<fb:activity actions="[YOUR_APP_NAMESPACE]:cook"></fb:activity>
</body>
</html>
We are introducing a lightweight review and approval process before your app can publish Open Graph actions to all users.

Open Graph activities will be immediately visible to the administrators, developers and testers of your app. This allows you to do end-to-end testing of your Open Graph integration. Once that is complete, submit the Open Graph actions of your app via the App Dashboard for review and approval.
After we have verified that the use of Open Graph actions by your app meets our criteria, we will approve your app to publish Open Graph actions to all Facebook users. Please note that we are not approving your app, only how Open Graph actions are being published by your app.
Read more about the approval process for further details.
Here are some helpful tips when troubleshooting issues in publishing Open Graph objects or actions by your app:
&expires token from your access_token before making the Graph API call id returned from the Graph API POST call Download the code presented in this tutorial from our Open Graph Samples.