With the help of our awesome engineer @yashmodi, we were able to get NetSuite OAuth 2.0 Client Credentials (Machine-to-Machine) working with a Celigo HTTP connection. Below is the full setup.
Out of curiosity, what is driving you to use OAuth 2.0 with NetSuite as opposed to OAuth 1.0 or using our native NetSuite connector?
1) NetSuite setup
A) Create an Integration record
In NetSuite, create a new integration record:
Setup → Integration → Manage Integrations → New
-
Enable Client Credentials (Machine To Machine) Grant
-
Enable the scopes you will need (make note of which ones)
-
Save the record, then copy and save the Client ID
- For M2M, you generally do not need the Client Secret in Celigo.
B) Generate a public/private key pair
Generate a key pair and certificate. NetSuite doc:
https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/subsect_162755332391.html
Example command (this is what I used):
openssl req -new -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -pkeyopt ec_param_enc:named_curve -nodes -days 365 -out public.pem -keyout private.pem
C) Create an OAuth 2.0 M2M setup record
Go to:
Setup → Integrations → OAuth 2.0 Client Credentials (M2M) Setup → Create New
- Select your Entity
- Select the Role
- Select the Application/Integration you created earlier
- Upload the public certificate (
public.pem)
- Save and copy the Certificate ID (you will need it in Celigo)
2) Celigo setup (HTTP connection)
A) Create the HTTP connection
Create a new HTTP connection in Celigo:
-
Base URI
https://<accountid>.suitetalk.api.netsuite.com
-
Auth type: OAuth 2.0
-
Create a new iClient
-
Grant type: Client Credentials
-
Enable Use JWT
-
Signature method: use the one matching your cert (mine was ES256)
-
Paste your private key contents (private.pem) into the private key field
B) JWT payload
Use the following JWT payload (update <accountid> and scope to match what you enabled on the Integration record):
{
"iss": "{{{iClient.oauth2.encrypted.clientId}}}",
"aud": "https://<accountid>.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token",
"iat": {{{dateFormat 'X' (timestamp) 'YYYY-MM-DDTHH:mm:ss.SSS[Z]'}}},
"exp": {{{dateFormat 'X' (dateAdd (timestamp) '2700000' 'UTC') 'YYYY-MM-DDTHH:mm:ss.SSS[Z]'}}},
"scope": "rest_webservices,restlets"
}
Notes:
- Make sure the
scope values here are enabled on the NetSuite integration record.
- The
exp above is set to about 45 minutes after iat (2700000 ms).
C) JWT headers
{
"typ": "JWT",
"alg": "ES256",
"kid": "{{{iClient.oauth2.encrypted.certificateId}}}"
}
alg must match the signature method you chose (for example, ES256).
D) Token endpoint
Access token URL:
https://<accountid>.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token
E) OAuth 2.0 overrides
Under OAuth 2.0 overrides:
Headers
content-type: application/x-www-form-urlencoded
Body
{
"grant_type": "client_credentials",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": "{{{iClient.jwt.token}}}"
}
F) Configure token auth
- Send token via: HTTP header
- Header name: Authorization
- Header scheme: Bearer
G) Non-standard API response patterns
- Override HTTP status code for auth errors: 400
H) Advanced → Encrypted fields
In Advanced → Encrypted fields, add:
{
"certificateId": "",
"clientId": ""
}
…and populate those values with:
certificateId = the NetSuite Certificate ID from the M2M setup record
clientId = the NetSuite Integration record Client ID
3) Test the connection
In the connection test: