HTTP Request node returns 401 with QuickBooks Online OAuth2 — native QBO nodes work fine with same credential

Describe the problem/error/question

I’m building a workflow that creates QBO sub-customers (projects) from Airtable records. The native QuickBooks Online nodes (Create a Customer, Get Many Customers) authenticate and work perfectly. However, any HTTP Request node using the same QBO OAuth2 credential returns a 401 Authorization Failure, regardless of configuration.

The reason I need the HTTP Request node: the native “Create a Customer” and “Update a Customer” nodes don’t expose the Job, ParentRef, or IsProject fields, which are required by QBO’s API to create/update sub-customers (projects). These fields aren’t available in the node dropdowns or additional fields.

What is the error message (if any)?

401 - {“Fault”:{“Error”:[{“Message”:“Authorization Failure”,“Detail”:“AuthorizationFailure: {0}”,“code”:“120”}],“type”:“AuthorizationFault”}}

What I’ve tried (all result in 401)

  1. HTTP Request node with Predefined Credential Type → QuickBooks Online OAuth2 API → same credential that works on native nodes → 401
  2. Same as above with Send Headers toggled off (letting the predefined credential handle headers automatically) → 401
  3. “Custom QuickBooks Online API Call” (the link at the bottom of the QBO node action picker — creates an HTTP Request node under the hood) → 401
  4. HTTP Request node with Generic Credential Type → OAuth2 API with a freshly created credential using correct Authorization URL (https://appcenter.intuit.com/connect/oauth2), Access Token URL (https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer), same Client ID/Secret from Intuit Developer portal, scope com.intuit.quickbooks.accounting, Authentication set to Header → 401
  5. Reconnected the QBO credential (fresh OAuth token) → 401
  6. Added minorversion=65 query parameter + explicit Content-Type/Accept headers → 401
  7. Tried a Python Code node with helpers.httpRequestWithAuthentication → not supported in Code node sandbox

Information on my n8n setup

  • n8n version: Latest (n8n Cloud)
  • Running n8n via: n8n Cloud
  • Operating system: N/A (Cloud)

The JSON body is correct

The body resolves and formats properly (verified in n8n’s output preview):

{
  "DisplayName": "c_994_19559 || 19559_Aye Garcia LLC_June Contract 2026",
  "Job": true,
  "BillWithParent": true,
  "ParentRef": {
    "value": "4404"
  }
}

The request details in the error output confirm the body is being sent correctly — it’s purely an authentication/token injection issue.

Notes

I found two other posts with the exact same issue (native QBO node works, HTTP Request doesn’t) and neither had a resolution:

One theory is that n8n lowercases the Authorization header to authorization, and QBO’s API may be case-sensitive.

Feature request

If the HTTP Request node auth issue is a known limitation, could the native QuickBooks Online node be updated to expose Job, ParentRef, and IsProject fields in the Create/Update Customer operations? These are standard QBO API fields required for sub-customer (project) management.

Hi @Cynthia_Valdes

If you want full control over header casing and avoid those limitations, i suggest a code node to make API call directly, something like (the code below is generated by AI so check and adapt it to yours):

const credential = await this.getCredentials(‘quickBooksOAuth2Api’);const token = credential.oauthTokenData?.access_token;const realmId = credential.companyId;
const response = await this.helpers.httpRequest({method: ‘POST’,url: https://quickbooks.api.intuit.com/v3/company/${realmId}/customer?minorversion=65,headers: {‘Authorization’: Bearer ${token},‘Content-Type’: ‘application/json’,‘Accept’: ‘application/json’,},body: {DisplayName: “your display name”,Job: true,BillWithParent: true,ParentRef: { value: “4404” }},json: true,});
return [{ json: response }];

It lets you use the Job/ParentRef/IsProject fields that the native node doesn’t expose.

Also worth filing a feature request on GitHub to add those fields to the native QBO node.

Let me know if it works :crossed_fingers: