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 in a Cloudflare Durable Object
- 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 - Scopes that require a redirect parameter other than
https://oauth.jsworkflows.com/oauth2/callback
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 authorised 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 → OAuth Connections 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 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') — 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”class Workflow { async start(data, headers, api) { const { token, error } = await api.getOAuthToken('my-custom-handle'); if (error) { api.log('Could not get token:', error); return; }
const res = await fetch('https://api.example.com/resource', { headers: { 'Authorization': `Bearer ${token}` }, }); const json = await res.json(); api.log('Response:', JSON.stringify(json)); }}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 (e.g. some social login providers), 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.