Task
I'm trying to retrieve all Ad Campaign, Adsets and Ads from various accounts associated with our Business Manager.
Issue
The specific endpoints that I'm accessing are:
https://graph.facebook.com/v2.8/act_xxxxxxxxxxxxx/campaigns
https://graph.facebook.com/v2.8/act_xxxxxxxxxxxxx/adsets
https://graph.facebook.com/v2.8/act_xxxxxxxxxxxxx/ads
When I query some of these accounts for all Campaigns using the filter parameter,
[{'operator': 'IN',
'field': 'ad.effective_status',
'value': [
'ACTIVE',
'PAUSED',
'DELETED',
'PENDING_REVIEW',
'DISAPPROVED',
'PREAPPROVED',
'PENDING_BILLING_INFO',
'CAMPAIGN_PAUSED',
'ARCHIVED',
'ADSET_PAUSED']}]
the Facebook API always returns this error:
{"error":{"code":1,"message":"Please reduce the amount of data you're asking for, then retry your request"}}
Troubleshooting
I've used various values for the filter parameter such as 1, 25, 50, 100, 500.
I've tried limiting the date using the date_preset parameters (this seems irrelevant).
I've tried limiting the queries by filtering down to individual campaigns by including {'operator': 'IN','field':'campaign.id','value':['xxxxxxxxxxxxx']} as an additional filter in the filter parameter.
I've attempted batch requests and querying the /insights endpoint, but I haven't had one work yet.
Other Details
When I only include ACTIVE campaigns in the filter, the query works. This has allowed me to deduce that the DELETED campaigns are the problem. In other words, these accounts have a ton of DELETED campaigns.
I'm making my requests using Postman Version 5.0.0 (5.0.0).
I imagine if I can figure out how to get the Campaigns, the Adsets and Ads will be similar. How do I go about resolving this?
The reason is that the API does not actually support querying for deleted objects for certain endpoints. I tried to obtain all campaigns for a certain account and this is the response.
Method: GET
Path:
https://graph.facebook.com/v2.10/act_XXXX/campaigns
Params: {'effective_status': '["ACTIVE","PAUSED","DELETED","ARCHIVED"]', 'fields': 'id,name,status', 'summary': 'true'}
Response:
{
"error": {
"code": 100,
"is_transient": false,
"error_subcode": 1815001,
"error_user_msg": "Requesting for deleted objects is not supported in this endpoint.",
"error_user_title": "Cannot Request for Deleted Objects",
"message": "Invalid parameter",
"type": "OAuthException",
"fbtrace_id": "FYDwMABcwxj"
}
}
After looking at the documentation I discovered this
https://developers.facebook.com/docs/marketing-api/best-practices/storing_adobjects
And here they state
If you keep the deleted object id, you can continue to retrieve the
stats or object details by individually querying the object ID.
However you cannot retrieve the deleted objects as a connection object
from a non deleted node/object.
Related
How I can update the inventory (stock_level) using (business manager API).
I use the business manager API to retrieve products. I am able to retrieve the products but I am not sure how I can set its stock (stock_level).
I have a special requirement where product quantity cannot exceed 1, so for that I need to set it in an inventory so that I can test it.
I have tried to see if I can set inventory level using product but that doesn't seem possible.
When I try to get inventory following is the error
{
"_v": "18.8",
"fault": {
"arguments": {
"method": "GET",
"path": "/data/v18_8/inventory_lists/*"
},
"type": "ClientAccessForbiddenException",
"message": "Access to resource 'GET /data/v18_8/inventory_lists/*' is not allowed for the current client."
}
}
There is actually a DATA API endpoint that can be used to update inventory. It is called the ProductInventoryRecords resource.
You can update a product inventory record with a PATCH eg:
PATCH /inventory_lists/{inventory_list_id}/product_inventory_records/{product_id}
With a ProductInventoryRecordAllocation payload as such:
{
"_resource_state" : "847f9c3c5867f641470b3046aeec31f07757991b792d722e10079926f7a289fb",
"allocation": {
"amount": 2000,
"reset_date": "2016-03-31T14:05:40.872Z"
}
}
See more about this document type here.
Please note that the best practice is to pass the _resource_state key to ensure that the record is properly updated. OCAPI checks to see if this value is the same as the current state of the record if that attribute provided.
So systems should first check the record to get the _resource_state by performing a GET on the same resource.
Edit Note that you'll need an authorization token that grants you access to the API in order to make this kind of call.
your question is not crystal clear but I will try to answer. Commerce Cloud has three distinct (OCAPI) APIs:
Shop API (provides similar access as a customer on the site)
Data API (provides similar access as a merchant using business manager)
Meta API (describes the API from a functional perspective)
To get availability of a product in the inventory use below call: {{shop_url}}/products/701644676568M/availability and look at ATS in the response.
To set the stocklevel go into to business manager or use business manager import utility. There is no out-of-the-box API to update the stocklevel.
There is a change to our business logic, where earlier with one of the APIs we use to return a list, for eg. list of employees. Recently we introduced authorization checks, to see if a particular user has permission to view a specific employee.
If say there are 10 employees that should be returned through method GET, due to the missing permission only 5 are returned. The request itself in this case is successful. I am currently not sure how to pass on the information back to the client that there were 5 employees that are filtered out due to missing permission.
Should this be mapped to HTTP status codes? If yes, which status code fits this? Or this is not an error at all?
What would be the best approach in this case?
A status code by itself wouldn't be sufficient to indicate the partial response. The status code 206 sounds close by name but is used when a client specifically requests a partial set of data based on headers.
Use 200. The request was fulfilled successfully after all, and the reason for the smaller set of data is proprietary to your API so extra metadata in the response to indicate a message might be sufficient.
Assuming JSON response:
{
"data": [ ... ],
"messages": [
"Only some data was returned due to permissions."
]
}
If you have many consumers and are worried about backward compatibility you may also want to provide a vendor specific versioned JSON media type:
"Content-Type": "application/vnd.myorg-v2+json"
I'm making API calls to retrieve simple data from Facebook pages:
/[page_id]?fields=likes,talking_about_count,checkins
I know I can get multiple results by providing multiple ids using the 'ids' variable:
/?ids=[page_id],[page_id],[page_id]&fields=likes,talking_about_count,checkins
My problem is that I don't how many ids I can retrieve simultaneously. I know the limit for batched request is 50, but I can't find the documentation for the 'ids' variable.
UPDATE: it seems like this limit has been removed on version 2.0 of the graph API, but I am still looking for an official answer.
I used Graph Explorer to list all post ids on a page. It returned me 140 posts.
I then sent those 140 posts to the Graph API using the ids parameter and got this in return:
{
"error": {
"message": "(#100) Too many IDs. Maximum: 50. Provided: 140.",
"type": "OAuthException",
"code": 100
}
}
So the answer is currently 50.
Facebook Graph API Limit Documentation
I have a RESTful API within a web-service with resources such as users, posts and so on. When I make a request for a list of posts (GET /posts), I want to retrieve an array of posts only with limited data for each post (i.e. subject, author name). When I make a request for a concrete post (GET /posts/42) I want to retrieve the full list of post object fields, including big post body, additional info about likes count, comments count.
I suppose there exist many ways to solve this problem.
In my mind, the three most obvious are:
Explicitly specify a fields list on every request
(/posts?fields=subject,author_name and
/posts/42?fields=subject,body,createAt,author_name,comments_count,likes_count, etc...).
Explicitly specify a fields list only if it differs from the default fields list.
Specify a fields list that should be excluded (or included) from (to)
the default fields set if the desired fields set differs from the default.
I want to build a clear and useful API for my customers. Which way should I choose?
I'd go for option 2 IMHO.
So if the consumer just requests the resource url (/posts/42) they receive the default fields.
Then consumers can alter the default response by defining values in the query string like:
/posts/42/fields?subject,author_name
This has worked well for me in the past and is how some other well know APIs work, e.g. Facebook
Edit: Looking back at this I’d change the request to be:
/posts/42?fields=subject,author_name
/post/42 is the resource, not fields.
Have been doing research into this as well and was pointed towards Facebook's GraphQL as an alternative to requesting a restful api with the fields wanted. It is still in the very early stages but seems very promising.
https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html
EDIT:
Reproduced from the URL:
A GraphQL query is a string interpreted by a server that returns data in a specified format. Here is an example query:
{
user(id: 3500401) {
id,
name,
isViewerFriend,
profilePicture(size: 50) {
uri,
width,
height
}
}
}
(Note: this syntax is slightly different from previous GraphQL examples. We've recently been making improvements to the language.)
And here is the response to that query.
{
"user" : {
"id": 3500401,
"name": "Jing Chen",
"isViewerFriend": true,
"profilePicture": {
"uri": "http://someurl.cdn/pic.jpg",
"width": 50,
"height": 50
}
}
}
I want to perform search queries using Youtube API v3.
What I need is to retrieve video ids and statistics for each video.
From the docs I can see that statistics is not returned for video items. If I try to ask for statistics using this query:
https://www.googleapis.com/youtube/v3/search?type=video&part=snippet,statistics&q=kittens&key={MY_KEY}
I receive an error:
{
"error": {
"errors": [
{
"domain": "youtube.part",
"reason": "unknownPart",
"message": "statistics",
"locationType": "parameter",
"location": "part"
}
],
"code": 400,
"message": "statistics"
}
}
So I guess that I need to make two requests:
Perform actual search and retrieve list of video ids.
Make API request https://developers.google.com/youtube/v3/docs/videos/list to retrieve statistics for each video.
Or maybe I'm missing something and there's a way to get statistics for videos within one search query?
In the guide, they specify "the part names that you can include in the parameter value are id and snippet" when using https://www.googleapis.com/youtube/v3/search. (statistics is not an accepted value).
So I think that you have to make two requests as you say, at least that is what I'm doing. I couldn't find any other solution. I would be interested to know if there was a workaround...
To avoid redundancy of data returned and not to use bandwidth with extra data, "video search data" and "video statistics" data are decoupled in API.
You are right about two calls.
In general, to get faster response, only use the "part" s in request that you will use in your application.