I’m using the NetSuite REST API to run an async Su...
# general
y
I’m using the NetSuite REST API to run an async SuiteQL query, but I keep getting a 400 error when trying to fetch the final result. The error says the Prefer header is missing—even though I’m sending it. I keep getting “Prefer” header error when fetching SuiteQL async results, even though header is set. Anyone had experience with this? (details in thread)
I’m using the NetSuite REST API to run an async SuiteQL query, but I keep getting a 400 error when trying to fetch the final result. The error says the Prefer header is missing—even though I’m sending it. Step 1 – Submit the query
Copy code
headers = {
    "Content-Type": "application/json",
    "Prefer": "respond-async",
}
r = <http://requests.post|requests.post>(
    "https://<ACCOUNT_ID>.<http://suitetalk.api.netsuite.com/services/rest/query/v1/suiteql|suitetalk.api.netsuite.com/services/rest/query/v1/suiteql>",
    auth=auth,
    headers=headers,
    data=json.dumps({"q": "SELECT count(*) FROM Transaction"})
)
Response includes:
Copy code
Location: https://<ACCOUNT_ID>.<http://suitetalk.api.netsuite.com/services/rest/async/v1/job/702|suitetalk.api.netsuite.com/services/rest/async/v1/job/702>
Step 2 – Poll job status
Copy code
job_loc = r.headers["Location"]
headers = {
    "Content-Type": "application/json",
    "Prefer": "transient",
}
j = requests.get(job_loc, auth=auth, headers=headers, params={"expandSubResources": "true"})
Response contains:
Copy code
.../job/702/task/702/result
Step 3 – Fetch result
Copy code
result_loc = j.json()['task']['items'][0]['links'][0]['href']
headers = {
    "Content-Type": "application/json",
    "Prefer": "transient",
}
k = requests.get(result_loc, auth=auth, headers=headers)
But this always returns:
Copy code
<Response [400]>
With:
Copy code
{
  "o:errorDetails": [
    {
      "detail": "The required request header 'Prefer' is missing or invalid. Use this header with one of the required values: transient.",
      "o:errorCode": "INVALID_HEADER"
    }
  ]
}
I’m following this doc: https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_161251386312.html#subsect_161278579295 Tried many header combos, always same result.
y
I think this is the documentation you should follow for SuiteQL queries. I just vibe-coded the following, which works for me. Try copying into your devtools console.
Copy code
(async function runSuiteQL() {
  // --- Configuration ---
  const suiteQlQuery = "SELECT * FROM account"; // Your SuiteQL query
  const suiteQlEndpoint = "/services/rest/query/v1/suiteql"; // Standard SuiteQL endpoint

  // Get the base URL (e.g., https://<accountID>.app.netsuite.com)
  const baseUrl = window.location.origin;
  const fullUrl = baseUrl + suiteQlEndpoint;

  console.log(
    `%cAttempting to run SuiteQL query:`,
    "color: blue; font-weight: bold;",
    suiteQlQuery,
  );
  console.log(`%cEndpoint:`, "color: blue; font-weight: bold;", fullUrl);

  try {
    // --- Make the Request ---
    const response = await fetch(fullUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Prefer: "transient", // This header is required by your NetSuite environment.
      },
      body: JSON.stringify({
        q: suiteQlQuery,
      }),
    });

    // --- Handle the Response ---
    if (!response.ok) {
      // Try to get more details from the response body if it's an error
      let errorDetails = `HTTP error! Status: ${response.status} ${response.statusText}`;
      try {
        const errorData = await response.json();
        errorDetails += `\nDetails: ${JSON.stringify(errorData, null, 2)}`;
      } catch (e) {
        // If response body is not JSON, just use the text
        const errorText = await response.text();
        errorDetails += `\nResponse Text: ${errorText}`;
      }
      throw new Error(errorDetails);
    }

    const data = await response.json();

    // --- Output the Results ---
    if (data && data.items) {
      console.log("%cQuery successful! ✅", "color: green; font-weight: bold;");
      console.log("%cReturned JSON object:", "color: green;");
      console.log(data); // Logs the full response object (includes links, count, etc.)
      console.log("%cQuery items (records):", "color: green;");
      console.table(data.items); // Displays the items in a table for better readability
      // To return the items directly for further use in the console:
      // return data.items;
    } else {
      console.warn(
        "%cQuery executed, but no items found or unexpected response structure.",
        "color: orange;",
      );
      console.log(data);
    }
  } catch (error) {
    console.error(
      "%c❌ Error running SuiteQL query:",
      "color: red; font-weight: bold;",
      error.message,
    );
    if (error.stack) {
      console.error(error.stack);
    }
  }
})();