From 24ce11880345710bc4a2c77956d4bad95677f422 Mon Sep 17 00:00:00 2001 From: Saif Shines Date: Mon, 25 May 2026 12:11:57 +0530 Subject: [PATCH 1/8] docs: add Scalekit integration page --- sources/platform/integrations/ai/scalekit.md | 303 +++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 sources/platform/integrations/ai/scalekit.md diff --git a/sources/platform/integrations/ai/scalekit.md b/sources/platform/integrations/ai/scalekit.md new file mode 100644 index 0000000000..008a8548e4 --- /dev/null +++ b/sources/platform/integrations/ai/scalekit.md @@ -0,0 +1,303 @@ +--- +title: Scalekit integration +sidebar_label: Scalekit +description: Add per-user OAuth to Apify Actors with Scalekit Agent Auth. Store tokens server-side, refresh them automatically, and proxy API calls to 90+ services. +sidebar_position: 21 +slug: /integrations/scalekit +--- + +import ThirdPartyDisclaimer from '@site/sources/_partials/_third-party-integration.mdx'; + +## What is Scalekit + +[Scalekit](https://scalekit.com) is auth infrastructure for AI agents. It provides a token vault and connector layer that handles OAuth 2.0 flows, token storage, automatic refresh, and API proxying for 90+ third-party services including Notion, Gmail, Slack, Google Calendar, GitHub, and more. + +With the [Scalekit Node SDK](https://www.npmjs.com/package/@scalekit-sdk/node) inside your Actor, each user who runs it can connect their own SaaS accounts. Scalekit stores the OAuth tokens server-side, refreshes them automatically, and proxies API calls on the user's behalf. Your Actor never touches a token directly. + +See the [Scalekit Agent Auth documentation](https://docs.scalekit.com/agent-auth/overview/) for the full API reference. + + + +## How to use Apify with Scalekit + +This guide shows how to add per-user OAuth to an Apify Actor using Scalekit. The example connects to a user's Notion workspace and searches their pages. + +### Prerequisites + +- A [Scalekit account](https://app.scalekit.com) with your `SCALEKIT_ENV_URL`, `SCALEKIT_CLIENT_ID`, and `SCALEKIT_CLIENT_SECRET` from **Dashboard > Developers > Settings > API Credentials** +- An [Apify account](https://console.apify.com/) +- A connection configured in the Scalekit dashboard (go to **Agent Auth > Connections > + Create Connection** and select the service, for example Notion) +- Node.js version 18 or later + +Install the Scalekit SDK in your Actor project: + +```bash +npm install @scalekit-sdk/node +``` + +Set your Scalekit credentials as Actor environment variables in Apify Console under **Settings > Environment variables**: + +```bash +SCALEKIT_ENV_URL=https://your-env.scalekit.com +SCALEKIT_CLIENT_ID=skc_... +SCALEKIT_CLIENT_SECRET=your-secret +``` + +### Step 1: Initialize the Scalekit client + +Create a Scalekit client using your environment credentials. Initialize it once and reuse it across your Actor. + +```javascript +import { Actor } from 'apify'; +import { ScalekitClient } from '@scalekit-sdk/node'; + +await Actor.init(); + +const scalekit = new ScalekitClient( + process.env.SCALEKIT_ENV_URL, + process.env.SCALEKIT_CLIENT_ID, + process.env.SCALEKIT_CLIENT_SECRET, +); +``` + +### Step 2: Connect a user's account + +Call `getOrCreateConnectedAccount` to check if a user has already authorized a service. This method is idempotent - safe to call on every Actor run. + +Use `Actor.getEnv().userId` as the identifier. This string is stable per Apify account, so each user gets their own OAuth session automatically. + +```javascript +const { userId } = Actor.getEnv(); + +const resp = await scalekit.actions.getOrCreateConnectedAccount({ + connectionName: 'notion', + identifier: userId, +}); + +let account = resp.connectedAccount ?? resp; +``` + +The connected account has one of these statuses: + +| Status | Meaning | +| --- | --- | +| `ACTIVE` | User is authorized, tokens are valid | +| `INACTIVE` | User has not connected yet | +| `EXPIRED` | Token needs re-authorization | + +### Step 3: Authorize the user + +If the account is not active, generate an authorization link and surface it in the Actor's status message. The user completes OAuth in their browser, and the Actor polls until the connection is active. + +```javascript +import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb'; + +if (account.status !== ConnectorStatus.ACTIVE) { + const { link } = await scalekit.actions.getAuthorizationLink({ + connectionName: 'notion', + identifier: userId, + }); + + await Actor.setStatusMessage(`Authorize Notion: ${link}`); + + // Poll until the user completes OAuth. + const deadline = Date.now() + 300_000; + let connected = false; + while (Date.now() < deadline) { + await new Promise((r) => setTimeout(r, 5_000)); + const poll = await scalekit.actions.getOrCreateConnectedAccount({ + connectionName: 'notion', + identifier: userId, + }); + const pollAccount = poll.connectedAccount ?? poll; + if (pollAccount.status === ConnectorStatus.ACTIVE) { + account = pollAccount; + connected = true; + break; + } + } + + if (!connected) throw new Error('Timed out waiting for Notion authorization.'); +} +``` + +:::tip Authorization persistence + +The user authorizes once. Every future Actor run for that Apify account finds an active session and skips the authorization step entirely. + +::: + +### Step 4: Call the API + +Once the account is active, call the third-party API through Scalekit. There are two approaches. + +#### Pre-built tools with `executeTool` + +Scalekit provides pre-built tools for common operations that return structured, AI-friendly responses: + +```javascript +const result = await scalekit.actions.executeTool({ + toolName: 'notion_page_search', + connectedAccountId: account.id, + toolInput: { query: 'Meeting Notes', page_size: 5 }, +}); + +console.log('Search results:', JSON.stringify(result, null, 2)); +``` + +#### Direct API calls with `actions.request` + +For any API endpoint - including ones without a pre-built tool - use `actions.request`. Scalekit injects the user's token and handles refresh automatically: + +```javascript +const result = await scalekit.actions.request({ + connectionName: 'notion', + identifier: userId, + path: '/v1/search', + method: 'POST', + body: { query: 'Meeting Notes', page_size: 5 }, +}); +``` + +Both approaches use the same connected account and the same token vault. Use `executeTool` when a pre-built tool exists for your use case. Use `actions.request` for full control over the API call or to reach endpoints without a pre-built tool. + +## Complete example + +An Actor that initializes Scalekit, checks authorization, and searches the user's Notion pages: + +```javascript +import { Actor } from 'apify'; +import { ScalekitClient } from '@scalekit-sdk/node'; +import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb'; + +await Actor.init(); + +try { + const input = await Actor.getInput(); + const { task } = input; + + const scalekit = new ScalekitClient( + process.env.SCALEKIT_ENV_URL, + process.env.SCALEKIT_CLIENT_ID, + process.env.SCALEKIT_CLIENT_SECRET, + ); + + const { userId } = Actor.getEnv(); + + const resp = await scalekit.actions.getOrCreateConnectedAccount({ + connectionName: 'notion', + identifier: userId, + }); + let account = resp.connectedAccount ?? resp; + + if (account.status !== ConnectorStatus.ACTIVE) { + const { link } = await scalekit.actions.getAuthorizationLink({ + connectionName: 'notion', + identifier: userId, + }); + + await Actor.setValue('OUTPUT', { + status: 'AWAITING_AUTH', + authorizationLink: link, + message: 'Open the link to authorize Notion.', + }); + await Actor.setStatusMessage(`Authorize Notion: ${link}`); + + const deadline = Date.now() + 300_000; + let connected = false; + while (Date.now() < deadline) { + await new Promise((r) => setTimeout(r, 5_000)); + const poll = await scalekit.actions.getOrCreateConnectedAccount({ + connectionName: 'notion', + identifier: userId, + }); + const pollAccount = poll.connectedAccount ?? poll; + if (pollAccount.status === ConnectorStatus.ACTIVE) { + account = pollAccount; + connected = true; + break; + } + } + + if (!connected) throw new Error('Timed out waiting for Notion authorization.'); + } + + const result = await scalekit.actions.executeTool({ + toolName: 'notion_page_search', + connectedAccountId: account.id, + toolInput: { query: task, page_size: 5 }, + }); + + await Actor.setValue('OUTPUT', { status: 'DONE', task, result }); + await Actor.pushData({ task, result }); +} catch (err) { + console.error('Actor failed:', err.message); + await Actor.fail(err.message); +} + +await Actor.exit(); +``` + +## Use Scalekit with an LLM agent Actor + +When your Actor runs an LLM-driven agent, Scalekit's pre-built tools integrate directly into the tool-calling loop. Define tool schemas, pass them to the LLM, and execute tool calls through `scalekit.actions.executeTool`: + +```javascript +// The LLM decided to search the user's Notion workspace. +// Execute the tool call through Scalekit - it handles auth automatically. +const result = await scalekit.actions.executeTool({ + toolName: 'notion_page_search', + connectedAccountId: account.id, + toolInput: { query: 'Meeting Notes', page_size: 5 }, +}); + +// Feed the result back to the LLM for reasoning. +messages.push({ + role: 'tool_result', + tool_use_id: toolCall.id, + content: JSON.stringify(result), +}); +``` + +For a complete working example, see [Notion + YouTube Agent](https://github.com/scalekit-developers/agentkit-apify-actor-example) - an open-source Actor that accepts a natural-language task, connects to the user's Notion and a shared YouTube account, and writes research results to a Notion page using Scalekit tool calls. + +## Available connectors + +Scalekit supports 90+ OAuth connectors. Common services include: + +| Service | `connectionName` | +| --- | --- | +| Gmail | `gmail` | +| Google Calendar | `googlecalendar` | +| Google Drive | `googledrive` | +| Slack | `slack` | +| Notion | `notion` | +| GitHub | `github` | +| HubSpot | `hubspot` | +| Jira | `jira` | +| Salesforce | `salesforce` | +| Linear | `linear` | +| Outlook | `outlook` | +| Zoom | `zoom` | +| Gong | `gong` | +| Airtable | `airtable` | + +Change `connectionName` in `getOrCreateConnectedAccount` and `getAuthorizationLink` to connect to a different service. The rest of the code stays the same. + +[Browse all connectors](https://docs.scalekit.com/reference/agent-connectors) + +:::tip Multiple services per user + +Use the same `identifier` across connectors to let your Actor access multiple services for the same user - for example, Gmail and Google Calendar for a scheduling assistant. + +::: + +## Resources + +- [Scalekit Agent Auth documentation](https://docs.scalekit.com/agent-auth/overview/) +- [Agent Auth quickstart](https://docs.scalekit.com/agent-auth/quickstart/) +- [All available connectors](https://docs.scalekit.com/reference/agent-connectors) +- [Agentic tool calling](https://docs.scalekit.com/agent-auth/tools/agent-tools-quickstart/) +- [Notion + YouTube Agent example](https://github.com/scalekit-developers/agentkit-apify-actor-example) +- [Apify Actor per-user OAuth cookbook](https://docs.scalekit.com/cookbooks/apify-actor-per-user-oauth/) +- [Apify Actor documentation](/platform/actors) \ No newline at end of file From 0c42035a83eab53f3c4038ea6c35291c8ca58a3b Mon Sep 17 00:00:00 2001 From: Saif Shines Date: Mon, 25 May 2026 12:16:37 +0530 Subject: [PATCH 2/8] docs: move scalekit.md to integrations root --- sources/platform/integrations/{ai => }/scalekit.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sources/platform/integrations/{ai => }/scalekit.md (100%) diff --git a/sources/platform/integrations/ai/scalekit.md b/sources/platform/integrations/scalekit.md similarity index 100% rename from sources/platform/integrations/ai/scalekit.md rename to sources/platform/integrations/scalekit.md From 0e49f541d6fd77e48b988404efe55e1d52654c4c Mon Sep 17 00:00:00 2001 From: Saif Shines Date: Mon, 25 May 2026 12:20:00 +0530 Subject: [PATCH 3/8] docs: fix description - AgentKit, remove refresh claim, 100+ connectors --- sources/platform/integrations/scalekit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/platform/integrations/scalekit.md b/sources/platform/integrations/scalekit.md index 008a8548e4..504a8df258 100644 --- a/sources/platform/integrations/scalekit.md +++ b/sources/platform/integrations/scalekit.md @@ -1,7 +1,7 @@ --- title: Scalekit integration sidebar_label: Scalekit -description: Add per-user OAuth to Apify Actors with Scalekit Agent Auth. Store tokens server-side, refresh them automatically, and proxy API calls to 90+ services. +description: Add per-user OAuth to Apify Actors with Scalekit AgentKit. Store tokens server-side, manage authorization flows, and call tools in 100+ connectors. sidebar_position: 21 slug: /integrations/scalekit --- From 24b218c06b8762eb35d87a5483f3d69d63692d58 Mon Sep 17 00:00:00 2001 From: Saif Shines Date: Mon, 25 May 2026 12:25:12 +0530 Subject: [PATCH 4/8] docs: fix AgentKit naming and URL paths --- sources/platform/integrations/scalekit.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sources/platform/integrations/scalekit.md b/sources/platform/integrations/scalekit.md index 504a8df258..c9a163bd32 100644 --- a/sources/platform/integrations/scalekit.md +++ b/sources/platform/integrations/scalekit.md @@ -14,7 +14,7 @@ import ThirdPartyDisclaimer from '@site/sources/_partials/_third-party-integrati With the [Scalekit Node SDK](https://www.npmjs.com/package/@scalekit-sdk/node) inside your Actor, each user who runs it can connect their own SaaS accounts. Scalekit stores the OAuth tokens server-side, refreshes them automatically, and proxies API calls on the user's behalf. Your Actor never touches a token directly. -See the [Scalekit Agent Auth documentation](https://docs.scalekit.com/agent-auth/overview/) for the full API reference. +See the [AgentKit documentation](https://docs.scalekit.com/agentkit/overview) for the full API reference. @@ -284,7 +284,7 @@ Scalekit supports 90+ OAuth connectors. Common services include: Change `connectionName` in `getOrCreateConnectedAccount` and `getAuthorizationLink` to connect to a different service. The rest of the code stays the same. -[Browse all connectors](https://docs.scalekit.com/reference/agent-connectors) +[Browse all connectors](https://docs.scalekit.com/agentkit/connectors) :::tip Multiple services per user @@ -294,10 +294,10 @@ Use the same `identifier` across connectors to let your Actor access multiple se ## Resources -- [Scalekit Agent Auth documentation](https://docs.scalekit.com/agent-auth/overview/) -- [Agent Auth quickstart](https://docs.scalekit.com/agent-auth/quickstart/) -- [All available connectors](https://docs.scalekit.com/reference/agent-connectors) -- [Agentic tool calling](https://docs.scalekit.com/agent-auth/tools/agent-tools-quickstart/) +- [AgentKit documentation](https://docs.scalekit.com/agentkit/overview) +- [AgentKit quickstart](https://docs.scalekit.com/agentkit/quickstart) +- [All available connectors](https://docs.scalekit.com/agentkit/connectors) +- [Agentic tool calling](https://docs.scalekit.com/agentkit/tools/agent-tools-quickstart) - [Notion + YouTube Agent example](https://github.com/scalekit-developers/agentkit-apify-actor-example) - [Apify Actor per-user OAuth cookbook](https://docs.scalekit.com/cookbooks/apify-actor-per-user-oauth/) - [Apify Actor documentation](/platform/actors) \ No newline at end of file From 00dc183bcd86547bf4ac68a80b55b99041afce7b Mon Sep 17 00:00:00 2001 From: Saif Shines Date: Mon, 25 May 2026 12:26:23 +0530 Subject: [PATCH 5/8] docs: fix broken tools URL --- sources/platform/integrations/scalekit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/platform/integrations/scalekit.md b/sources/platform/integrations/scalekit.md index c9a163bd32..b1d2fdcb96 100644 --- a/sources/platform/integrations/scalekit.md +++ b/sources/platform/integrations/scalekit.md @@ -297,7 +297,7 @@ Use the same `identifier` across connectors to let your Actor access multiple se - [AgentKit documentation](https://docs.scalekit.com/agentkit/overview) - [AgentKit quickstart](https://docs.scalekit.com/agentkit/quickstart) - [All available connectors](https://docs.scalekit.com/agentkit/connectors) -- [Agentic tool calling](https://docs.scalekit.com/agentkit/tools/agent-tools-quickstart) +- [Agentic tool calling](https://docs.scalekit.com/agentkit/tools/overview) - [Notion + YouTube Agent example](https://github.com/scalekit-developers/agentkit-apify-actor-example) - [Apify Actor per-user OAuth cookbook](https://docs.scalekit.com/cookbooks/apify-actor-per-user-oauth/) - [Apify Actor documentation](/platform/actors) \ No newline at end of file From 176c95b093355b3065cc1ce0d849e9a152549e0b Mon Sep 17 00:00:00 2001 From: Saif Shines Date: Mon, 25 May 2026 12:29:43 +0530 Subject: [PATCH 6/8] docs: update connector count to 100+ --- sources/platform/integrations/scalekit.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/platform/integrations/scalekit.md b/sources/platform/integrations/scalekit.md index b1d2fdcb96..a45977e009 100644 --- a/sources/platform/integrations/scalekit.md +++ b/sources/platform/integrations/scalekit.md @@ -10,7 +10,7 @@ import ThirdPartyDisclaimer from '@site/sources/_partials/_third-party-integrati ## What is Scalekit -[Scalekit](https://scalekit.com) is auth infrastructure for AI agents. It provides a token vault and connector layer that handles OAuth 2.0 flows, token storage, automatic refresh, and API proxying for 90+ third-party services including Notion, Gmail, Slack, Google Calendar, GitHub, and more. +[Scalekit](https://scalekit.com) is auth infrastructure for AI agents. It provides a token vault and connector layer that handles OAuth 2.0 flows, token storage, automatic refresh, and API proxying for 100+ third-party services including Notion, Gmail, Slack, Google Calendar, GitHub, and more. With the [Scalekit Node SDK](https://www.npmjs.com/package/@scalekit-sdk/node) inside your Actor, each user who runs it can connect their own SaaS accounts. Scalekit stores the OAuth tokens server-side, refreshes them automatically, and proxies API calls on the user's behalf. Your Actor never touches a token directly. @@ -263,7 +263,7 @@ For a complete working example, see [Notion + YouTube Agent](https://github.com/ ## Available connectors -Scalekit supports 90+ OAuth connectors. Common services include: +Scalekit supports 100+ connectors. Common services include: | Service | `connectionName` | | --- | --- | From 8a2b88bb24c0c1f2d4f5fc84be4ef7446062daaa Mon Sep 17 00:00:00 2001 From: Saif Shines Date: Mon, 25 May 2026 12:56:04 +0530 Subject: [PATCH 7/8] docs: update description --- sources/platform/integrations/scalekit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/platform/integrations/scalekit.md b/sources/platform/integrations/scalekit.md index a45977e009..4bdb561f4d 100644 --- a/sources/platform/integrations/scalekit.md +++ b/sources/platform/integrations/scalekit.md @@ -1,7 +1,7 @@ --- title: Scalekit integration sidebar_label: Scalekit -description: Add per-user OAuth to Apify Actors with Scalekit AgentKit. Store tokens server-side, manage authorization flows, and call tools in 100+ connectors. +description: Add delegated Auth to your actors. Define scopes and access 5K+ tools. Zero token code. sidebar_position: 21 slug: /integrations/scalekit --- From 21df296d7b35a43e1b969ad5900e64020861f566 Mon Sep 17 00:00:00 2001 From: Saif Shines Date: Tue, 26 May 2026 09:09:34 +0530 Subject: [PATCH 8/8] docs: align with Apify integration page conventions - Update description to use 'Learn how to...' pattern (140-160 chars) - Format prerequisites with italic item names per style guide --- sources/platform/integrations/scalekit.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sources/platform/integrations/scalekit.md b/sources/platform/integrations/scalekit.md index 4bdb561f4d..f485324670 100644 --- a/sources/platform/integrations/scalekit.md +++ b/sources/platform/integrations/scalekit.md @@ -1,7 +1,7 @@ --- title: Scalekit integration sidebar_label: Scalekit -description: Add delegated Auth to your actors. Define scopes and access 5K+ tools. Zero token code. +description: Learn how to use Scalekit with Apify Actors to add per-user OAuth authorization, enabling access to 100+ third-party services like Notion, Gmail, and Slack. sidebar_position: 21 slug: /integrations/scalekit --- @@ -24,10 +24,10 @@ This guide shows how to add per-user OAuth to an Apify Actor using Scalekit. The ### Prerequisites -- A [Scalekit account](https://app.scalekit.com) with your `SCALEKIT_ENV_URL`, `SCALEKIT_CLIENT_ID`, and `SCALEKIT_CLIENT_SECRET` from **Dashboard > Developers > Settings > API Credentials** -- An [Apify account](https://console.apify.com/) -- A connection configured in the Scalekit dashboard (go to **Agent Auth > Connections > + Create Connection** and select the service, for example Notion) -- Node.js version 18 or later +- _A Scalekit account_ with your `SCALEKIT_ENV_URL`, `SCALEKIT_CLIENT_ID`, and `SCALEKIT_CLIENT_SECRET` from **Dashboard > Developers > Settings > API Credentials** - [sign up here](https://app.scalekit.com) +- _An Apify account_ - [sign up here](https://console.apify.com/) +- _A configured connection_ in the Scalekit dashboard - go to **Agent Auth > Connections > + Create Connection** and select the service, for example Notion +- _Node.js 18+_ Install the Scalekit SDK in your Actor project: