Custom OAuth 2.0
The Custom OAuth 2.0 option lets you connect any service that supports the standard Authorization Code grant flow. You supply the Authorization URL, Token URL, Client ID, Client Secret, and scopes. JsWorkflows handles the redirect, token exchange, and storage.
What is supported
Section titled “What is supported”- Standard OAuth 2.0 Authorization Code flow
- Token exchange via
application/x-www-form-urlencodedPOST to your Token URL - Token storage encrypted at rest
- Automatic token refresh at expiry, only if the provider returns a
refresh_tokenandexpires_inin the token response
What is not supported
Section titled “What is not supported”- PKCE (code challenge/verifier)
- Token endpoints that require JSON body instead of form-encoded body
- Non-standard grant types (client credentials, device code, etc.)
- Providers that do not follow the standard
access_tokenresponse field name - Providers that require a different redirect URI
1. Create an OAuth app at the provider
Section titled “1. Create an OAuth app at the provider”In the provider’s developer console, create an OAuth 2.0 application. Note:
- Grant type must be Authorization Code
- Add
https://oauth.jsworkflows.com/oauth2/callbackas an authorized redirect URI (exact match required) - Copy the Client ID, Client Secret, Authorization URL, and Token URL
2. Add the connection in JsWorkflows
Section titled “2. Add the connection in JsWorkflows”Go to Settings → OAuth2 Tokens and click Connect to Service. Select Custom (OAuth 2.0) from the service list.
Fill in the fields:
| Field | Description |
|---|---|
| OAuth Redirect URL | Pre-filled. Copy and add it to your provider’s redirect URI list |
| Client ID | From your OAuth app |
| Client Secret | From your OAuth app |
| Authorization URL | The provider’s OAuth authorization endpoint |
| Token URL | The provider’s token exchange endpoint |
| OAuth Name | A friendly label visible only to you |
| Handle | The unique identifier used in api.getOAuthToken('your-handle'). Use lowercase letters, numbers, and hyphens only. It cannot be changed after creation |
| Scopes | Space-separated scopes to request (e.g. read:data write:data) |
Click Generate and Authorize. A popup window opens the provider’s authorization page. After you grant access, the popup closes and the connection appears in your list.
Usage in workflows
Section titled “Usage in workflows”export class Workflow { async start(_data, _headers, api) { const { token, error } = await api.getOAuthToken('my-custom-handle'); if (error || !token) throw new Error(error || 'Missing OAuth token');
const res = await fetch('https://api.example.com/resource', { headers: { Authorization: `Bearer ${token}` }, });
if (!res.ok) { throw new Error(`API ${res.status}: ${await res.text()}`); }
const json = await res.json(); console.log(`Response: ${JSON.stringify(json)}`); }}Many OAuth providers use Authorization: Bearer <token> for API calls, but some APIs require a different header format. Always follow the provider’s API documentation for resource requests.
Token refresh
Section titled “Token refresh”JsWorkflows automatically refreshes the access token when it expires, using the refresh_token returned by the provider. The refresh POST uses the same Token URL you provided during setup, with standard refresh_token grant parameters.
If the provider does not return a refresh_token in the initial token response, automatic refresh is not possible. In that case, the token will stop working after it expires and you will need to reconnect the integration manually.
Editing a connection
Section titled “Editing a connection”When you edit a Custom OAuth connection, the Authorization URL and Token URL are pre-filled from the stored values. The Client Secret is shown as a placeholder — leave it unchanged to keep the existing secret, or enter a new one to replace it.
Re-saving triggers a new OAuth authorization popup so the provider can issue a fresh token with the updated credentials or scopes.
Limitations
Section titled “Limitations”- No PKCE support: providers that require PKCE (common for public clients and mobile apps) will not work.
- No JSON token body: the token request always uses
application/x-www-form-urlencoded. Providers that require a JSON body are not compatible. - Refresh requires
refresh_token: if the provider only issues short-lived access tokens without a refresh token, the token will expire and need manual reconnection. - Standard
access_tokenfield required: the token response must contain anaccess_tokenfield at the top level of the JSON response. - One redirect URI: the fixed redirect URI is
https://oauth.jsworkflows.com/oauth2/callback. Providers that do not allow this exact URI cannot be used.