App reviews, troubleshooting, and recommendations
Heya folks!
Problem: POST requests are not posting. Are returning 200 and GET response instead of 201 and POST response.
Expectation: 201 POST New resource created. A new price rule is created with a return giving, among other things, its ID.
Reality: 200 GET of all price rules. No change to list of price rules or discount codes.
I have this here (sanitized) Google Apps Script based code:
var accessToken = '{my_access_token}'; function createPriceRule() { var shopName = '{my_shop_name}'; var url = 'https://' + shopName + '.myshopify.com/admin/api/2023-10/price_rules.json'; var headers = { "X-Shopify-Access-Token": accessToken, 'Content-Type': 'application/json', "Cookie": "" }; var payload = { 'price_rule': { "title": "abcdefg", "target_type": "order", "target_selection": "all", "allocation_method": "across", "value_type": "percentage", "value": "-100.0", "customer_selection": "all", "starts_at": "2023-01-01T00:00:00Z" } }; var options = { 'method': 'post', 'headers': headers, 'payload': JSON.stringify(payload) }; try { var response = UrlFetchApp.fetch(url, options); Logger.log("Response Code: " + response.getResponseCode()); Logger.log("Response Content: " + response.getContentText()); } catch (e) { Logger.log("Exception: " + e.toString()); } }
For context, I created this custom app through the shopify admin via settings > apps and sales channels > develop apps > create an app. I created this app on Jan 4th 2024 and it is now Jan 6th 2024
I know the following to be true and triple checked:
- I am using the correct access token.
- I have the proper scopes set (I have over shot on purpose)
- I am using the "X-Shopify-Access-Token" header
- I am not passing any cookies in my request because by default Google apps script does not pass cookies, but I doubled down and passed an empty cookies parameter. (as part of attempting to troubleshoot this)
- This request also is not functioning in curl, postman, or php for me.
I am thinking I am experiencing some sort of bug or "new access token blockage". Any help here would be greatly appreciated because I am pulling my hair out over what should be a simple non-oauth2 basic access token driven API call.
Solved! Go to the solution
This is an accepted solution.
I figured it out!
So for some reason when it in https://reqbin.com/ I was able to run it under myshopname.myshopify.com and it returned just fine. Great!
I got frustrated with Google Apps Script, so I made an endpoint on my server and wrote what I just got working in reqbin in PHP....
php returned a 301....redirect. Weird. So I examined the entirety of the php and found out that it was redirecting to a different url within my schema. I am not sure why it is doing this because that is not the first domain on the shopify account, BUT I reran it in google apps script and used the new URL and it worked.
I am so dumbfounded as to why there is a redirect when i was petitioning example.myshopify.com over to example-dash-example.myshopify.com when example.myshopify.com is the actual domain that everything else redirects to.
I don't think it is a scope or access token problem since it is at least connecting and getting some type of valid 200 response back. If it isn't triggering the create, then I feel like this would be an issue with your request format or the data being sent... I would focus your search there.
I was able to get a 201 when using the following curl:
curl -X POST "https://{your-shop-name}.myshopify.com/admin/api/2023-10/price_rules.json" \
-H "Content-Type: application/json" \
-H "X-Shopify-Access-Token: {your-access-token}" \
-d '{
"price_rule": {
"title": "New Price Rule",
"target_type": "line_item",
"target_selection": "all",
"allocation_method": "across",
"value_type": "fixed_amount",
"value": "-10.0",
"customer_selection": "all",
"starts_at": "2024-01-01"
}
}'
response:
Status:
201 (Created)
Time:
208 ms
Size:
1.01 kb
Content (39)
Headers (36)
Raw (38)
JSON
Timings
{
"price_rule": {
"id": 1399987994862,
"value_type": "fixed_amount",
"value": "-10.0",
"customer_selection": "all",
"target_type": "line_item",
"target_selection": "all",
"allocation_method": "across",
"allocation_limit": null,
"once_per_customer": false,
"usage_limit": null,
"starts_at": "2023-12-31T16:00:00-08:00",
"ends_at": null,
"created_at": "2024-01-06T23:36:58-08:00",
"updated_at": "2024-01-06T23:36:58-08:00",
"entitled_product_ids": [],
"entitled_variant_ids": [],
"entitled_collection_ids": [],
"entitled_country_ids": [],
"prerequisite_product_ids": [],
"prerequisite_variant_ids": [],
"prerequisite_collection_ids": [],
"customer_segment_prerequisite_ids": [],
"prerequisite_customer_ids": [],
"prerequisite_subtotal_range": null,
"prerequisite_quantity_range": null,
"prerequisite_shipping_price_range": null,
"prerequisite_to_entitlement_quantity_ratio": {
"prerequisite_quantity": null,
"entitled_quantity": null
},
"prerequisite_to_entitlement_purchase": {
"prerequisite_amount": null
},
"title": "New Price Rule",
"admin_graphql_api_id": "gid:\/\/shopify\/PriceRule\/1399987994862"
}
}
The only thing for me, is check to make sure this is the correct format
starts_at": "2023-01-01T00:00:00Z
I notice you are sending a
"Starts at: 2024-01-01"
But receiving a
""starts_at": "2023-12-31T16:00:00-08:00"
Is this due to the unspecified time parameter?
And how does shopify want me to send time parameters.
Also I think it might be a little deeper than this, because I am getting the same exact error on POST, PUT and DELETEs as well, which I were I started looking for problems with access tokens.
Access token or scopes will return a 403 forbidden response. I just tried with incorrect scopes.
Yes. I tried that as well using this page as my reference
https://shopify.dev/docs/api/usage/response-codes
Also,
I updated the time param, like this:
var accessToken = '{my_access_token}';
function createPriceRule() {
var shopName = '{my_shop_name}';
var url = 'https://' + shopName + '.myshopify.com/admin/api/2023-10/price_rules.json';
var headers = {
"X-Shopify-Access-Token": accessToken,
'Content-Type': 'application/json',
"Cookie": ""
};
var payload = {
'price_rule': {
"title": "abcdefg",
"target_type": "order",
"target_selection": "all",
"allocation_method": "across",
"value_type": "percentage",
"value": "-100.0",
"customer_selection": "all",
"starts_at": "2024-01-07"
}
};
var options = {
'method': 'post',
'headers': headers,
'payload': JSON.stringify(payload)
};
try {
var response = UrlFetchApp.fetch(url, options);
Logger.log("Response Code: " + response.getResponseCode());
Logger.log("Response Content: " + response.getContentText());
} catch (e) {
Logger.log("Exception: " + e.toString());
}
}
and I am still receiving the same exact problem. 200 code. No 201, no return like what you are showing.
Did you make a brand new access token to test this, or was this an existing token?
Also for anyone else who may stumble across this, I also tried the time code of "2023-12-31T16:00:00-08:00", which is what is listed in the response of @SomeUsernameHe's 201 return
and your responses come with no other information besides the 200, OK?
I figured it out, your target type is invalid.
target_type can only be "line_item" or "shipping_line"
The target type that the price rule applies to. Valid values:
Hide target_type properties
line_item: The price rule applies to the cart's line items.
shipping_line: The price rule applies to the cart's shipping lines.
with the following curl:
curl -X POST "https://your-shop-name.myshopify.com/admin/api/2023-10/price_rules.json" \
-H "Content-Type: application/json" \
-H "X-Shopify-Access-Token: your-access-token" \
-d '{
"price_rule": {
"title": "abcdefg",
"target_type": "line_item",
"target_selection": "all",
"allocation_method": "across",
"value_type": "percentage",
"value": "-100.0",
"customer_selection": "all",
"starts_at": "2024-01-07"
}
}'
returns a 201:
Status:
201 (Created)
{
"price_rule": {
"id": 1400074207470,
"value_type": "percentage",
"value": "-100.0",
"customer_selection": "all",
"target_type": "line_item",
"target_selection": "all",
"allocation_method": "across",
"allocation_limit": null,
"once_per_customer": false,
"usage_limit": null,
"starts_at": "2024-01-06T16:00:00-08:00",
"ends_at": null,
"created_at": "2024-01-07T11:01:40-08:00",
"updated_at": "2024-01-07T11:01:40-08:00",
"entitled_product_ids": [],
"entitled_variant_ids": [],
"entitled_collection_ids": [],
"entitled_country_ids": [],
"prerequisite_product_ids": [],
"prerequisite_variant_ids": [],
"prerequisite_collection_ids": [],
"customer_segment_prerequisite_ids": [],
"prerequisite_customer_ids": [],
"prerequisite_subtotal_range": null,
"prerequisite_quantity_range": null,
"prerequisite_shipping_price_range": null,
"prerequisite_to_entitlement_quantity_ratio": {
"prerequisite_quantity": null,
"entitled_quantity": null
},
"prerequisite_to_entitlement_purchase": {
"prerequisite_amount": null
},
"title": "abcdefg",
"admin_graphql_api_id": "gid:\/\/shopify\/PriceRule\/1400074207470"
}
}
I was very excited to try this when i got home.
I made that change and
var accessToken = '{accesstoken}';
function createPriceRule() {
var shopName = '{shopname}';
var url = 'https://' + shopName + '.myshopify.com/admin/api/2024-01/price_rules.json';
var headers = {
"X-Shopify-Access-Token": accessToken,
'Content-Type': 'application/json',
"Cookie": ""
};
var payload = {
'price_rule': {
"title": "abcdefg",
"target_type": "line_item",
"target_selection": "all",
"allocation_method": "across",
"value_type": "percentage",
"value": "-100.0",
"customer_selection": "all",
"starts_at": "2023-12-31T16:00:00-08:00",
}
};
var options = {
'method': 'post',
'headers': headers,
'payload': JSON.stringify(payload)
};
try {
var response = UrlFetchApp.fetch(url, options);
Logger.log("Response Code: " + response.getResponseCode());
Logger.log("Response Content: " + response.getContentText());
} catch (e) {
Logger.log("Exception: " + e.toString());
}
}
....still not working for me 😞
I even tried copying your Curl and running that.
Remove the comma after start_at:
change this:
"starts_at": "2023-12-31T16:00:00-08:00",
to this:
"starts_at": "2023-12-31T16:00:00-08:00"
Oh shoot. That was actually a typo here and not in my code as I had tried a few more things since then, but reverted back to paste this version. That comma is not present in the code here:
var accessToken = '{access}';
function createPriceRule() {
var shopName = '{shopname}';
var url = 'https://' + shopName + '.myshopify.com/admin/api/2024-01/price_rules.json';
var headers = {
"X-Shopify-Access-Token": accessToken,
'Content-Type': 'application/json',
"Cookie": ""
};
var payload = {
'price_rule': {
"title": "abcdefg",
"target_type": "line_item",
"target_selection": "all",
"allocation_method": "across",
"value_type": "percentage",
"value": "-100.0",
"customer_selection": "all",
"starts_at": "2023-12-31T16:00:00-08:00"
}
};
var options = {
'method': 'post',
'headers': headers,
'payload': JSON.stringify(payload)
};
try {
var response = UrlFetchApp.fetch(url, options);
Logger.log("Response Code: " + response.getResponseCode());
Logger.log("Response Content: " + response.getContentText());
} catch (e) {
Logger.log("Exception: " + e.toString());
}
I am positive this is the version I just ran because I copied it direct and sanitized it here.
I guess it may be helpful to see a log, but really it is as described at the beginning of the post:
11:00:49 PM Info Response Code: 200
11:00:49 PM Info Logging output too large. Truncating output. Response Content: {"price_rules":[{"id":1441878638875,"value_type":"percentage","value":"-100.0","customer_selection":"all","target_type":"line_item","target_selection":"all","allocation_method":"across","allocation_limit":null,"once_per_customer":false,"usage_limit":null,"starts_at":"2024-01-08T00:00:00-05:00","ends_at":"2024-01-08T23:59:59-05:00","created_at":"2024-01-05T16:15:07-05:00","updated_at":"2024-01-05T16:16:59-05:00","entitled_product_ids":[],"entitled_variant_ids":[],"entitled_collection_ids":[],"entitled_country_ids":[],"prerequisite_product_ids":[],"prerequisite_variant_ids":[],"prerequisite_collection_ids":[],"customer_segment_prerequisite_ids":[],"prerequisite_customer_ids":[],"prerequisite_subtotal_range":null,"prerequisite_quantity_range":null,"prerequisite_shipping_price_range":null,"prerequisite_to_entitlement_quantity_ratio":{"prerequisite_quantity":null,"entitled_quantity":null},"prerequisite_to_entitlement_purchase":{"prerequisite_amount":null},"title":"DISCOUNTCODE","admin_graphql_api_id":"gid:\/\/shopify\/PriceRule\/1441878638875"},{"id":1441878540571,"value_type":"percentage","value":"-100.0","customer_selection":"all","target_type":"line_item","target_selection":"all","allocation_method":"across","allocation_limit":null,"once_per_customer":false,"usage_limit":null,"starts_at":"2024-01-07T00:00:00-05:00","ends_at":"2024-01-07T23:59:59-05:00","created_at":"2024-01-05T16:14:29-05:00","updated_at":"2024-01-07T22:10:05-05:00","entitled_product_ids":[],"entitled_variant_ids":[],"entitled_collection_ids":[],"entitled_country_ids":[],"prerequisite_product_ids":[],"prerequisite_variant_ids":[],"prerequisite_collection_ids":[],"customer_segment_prerequisite_ids":[],"prerequisite_customer_ids":[],"prerequisite_subtotal_range":null,"prerequisite_quantity_range":null,"prerequisite_shipping_price_range":null,"prerequisite_to_entitlement_quantity_ratio":{"prerequisite_quantity":null,"entitled_quantity":null},"prerequisite_to_entitlement_purchase":{"prerequisite_amount":null},"title":"DISCOUNTCODE","admin_graphql_api_id":"gid:\/\/shopify\/PriceRule\/1441878540571"},{"id":1441877819675,"value_type":"percentage","value":"-100.0","customer_selection":"all","target_type":"line_item","target_selection":"all","allocation_method":"across","allocation_limit":null,"once_per_customer":false,"usage_limit":null,"starts_at":"2024-01-06T00:00:00-05:00","ends_at":"2024-01-06T23:59:59-05:00","created_at":"2024-01-05T16:08:48-05:00","updated_at":"2024-01-06T23:35:02-05:00","entitled_product_ids":[],"entitled_variant_ids":[],"entitled_collection_ids":[],"entitled_country_ids":[],"prerequisite_product_ids":[],"prerequisite_variant_ids":[],"prerequisite_collection_ids":[],"customer_segment_prerequisite_ids":[],"prerequisite_customer_ids":[],"prerequisite_subtotal_range":null,"prerequisite_quantity_range":null,"prerequisite_shipping_price_range":null,"prerequisite_to_entitlement_quantity_ratio":{"prerequisite_quantity":null,"entitled_quantity":null},"prerequisite_to_entitlement_purchase":{"prerequisite_amount":null},"title":"DISCOUNTCODE","admin_graphql_api_id":"gid:\/\/shopify\/PriceRule\/1441877819675"},{"id":1393172185371,"value_type":"fixed_amount","value":"-500.0","customer_selection":"all","target_type":"line_item","target_selection":"entitled","allocation_method":"across","allocation_limit":null,"once_per_customer":false,"usage_limit":1,"starts_at":"2023-06-14T20:42:43-04:00","ends_at":null,"created_at":"2023-06-14T20:42:43-04:00","updated_at":"2023-07-31T18:55:01-04:00","entitled_product_ids":[8048362946843],"entitled_variant_ids":[],"entitled_collection_ids":[],"entitled_country_ids":[],"prerequisite_product_ids":[],"prerequisite_variant_ids":[],"prerequisite_collection_ids":[],"customer_segment_prerequisite_ids":[],"prerequisite_customer_ids":[],"prerequisite_subtotal_range":null,"prerequisite_quantity_range":null,"prerequisite_shipping_price_range":null,"prerequisite_to_entitlement_quantity_ratio":{"prerequisite_quantity":null,"entitled_quantity":null},"prerequisite_to_entitlement_purchase":{"prerequisite_amount":null},"title":"DISCOUNTCODE","admin_graphql_api_id":"gid:\/\/shopify\/PriceRule\/1393172185371"},{"id":1388207636763,"value_type":"fixed_amount","value":"-500.0","customer_selection":"all","target_type":"line_item","target_selection":"entitled","allocation_method":"across","allocation_limit":null,"once_per_customer":false,"usage_limit":1,"starts_at":"2023-04-23T23:22:39-04:00","ends_at":null,"created_at":"2023-04-23T23:22:39-04:00","updated_at":"2023-04-23T23:25:02-04:00","entitled_product_ids":[8048362946843],"entitled_variant_ids":[],"entitled_collection_ids":[],"entitled_country_ids":[],"prerequisite_product_ids":[],"prerequisite_variant_ids":[],"prerequisite_collection_ids":[],"customer_segment_prerequisite_ids":[],"prerequisite_customer_ids":[],"prerequisite_subtotal_range":null,"prerequisite_quantity_range":null,"prerequisite_shipping_price_range":null,"prerequisite_to_entitlement_quantity_ratio":{"prerequisite_quantity":null,"entitled_quantity":null},"prerequisite_to_entitlement_purchase":{"prerequisite_amount":null},"title":"DISCOUNTCODE","admin_graphql_api_id":"gid:\/\/shopify\/PriceRule\/1388207636763"},{"id":1387254776091,"value_type":"fixed_amount","value":"-500.0","customer_selection":"all","target_type":"line_item","target_selection":"entitled","allocation_method":"across","allocation_limit":null,"once_per_customer":false,"usage_limit":1,"starts_at":"2023-04-11T16:50:30-04:00","ends_at":null,"created_at":"2023-04-11T16:50:30-04:00","updated_at":"2023-04-11T16:50:30-04:00","entitled_product_ids":[8048361931035],"entitled_variant_ids":[],"entitled_collection_ids":[],"entitled_country_ids":[],"prerequisite_product_ids":[],"prerequisite_variant_ids":[],"prerequisite_collection_ids":[],"customer_segment_prerequisite_ids":[],"prerequisite_customer_ids":[],"prerequisite_subtotal_range":null,"prerequisite_quantity_range":null,"prerequisite_shipping_price_range":null,"prerequisite_to_entitlement_quantity_ratio":{"prerequisite_quantity":null,"entitled_quantity":null},"prerequisite_to_entitlement_purchase":{"prerequisite_amount":null},"title":"DISCOUNTCODE","admin_graphql_api_id":"gid:\/\/shopify\/PriceRule\/1387254776091"},{"id":1384951382299,"value_type":"fixed_amount","value":"-500.0","customer_selection":"all","target_type":"line_item","target_selection":"entitled","allocation_method":"across","allocation_limit":null,"once_per_customer":false,"usage_limit":1,"starts_at":"2023-03-09T14:05:12-05:00","ends_at":null,"created_at":"2023-03-09T14:05:12-05:00","updated_at":"2023-03-09T14:05:12-05:00","entitled_product_ids":[8048362946843],"entitled_variant_ids":[],"entitled_collection_ids":[],"entitled_country_ids":[],"prerequisite_product_ids":[],"prerequisite_variant_ids":[],"prerequisite_collection_ids":[],"customer_segment_prerequisite_ids":[],"prerequisite_customer_ids":[],"prerequisite_subtotal_range":null,"prerequisite_quantity_range":null,"prerequisite_shipping_price_range":null,"prerequisite_to_entitlement_quantity_ratio":{"prerequisite_quantity":null,"entitled_quantity":null},"prerequisite_to_entitlement_purchase":{"prerequisite_amount":null},"title":"DISCOUNTCODE","admin_graphql_api_id":"gid:\/\/shopify\/PriceRule\/1384951382299"},{"id":1384951316763,"value_type":"fixed_amount","value":"-500.0","customer_selection":"all","target_type":"line_item","target_selection":"entitled","allocation_method":"across","allocation_limit":null,"once_per_customer":false,"usage_limit":1,"starts_at":"2023-03-09T14:05:03-05:00","ends_at":null,"created_at":"2023-03-09T14:05:03-05:00","updated_at":"2023-03-09T14:05:03-05:00","entitled_product_ids":[8048361931035],"entitled_variant_ids":[],"entitled_collection_ids":[],"entitled_country_ids":[],"prerequisite_product_ids":[],"prerequisite_variant_ids":[],"prerequisite_collection_ids":[],"customer_segment_prerequisite_ids":[],"prerequisite_customer_ids":[],"prerequisite_subtotal_range":null,"prerequisite_quantity_range":null,"prerequisite_shipping_price_range":null,"prerequisite_to_entitlement_quantity_ratio":{"prerequisite_quantity":null,"entitled_quantity":null
(the discount codes have been sanitized --just in case)
Like I said, It is like returning me a GET despite being a post
I have other apis that use this same methodology through google apps script, so I know the post works as expected.
For this one, maybe try this really quick:
var accessToken = '{access}';
function createPriceRule() {
var shopName = '{shopname}';
var url = 'https://' + shopName + '.myshopify.com/admin/api/2024-01/price_rules.json';
var headers = {
"X-Shopify-Access-Token": accessToken,
'Content-Type': 'application/json'
};
var payload = {
'price_rule': {
"title": "abcdefg",
"target_type": "line_item",
"target_selection": "all",
"allocation_method": "across",
"value_type": "percentage",
"value": "-100.0",
"customer_selection": "all",
"starts_at": "2023-12-31T16:00:00-08:00"
}
};
var options = {
'method': 'post',
'headers': headers,
'payload': JSON.stringify(payload),
'muteHttpExceptions': true
};
try {
var response = UrlFetchApp.fetch(url, options);
var responseCode = response.getResponseCode();
var responseBody = response.getContentText();
if (responseCode === 201) {
Logger.log("Price rule created successfully: " + responseBody);
} else {
Logger.log("Response Code: " + responseCode);
Logger.log("Response Content: " + responseBody);
}
} catch (e) {
Logger.log("Exception: " + e.toString());
}
}
If you are still getting a 200, then I would reach our directly to shopify support and see if it is a bug with this specific store.
You can also go to this site: https://reqbin.com/curl
and test with this known working code:
curl -X POST "https://your-shop-name.myshopify.com/admin/api/2023-10/price_rules.json" \
-H "Content-Type: application/json" \
-H "X-Shopify-Access-Token: your-access-token" \
-d '{
"price_rule": {
"title": "abcdefg",
"target_type": "order",
"target_selection": "all",
"allocation_method": "across",
"value_type": "percentage",
"value": "-100.0",
"customer_selection": "all",
"starts_at": "2024-01-07"
}
}'
Just replace the access token and your shop. If this works, you know it is not an issue with the API but your code.
This is an accepted solution.
I figured it out!
So for some reason when it in https://reqbin.com/ I was able to run it under myshopname.myshopify.com and it returned just fine. Great!
I got frustrated with Google Apps Script, so I made an endpoint on my server and wrote what I just got working in reqbin in PHP....
php returned a 301....redirect. Weird. So I examined the entirety of the php and found out that it was redirecting to a different url within my schema. I am not sure why it is doing this because that is not the first domain on the shopify account, BUT I reran it in google apps script and used the new URL and it worked.
I am so dumbfounded as to why there is a redirect when i was petitioning example.myshopify.com over to example-dash-example.myshopify.com when example.myshopify.com is the actual domain that everything else redirects to.
For some reason unbeknownst to me, the example-dash-example.myshopify.com domain was the one that ended up working.
Your issue was a two-part solution. The target type was still not correct.
"target_type": "order",
and I am kind of confused about why you would be using anything other than your shop "shop.myshopify.com" domain. Is that not what your code and my code as doing?
var url = 'https://' + shopName + '.myshopify.com/admin/api/2023-10/price_rules.json';
It was not happy with the primary url for some reason which is still unbeknownst to me.
I rewrote it in php and examined the php errors using -t in cli. In tail, it was showing a 301 redirect to one of the other domains on my account. This is curious because I was originally petitioning the primary url.
For some reason a redirect url was what ended up being in the 301 response. When I petitioned the url in the 301 response instead it actually worked. Then from there it actually told me where I had messed up payload parameters.
I still after doing everything I needed to do could not tell you why it redirected me to a redirect url that redirects back to the primary...instead of just letting me use the primary.
Hi, i have the same problem here. i ran through postman for creating customer. this is my postman:
instead of getting 201 (created), i'm getting 200. i have tried the same payload to my trial store and i'm getting the right response with 201 created.
when i tried to console the hit processs. i got the same result as you. the domain got redirected to another domain, which is not my original domain. any idea how to solve this ?
Thanks in advance!
Hey Community! As the holiday season unfolds, we want to extend heartfelt thanks to a...
By JasonH Dec 6, 2024Dropshipping, a high-growth, $226 billion-dollar industry, remains a highly dynamic bus...
By JasonH Nov 27, 2024Hey Community! It’s time to share some appreciation and celebrate what we have accomplis...
By JasonH Nov 14, 2024