Real-time Photo Updates
Real-time photo updates provide your application with instant notifications of new photos as they are posted on Instagram. It’s our belief that Instagram can be a platform for changing the way we see the world. The most interesting way to view the world is live, as it happens. (No one likes day-old news, right?) By adopting parts of the Pubsubhubub protocol, and through the use of a couple simple web hooks, we’ve been able to create a system where your application gets notified of new photos as they’re posted.
Our real-time API serves a couple of basic needs: First, instead of polling the Instagram servers to check to see if there are new photos available, you can rely upon our servers to POST to a callback URL on your server when new data is available. Second, developers running servers like Tornado or Node.js can provide real-time experiences of events to their users. We’re most excited to see what developers will create with live data at their fingertips.
Subscriptions
You may subscribe to real-time updates from four basic Instagram object types:
- Users: receive notifications when users who have registered with your application post new photos.
- Tags: receive notifications when a new photo is tagged with tags of your choosing
- Locations: receive notifications when new photos are posted and tagged with a specific location
- Geographies: receive notifications when a new photos are posted in an arbitrary geographical location as defined by a center point and radius
Process
Register a client
To create a subscription, you must first register a client to obtain a client_id and client_secret.
Create a Callback URL
When we have new updates to send your server, we do a simple POST with a payload containing updates to a URL on your server. This callback URL must support GET and POST methods.
When you add a subscription, we will send a GET request to your callback URL to verify the existence of the URL and that want to create the subscription. When we have new data, we’ll POST this data to your callback URL. We’ll explain more about what this URL needs to do later on this page.
http://your-callback.com/url/
Create a Subscription
To create a subscription, you make a POST request to the subscriptions endpoint.
curl -F 'client_id=CLIENT-ID' \
-F 'client_secret=CLIENT-SECRET' \
-F 'object=user' \
-F 'aspect=media' \
-F 'verify_token=myVerifyToken' \
-F 'callback_url=http://YOUR-CALLBACK/URL' \
https://api.instagram.com/v1/subscriptions/
If you run this command with your own callback_url, client_id and client_secret you’ll notice it will fail with the error: “Challenge Verification Failed”. In order to keep someone else from creating unwanted subscriptions, we must verify that the endpoint would like this new subscription. We do this by following the Pubsubhubub challenge flow.
When you POST with the info above to create a new subscription, we simultaneously submit a GET request to your callback URL with the following parameters:
- hub.mode – This will be set to “subscribe”
- hub.challenge – This will be set to a random string that your callback URL will need to echo back in order to verify you’d like to subscribe.
- hub.verify_token – This will be set to whatever verify_token passed in with the subscription request. It’s helpful to use this to differentiate between multiple subscription requests.
For instance, the GET you’ll see coming will look like this:
http://your-callback.com/url/?hub.mode=subscribe&hub.challenge=15f7d1a91c1f40f8a748fd134752feb3&hub.verify_token=myVerifyToken
In order to verify the subscription, your server must respond to the GET request with the hub.challenge parameter only:
15f7d1a91c1f40f8a748fd134752feb3
If this request succeeds and everything else about your subscription succeeds as well, you’ll get a subscription JSON response from your original POST with the created subscription:
{
"meta": {
"code": 200
},
"data": [
{
"id": "1",
"type": "subscribe",
"object": "user",
"aspect": "media",
"callback_url": "http://your-callback.com/url/"
},
{
"id": "2",
"type": "subscription",
"object": "location",
"object_id": "2345",
"aspect": "media",
"callback_url": "http://your-callback.com/url/"
}
]
}
User subscriptions
In the previous example, we set up a subscription to receive updates whenever one of our client’s authenticated users posts a photo. Note that this subscription is for all of the client’s authenticated users, not just a specific user.
Other than the required client_id, client_secret, and callback_url parameters, the two parameters you need to include in order to subscribe to all photo updates from a user are:
- object: The object you’d like to subscribe to (in this case, “user“)
- aspect: The aspect of the object you’d like to subscribe to (in this case, “media“). Note that we only support “media” at this time, but we might support other types of subscriptions in the future.
At the current moment we only allow you to subscribe to all users that have authenticated your application – not individual users.
Tag Subscriptions
With Tag Subscriptions, we’ve made it easier to subscribe to new photos tagged with certain words. For instance, if you create a subscription for the tag “nofilter”, your server will receive a POST request at the callback URL every time anyone posts a new photo with the tag #nofilter
To create a tag subscription:
curl -F 'client_id=CLIENT-ID' \
-F 'client_secret=CLIENT-SECRET' \
-F 'object=tag' \
-F 'aspect=media' \
-F 'object_id=nofilter' \
-F 'callback_url=http://YOUR-CALLBACK/URL' \
https://api.instagram.com/v1/subscriptions/
Note that in this case, object_id is the tag to which you’d like to subscribe. Unlike user subscriptions, you’re subscribing to a single object, so you must pass object_id.
Location Subscriptions
With a location subscription, you can receive updates every time someone posts a photo tagged with a specific Instagram location. In this case, you change object to “location” and object_id to the ID of the location to which you’d like to subscribe.
curl -F 'client_id=CLIENT-ID' \
-F 'client_secret=CLIENT-SECRET' \
-F 'object=location' \
-F 'aspect=media' \
-F 'object_id=1257285' \
-F 'callback_url=http://YOUR-CALLBACK/URL' \
https://api.instagram.com/v1/subscriptions/
In this example, the location to which we’ve subscribed is Shibuya in Tokyo.
Geography Subscriptions
While subscribing to individual locations can be useful, it can also be difficult to get a good picture of larger areas. In the last example, Shibuya has multiple entries in our database – so which location do you use? Or consider the fact that many photos don’t have specific locations tied to them, but have been geotagged – how do you subscribe to those photos?
While subscribing to a location is perfect for some situations, it’s too rigid of a constraint to capture larger areas like a city or a large park. For this, we’ve created Geography subscriptions.
To create a subscription to a geography, specify a center latitude and longitude and a radius of the area you’d like to capture around that point (maximum radius is 5000 meters)
curl -F 'client_id=CLIENT-ID' \
-F 'client_secret=CLIENT-SECRET' \
-F 'object=geography' \
-F 'aspect=media' \
-F 'lat=35.657872' \
-F 'lng=139.70232' \
-F 'radius=1000' \
-F 'callback_url=http://YOUR-CALLBACK/URL' \
https://api.instagram.com/v1/subscriptions/
Later, when fetching media about the geography you’ve just created through this subscription, you can access:
https://api.instagram.com/v1/geographies/{geography id}/media/recent?client_id=CLIENT-ID
Note that this endpoint is meant to be used to fetch media as you hear about it through the real-time callback, and only returns media taken recently.
Receiving Updates
When someone posts a new photo and it triggers an update of one of your subscriptions, we make a POST request to the callback URL that you defined in the subscription. The post body contains a raw text JSON body with update objects:
[
{
"subscription_id": "1",
"object": "user",
"object_id": "1234",
"changed_aspect": "media",
"time": 1297286541
},
{
"subscription_id": "2",
"object": "tag",
"object_id": "nofilter",
"changed_aspect": "media",
"time": 1297286541
},
...
]
You should build your system to accept multiple update objects per payload – though often there will be only one included. Also, you should acknowledge the POST within a 2 second timeout–if you need to do more processing of the received information, you can do so in an asynchronous task.
The changed data is not included in the payload, so it is up to you how you’d like to fetch the new data. For example, you may decide only to fetch new data for specific users, or after a certain number of photos have been posted.
To verify that the payload you received comes from us, you can verify the “X-Hub-Signature” header. This will be a SHA-1-signed hexadecimal digest, using your client secret as a key and the payload as the message. Our Ruby and Python libraries provide sample implementations of this check.
List your subscriptions
If you’d like to see your current subscriptions, all you have to do is make a GET request to the /subscriptions endpoint
https://api.instagram.com/v1/subscriptions?client_secret=CLIENT-SECRET&client_id=CLIENT-ID
You will recieve the following response:
{
"meta": {
"code": 200
},
"data": [
{
"id": "1",
"type": "subscription",
"object": "user",
"aspect": "media",
"callback_url": "http://your-callback.com/url/"
},
{
"id": "2",
"type": "subscription",
"object": "location",
"object_id": "2345",
"aspect": "media",
"callback_url": "http://your-callback.com/url/"
}
]
}
Delete Subscriptions
To delete subscriptions, you make a DELETE request to the subscriptions endpoint. You can clear subscriptions either by object type or subscription ID, by specifying an “object” or “id” URL parameter respectively. You can clear all your current subscriptions by passing “object=all”.
curl -X DELETE 'https://api.instagram.com/v1/subscriptions?client_secret=CLIENT-SECRET&object=all&client_id=CLIENT-ID'
If you’d like to remove a specific subscription, just include the ID of the subscription as a parameter:
curl -X DELETE 'https://api.instagram.com/v1/subscriptions?client_secret=CLIENT-SECRET&id=1&client_id=CLIENT-ID'
And finally, if you’d like to remove all subscriptions of a certain object type, you may include the object type:
curl -X DELETE 'https://api.instagram.com/v1/subscriptions?client_secret=CLIENT-SECRET&object=tag&client_id=CLIENT-ID'
Source: https://instagram.com/developer/realtime/#