The API is based on the query language GraphQL. This language is used by Instagram for its APIs, so it is the best way to mimic Graph API. You can get more info by the following links:
Relay Cursor Connections Specification
We are launching a new Hashtag Search feature for Businesses on Instagram. With this new feature, businesses will still be able to discover content, measure the reach of their marketing campaigns, and understand the public sentiment around their brand.
With deprecation date for Hashtag Search via Instagram in mind, our team has been working to create an API which enables appropriate business use-cases, while protecting user privacy and safety.
To learn more, please check our developer documentation and contact us.
We use Graph API style for requests. API accepts only GET requests. The access token is provided by us. Instagram API request takes the following form:
https://api.singularex.com/instagram/
<node-type>/<node-ID>
?fields=<graph-request>
&access_token=<your_access_token>
https://api.singularex.com/instagram/
media/1770093817144369706
?fields=id,shortcode,created_time,media_url
&access_token=<your_access_token>
https://api.singularex.com/instagram/
tag/juice
?fields=id,media_count,profile_pic_url,last_update,is_being_updated
&access_token=<your_access_token>
https://api.singularex.com/instagram/
user/spacex
?fields=id,username,media.first(1){edges{node{shortcode,created_time,timestamp,media_type,media_url,caption,
tagged_user_media,tagged_user_text,tags,like_count,comment_count,video_view_count,
location{id,name,slug,has_public_page},
owner{id,username,full_name,profile_pic_url},
comments.first(1){edges{node{id,parent_id,created_time,timestamp,text,
owner{id,username,full_name,profile_pic_url}}}}}}}
&access_token=<your_access_token>
Certain parameters are required while others are optional. As is standard in URLs, all parameters are separated using the ampersand (&) character.
https://api.singularex.com/instagram/
media/<media-ID or media-shortcode>
?fields=<graph-request>
&access_token=<your_access_token>
{
media: InstagramMedia {
id: ID
shortcode: String
created_time: Datetime # ISO 8601 format
timestamp: Int # UNIX timestamp
media_type: String
media_url: String
caption: [String]
tagged_user_media: [String]
tagged_user_text: [String]
tags: [String]
like_count: Int
comment_count: Int
video_view_count: Int
owner_id: ID
location_id: ID
last_update: Int # UNIX timestamp
is_being_updated: Boolean
location: InstagramLocation {
id: ID
name: String
slug: String
has_public_page: Boolean
}
owner: InstagramNodeOwner {
id: ID
username: String
profile_pic_url: String
type: String
full_name: String
}
comments: InstagramCommentsConnection {
page_info: PageInfo {
has_next_page: Boolean
has_previous_page: Boolean
start_cursor: String
end_cursor: String
}
edges: Edges {
node: InstagramComment {
id: ID
parent_id: ID # ID of parent media
created_time # ISO 8601 format
timestamp # UNIX timestamp
text: String
owner_id: ID
last_update: Int # UNIX timestamp
is_being_updated: Boolean
owner: InstagramNodeOwner {
id: ID
username: String
profile_pic_url: String
type: String
full_name: String
}
}
}
}
}
}
All filters must be sent as separate GET-params in request URL, for example:
&from_date=2019-06-20&to_date=2019-06-25 or
&from_timestamp=1540000000&to_timestamp=1550000000
https://api.singularex.com/instagram/
user/<username>
?fields=<graph-request>
&access_token=<your_access_token>
{
user: InstagramUser {
id: ID
username: String
profile_pic_url: String
type: String
full_name: String
biography: String
external_url: String
connected_fb_page: String
is_private: Boolean
is_verified: Boolean
follower_count: Integer
follow_count: Integer
media_count: Integer
saved_media_count: Integer
collection_count: Integer
last_update: Int # UNIX timestamp
is_being_updated: Boolean
media: InstagramMediaConnection {
page_info: PageInfo {
has_next_page: Boolean
has_previous_page: Boolean
start_cursor: String
end_cursor: String
}
edges: Edges {
node: InstagramMedia {
...
# Same fields as in the instagram.media
...
}
}
}
}
}
All filters must be sent as separate GET-params in request URL, for example:
&from_date=2019-06-20&to_date=2019-06-25 or
&from_timestamp=1540000000&to_timestamp=1550000000
https://api.singularex.com/instagram/
tag/<tag-name>
?fields=<graph-request>
&access_token=<your_access_token>
{
tag: InstagramTag {
id: String # tag name without hashtag symbol
profile_pic_url: String
media_count: Int
last_update: Int # UNIX timestamp
is_being_updated: Boolean
media: InstagramMediaConnection {
page_info: PageInfo {
has_next_page: Boolean
has_previous_page: Boolean
start_cursor: String
end_cursor: String
}
edges: Edges {
node: InstagramMedia {
…
# Same fields as in the instagram.media
…
}
}
}
}
}
For example, to get info about media with tag #juice you need to make the next request:
https://api.singularex.com/instagram/
tag/juice
?fields=id,media_count,profile_pic_url,last_update,is_being_updated
&access_token=<your_access_token>
{
"error": {},
"data": {
"id": "juice",
"media_count": 7979876,
"profile_pic_url": "https://scontent-frx5-1.cdninstagram.com/vp/53bf5417386018688db2026becc5e1b2/5D7CE102/t51.2885-15/e35/c0.180.1440.1440a/s150x150/59967397_1041572172698184_788691368965451057_n.jpg?_nc_ht=scontent-frx5-1.cdninstagram.com",
"last_update": 1559150950,
"is_being_updated": false
},
"status": "ok"
}
For example, to get info about media with ID=1770093817144369706 you need to make the next request:
https://api.singularex.com/instagram/
media/1770093817144369706
?fields=id,shortcode,created_time,media_url
&access_token=<your_access_token>
{
"error": {},
"data": {
"id": "1770093817144369706",
"shortcode": "BiQovLGAWIq",
"created_time": "2018-05-02T03:27:28",
"media_url": "https://scontent-arn2-1.cdninstagram.com/vp/fad582c6f3702b6dc555acd344faef47/5D280A56/t51.2885-15/e35/30841940_161598917841784_3832690349499744256_n.jpg?_nc_ht=scontent-arn2-1.cdninstagram.com"
},
"status": "ok"
}
If you want to get info about media’s owner, just add one more field:
https://api.singularex.com/instagram/
media/1770093817144369706
?fields=id,shortcode,created_time,media_url,
owner{id,username,profile_pic_url}
&access_token=<your_access_token>
{
"error": {},
"data": {
"id": "1770093817144369706",
"shortcode": "BiQovLGAWIq",
"created_time": "2018-05-02T03:27:28",
"media_url": "https://scontent-arn2-1.cdninstagram.com/vp/fad582c6f3702b6dc555acd344faef47/5D280A56/t51.2885-15/e35/30841940_161598917841784_3832690349499744256_n.jpg?_nc_ht=scontent-arn2-1.cdninstagram.com",
"owner": {
"id": "3008836221",
"username": "teslamotorsports",
"profile_pic_url": "https://scontent-arn2-1.cdninstagram.com/vp/d3c0da6a1364fbc4c6a1ee22548177c7/5D12A1B2/t51.2885-19/s150x150/36136080_195401041310743_524733991551500288_n.jpg?_nc_ht=scontent-arn2-1.cdninstagram.com"
}
},
"status": "ok"
}
And first comment + owner info for comment:
https://api.singularex.com/instagram/
media/1770093817144369706
?fields=id,shortcode,created_time,owner{id,username},
comments.first(1){edges{node{id,text,owner{id,username}}}}
&access_token=<your_access_token>
{
"error": {},
"data": {
"id": "1770093817144369706",
"shortcode": "BiQovLGAWIq",
"created_time": "2018-05-02T03:27:28",
"owner": {
"id": "3008836221",
"username": "teslamotorsports"
},
"comments": {
"edges": [
{
"node": {
"id": "17927679481127546",
"timestamp": 1525641658,
"last_update": 1551696861,
"is_being_updated": false,
"text": "Those brake pads ????",
"owner": {
"id": "527779220",
"username": "steffenology"
}
}
}
]
}
},
"status": "ok"
}
To get next pages use page_info’s fields has_next_page, has_previous_page, start_cursor, end_cursor. You can get more info by following the link: Relay Cursor Connections Specification
The has_next_page and has_previous_page values are false in the case when your request displays all available media. The following endpoints should only be used with restrictions such as media.first(5) or media.last(10).
For example, to get the next 5 media, use the value end_cursor in the endpoint such as media.first(5).after(“end_cursor”). The end_cursor value is taken from the previous request such as media.first(5).
To get the previous 5 media, use the value start_cursor in the endpoint such as media.last(5).before(“start_cursor”). The start_cursor value is taken from the previous request such as media.last(5).
https://api.singularex.com/instagram/
tag/photography
?fields=id,
media.first(3){page_info{has_next_page,start_cursor,end_cursor},edges{node{id}}}
&access_token=<your_access_token>
{
"error": {},
"data": {
"id": "photography",
"media": {
"page_info": {
"has_next_page": true,
"start_cursor": "YXJyYXljb25uZWN0aW9uOjA=",
"end_cursor": "YXJyYXljb25uZWN0aW9uOjI="
},
"edges": [
{
"node": {
"id": "2065332295327345047",
"timestamp": 1560426817,
"last_update": 1560427709,
"is_being_updated": false
}
},
{
"node": {
"id": "2065330707747587078",
"timestamp": 1560426628,
"last_update": 1560427712,
"is_being_updated": false
}
},
{
"node": {
"id": "2065325341622271037",
"timestamp": 1560425988,
"last_update": 1560426993,
"is_being_updated": false
}
}
]
}
},
"status": "ok"
}
https://api.singularex.com/instagram/
tag/photography
?fields=id,
media.first(3).after("YXJyYXljb25uZWN0aW9uOjI="){page_info{has_next_page,start_cursor,end_cursor},edges{node{id}}}
&access_token=<your_access_token>
{
"error": {},
"data": {
"id": "photography",
"media": {
"page_info": {
"has_next_page": true,
"start_cursor": "YXJyYXljb25uZWN0aW9uOjM=",
"end_cursor": "YXJyYXljb25uZWN0aW9uOjU="
},
"edges": [
{
"node": {
"id": "2065325342754604765",
"timestamp": 1560425988,
"last_update": 1560426991,
"is_being_updated": false
}
},
{
"node": {
"id": "2065325341632498158",
"timestamp": 1560425988,
"last_update": 1560426996,
"is_being_updated": false
}
},
{
"node": {
"id": "2065325341395840663",
"timestamp": 1560425988,
"last_update": 1560426990,
"is_being_updated": false
}
}
]
}
},
"status": "ok"
}
Responses are encoded in JSON format and have 3 fields: status, data, and error.
https://api.singularex.com/instagram/
media/1770093817144369706
?fields=id,shortcode,created_time,owner{id,username}
{
"error": {},
"data": {
"id": "1770093817144369706",
"shortcode": "BiQovLGAWIq",
"created_time": "2018-05-02T03:27:28",
"owner": {
"id": "3008836221",
"username": "teslamotorsports"
}
},
"status": "ok"
}
RequestAccepted (HTTP response: 202 Accepted)
Cannot find the requested node in a cache. Starting the parsing process. Repeat request later.
{
"error": {
"message": "Some nodes you requested are being loaded now: 12345. Try again later",
"type": "RequestAccepted"
},
"data": {},
"status": "accepted"
}
InvalidRequestError (HTTP response: 400 Bad Request)
The graph request is invalid. Repeat request later
{
"error": {
"message": "Cannot query field \"id_\" on type \"Media\". Did you mean \"id\"?",
"type": "InvalidRequestError"
},
"data": {},
"status": "InvalidRequestError"
}
AuthenticationError (HTTP response: 403 Forbidden)
The access token examination has failed. The access token is not provided or invalid.
{
"error": {
"message": "Invalid access token",
"type": "AuthenticationError"
},
"data": {},
"status": "AuthenticationError"
}
NodeNotExistsError (HTTP response: 404 Not Found)
A page for the requested node does not exist or cannot be loaded.
{
"error": {
"message": "Some nodes you requested cannot be loaded: 1690",
"type": "NodeNotExistsError"
},
"data": {},
"status": "NodeNotExistsError"
}
InternalServerError (HTTP response: 500 Internal Server Error)
Something was wrong on our side.
{
"error": {
"message": "Internal server error",
"type": "InternalServerError"
},
"data": {},
"status": "InternalServerError"
}