/admin/api/2023-07/price_rules.json returning an array instead of the new price rule object

Topic summary

Issue: When making a POST request to Shopify’s /admin/api/2023-07/price_rules.json endpoint to create a new price rule, the API returns an array of all existing price rules instead of the newly created object—essentially behaving like a GET request.

Troubleshooting Attempts:

  • Verified correct headers (Content-Type: application/json) and access token permissions (read/write price_rules, discounts, analytics)
  • Confirmed proper JSON formatting of request body with standard price rule parameters
  • Tested successfully on personal store with identical parameters and access scopes
  • Deleted existing price rules to ensure account wasn’t hitting the 20,000,000 rule limit
  • Multiple users confirmed experiencing the same problem

Resolution Found:
The issue only occurs when calling the main Shopify domain. When using the myshopify domain instead, POST requests work correctly. This appears to be a redirection bug where POST requests to the main domain get converted to GET requests during the redirect process.

Status: Resolved—use the myshopify domain for API calls to avoid this issue.

Summarized with AI on November 12. AI used: claude-sonnet-4-5-20250929.

Hey, thanks for your time.

The problem is, I call the price rules api endpoint using POST method and it returns a list of all the existing prices rules instead of the price rule I just created. Basically, it’s returning what would be the response for the GET method using that same endpoint, except, I’m using POST. Any help is appreciated, I’m quite pressed for time. Thanks.

I’m using POST method, my body:

const requestBody = {
price_rule: {
title: ‘TEST10’,
target_type: ‘line_item’,
target_selection: ‘entitled’,
entitled_product_ids: [5419639406749, 8167846412514],
allocation_method: ‘across’,
value_type: ‘percentage’,
value: -10.0,
usage_limit: 1,
starts_at: isoStartDate,
ends_at: isoEndDate,
customer_selection: ‘all’
}
};
the request response is far to big for me to send it here but it’s an array of existing price rules (and my price rule isnt in it), other than that, it’s just typical price rules.
Calling from server, no from client.
endpoint:

https://{domain}/admin/api/2023-07/price_rules.json
X-Request-Id: e54bf548-5fdb-4259-8f53-cdb1e7db694f

Access scopes:

  • read/write price rules
  • read/write discount codes
  • read analytics

(Leave a like if you have the same problem, so that it brings attention to this)
Tell me if any more info is needed, I’ll provide it.
Thanks.

1 Like

Hi Admchrs1,

This does seem unusual that your request is not being correctly processed as a POST request, but instead as a GET request. This could be due to a number of reasons. Here are some steps you can take to troubleshoot:

  1. Check your Headers: Make sure you are setting the correct ‘Content-Type’ header to ‘application/json’. This lets the server know that you’re sending JSON data.

  2. Check your Data format: Ensure that your request body is correctly formatted as JSON. You can use a tool like Postman to help with this.

  3. Check your Access Token: Ensure that you have the necessary permissions to create a price rule. You mentioned the access scopes you have, make sure they are correct and have the necessary permissions

Try the above and let us know if you’re still seeing issues. Hope this helps!

1 Like

Firstly, thank you so much for your response.

Secondly, unfortunately, I already did all the above x).

Here’s the code:

const currentDate = new Date();
const isoStartDate = currentDate.toISOString();
const endTimeInMilliseconds = currentDate.getTime() + 30 * 60 * 1000; // Add 30 minutes
const isoEndDate = new Date(endTimeInMilliseconds).toISOString();

const requestBody = {
price_rule: {
title: ‘TESTKIPP1234567891’,
target_type: ‘line_item’,
target_selection: ‘entitled’,
entitled_product_ids: [7673522094306],
allocation_method: ‘across’,
value_type: ‘percentage’,
value: -5.0,
usage_limit: 1,
starts_at: isoStartDate,
ends_at: isoEndDate,
customer_selection: ‘all’
}
};

fetch(url, {
method: ‘POST’,
headers: {
‘X-Shopify-Access-Token’: ‘accessToken’,
‘Content-Type’: ‘application/json’,
},
body: JSON.stringify(requestBody),
}).then(async response => {
if (response.ok) {
const status = response.status;
const statusText = response.statusText;
console.log(Status: ${status});
console.log(StatusText: ${statusText});
const location = response.headers.get(‘Location’);
console.log(Price rule created at ${location});
const xRequestId = response.headers.get(‘X-Request-ID’);
console.log(X-Request-ID: ${xRequestId});
return response.json();
} else {
const text = await response.text();
console.log(Response text: ${text});
throw new Error(Request failed with status: ${response.status});
}
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});

I didn’t include the url and the access token.
For the access token I even double checked by calling the endpoint to know if I had write access, and I do.

But the weirdest thing is that I tried this with my own store (with the same parameters and same access scopes) and it works fine, so I’m completely confused.

I thought it was probably because my client had too much price rules already, so I delete 2 and tried it again… no change. I then read somewhere that the limit was 20 000 000 price rules, so it’s unlikely that my client reached that.

Do you have anymore ideas with this added info?
Thanks.
Adam.

Firstly, thank you so much for your response.

Secondly, unfortunately, I already did all the above x).

Here’s the code:

const currentDate = new Date();
const isoStartDate = currentDate.toISOString();
const endTimeInMilliseconds = currentDate.getTime() + 30 * 60 * 1000; // Add 30 minutes
const isoEndDate = new Date(endTimeInMilliseconds).toISOString();

const requestBody = {
price_rule: {
title: ‘TESTKIPP1234567891’,
target_type: ‘line_item’,
target_selection: ‘entitled’,
entitled_product_ids: [7673522094306],
allocation_method: ‘across’,
value_type: ‘percentage’,
value: -5.0,
usage_limit: 1,
starts_at: isoStartDate,
ends_at: isoEndDate,
customer_selection: ‘all’
}
};

fetch(url, {
method: ‘POST’,
headers: {
‘X-Shopify-Access-Token’: ‘accessToken’,
‘Content-Type’: ‘application/json’,
},
body: JSON.stringify(requestBody),
}).then(async response => {
if (response.ok) {
const status = response.status;
const statusText = response.statusText;
console.log(Status: ${status});
console.log(StatusText: ${statusText});
const location = response.headers.get(‘Location’);
console.log(Price rule created at ${location});
const xRequestId = response.headers.get(‘X-Request-ID’);
console.log(X-Request-ID: ${xRequestId});
return response.json();
} else {
const text = await response.text();
console.log(Response text: ${text});
throw new Error(Request failed with status: ${response.status});
}
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});

Access token: I double checked by calling the endpoint and I have the permissions needed.

I even tried with my own store and it works fine with the same parameters and same permissions for the key.

I even deleted 2 price rules to make sure that my client hadn’t reached the limit. Moreover I read the limit was 20 000 000, so it’s unlikely.

I don’t really know what else I can try, if you have any more ideas given this added info, I’d appreciate it immensely.
Thanks.
Adam.

(duplicate reply)

Hey Liam, any new ideas or solutions for this? Thanks

I’m getting the same issue.
Did you resolve that?

2 Likes

No, I tried so many things, but to no avail.

Completely ran out of ideas.

You should like the original post so that it brings attention to this ;).

@Liam do you have any new ideas for this issue?

1 Like

Hi team,

I’m having the same issue, anyone was able to fix it ?

Thank you

For anyone facing the same issue, it turn out it only happen when we call the main domain but it doesn’t happen when we call myshopify domain. so probably an bug on the redirection where the POST requests end up turning to a GET requests

1 Like