$npx -y skills add apify/agent-skills --skill apify-sdk-integrationIntegrate Apify into an existing JavaScript/TypeScript or Python application using the apify-client package. Use when adding web scraping, automation, or data extraction capabilities to an existing app via the Apify API.
| 1 | # Apify SDK Integration |
| 2 | |
| 3 | Add Apify Actor execution to an existing application. This skill covers the `apify-client` package for JS/TS and Python, plus the REST API for other languages. |
| 4 | |
| 5 | ## When to Use This Skill |
| 6 | |
| 7 | - Adding web scraping or automation to an existing app |
| 8 | - Calling Apify Actors programmatically from application code |
| 9 | - Building a product that uses Apify as a backend service |
| 10 | - Integrating Actor results into a data pipeline |
| 11 | |
| 12 | ## Critical: Package Naming |
| 13 | |
| 14 | > **`apify-client`** is the API client for **calling** Actors from your app. |
| 15 | > **`apify`** is the SDK for **building** Actors (wrong package for this use case). |
| 16 | > |
| 17 | > Always install `apify-client`. Never install `apify` for integration work. |
| 18 | |
| 19 | ## Prerequisites |
| 20 | |
| 21 | The user needs an `APIFY_TOKEN`. Direct them to **Console > Settings > Integrations** at https://console.apify.com/settings/integrations to create one. If they don't have an account: https://console.apify.com/sign-up (free, no credit card). |
| 22 | |
| 23 | Store the token securely — environment variable or secrets manager, never hardcoded. |
| 24 | |
| 25 | ## Finding the Right Actor |
| 26 | |
| 27 | Before writing integration code, find the Actor that fits the user's needs. Use the MCP tools if available: |
| 28 | - `search-actors` — search the Apify Store by keyword |
| 29 | - `fetch-actor-details` — get the Actor's input schema, output format, and pricing |
| 30 | |
| 31 | Alternatively, browse https://apify.com/store. Append `.md` to any Actor's Store URL to get its docs in markdown. |
| 32 | |
| 33 | ## JavaScript / TypeScript |
| 34 | |
| 35 | ### Install |
| 36 | |
| 37 | ```bash |
| 38 | npm install apify-client |
| 39 | ``` |
| 40 | |
| 41 | ### Synchronous Execution (wait for results) |
| 42 | |
| 43 | ```typescript |
| 44 | import { ApifyClient } from 'apify-client'; |
| 45 | |
| 46 | const client = new ApifyClient({ token: process.env.APIFY_TOKEN }); |
| 47 | |
| 48 | const run = await client.actor('apify/web-scraper').call({ |
| 49 | startUrls: [{ url: 'https://example.com' }], |
| 50 | maxPagesPerCrawl: 10, |
| 51 | }); |
| 52 | |
| 53 | const { items } = await client.dataset(run.defaultDatasetId).listItems(); |
| 54 | ``` |
| 55 | |
| 56 | `.call()` blocks until the Actor finishes. Use for short-running Actors (under a few minutes). |
| 57 | |
| 58 | ### Asynchronous Execution (start and poll/retrieve later) |
| 59 | |
| 60 | ```typescript |
| 61 | const run = await client.actor('apify/web-scraper').start({ |
| 62 | startUrls: [{ url: 'https://example.com' }], |
| 63 | }); |
| 64 | |
| 65 | // Poll for completion |
| 66 | const finishedRun = await client.run(run.id).waitForFinish(); |
| 67 | |
| 68 | // Retrieve results |
| 69 | const { items } = await client.dataset(finishedRun.defaultDatasetId).listItems(); |
| 70 | ``` |
| 71 | |
| 72 | Use `.start()` + `.waitForFinish()` for long-running Actors or when you need the run ID immediately. |
| 73 | |
| 74 | ### Retrieving Results |
| 75 | |
| 76 | ```typescript |
| 77 | // Dataset items (structured data from pushData) |
| 78 | const { items } = await client.dataset(run.defaultDatasetId).listItems({ |
| 79 | limit: 100, |
| 80 | offset: 0, |
| 81 | }); |
| 82 | |
| 83 | // Key-value store (files, screenshots, etc.) |
| 84 | const record = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT'); |
| 85 | ``` |
| 86 | |
| 87 | ### Error Handling |
| 88 | |
| 89 | ```typescript |
| 90 | try { |
| 91 | const run = await client.actor('apify/web-scraper').call(input); |
| 92 | |
| 93 | if (run.status !== 'SUCCEEDED') { |
| 94 | const log = await client.log(run.id).get(); |
| 95 | throw new Error(`Actor failed with status ${run.status}: ${log}`); |
| 96 | } |
| 97 | |
| 98 | const { items } = await client.dataset(run.defaultDatasetId).listItems(); |
| 99 | } catch (error) { |
| 100 | if (error.message?.includes('not found')) { |
| 101 | // Actor ID is wrong or Actor was deleted |
| 102 | } else if (error.statusCode === 401) { |
| 103 | // Invalid or missing APIFY_TOKEN |
| 104 | } |
| 105 | throw error; |
| 106 | } |
| 107 | ``` |
| 108 | |
| 109 | ## Python |
| 110 | |
| 111 | ### Install |
| 112 | |
| 113 | ```bash |
| 114 | pip install apify-client |
| 115 | ``` |
| 116 | |
| 117 | ### Synchronous Execution |
| 118 | |
| 119 | ```python |
| 120 | from apify_client import ApifyClient |
| 121 | import os |
| 122 | |
| 123 | client = ApifyClient(token=os.environ['APIFY_TOKEN']) |
| 124 | |
| 125 | run = client.actor('apify/web-scraper').call(run_input={ |
| 126 | 'startUrls': [{'url': 'https://example.com'}], |
| 127 | 'maxPagesPerCrawl': 10, |
| 128 | }) |
| 129 | |
| 130 | items = client.dataset(run['defaultDatasetId']).list_items().items |
| 131 | ``` |
| 132 | |
| 133 | ### Asynchronous Execution |
| 134 | |
| 135 | ```python |
| 136 | run = client.actor('apify/web-scraper').start(run_input={ |
| 137 | 'startUrls': [{'url': 'https://example.com'}], |
| 138 | }) |
| 139 | |
| 140 | # Poll for completion |
| 141 | finished_run = client.run(run['id']).wait_for_finish() |
| 142 | |
| 143 | items = client.dataset(finished_run['defaultDatasetId']).list_items().items |
| 144 | ``` |
| 145 | |
| 146 | ### Async Client (asyncio) |
| 147 | |
| 148 | ```python |
| 149 | from apify_client import ApifyClientAsync |
| 150 | |
| 151 | client = ApifyClientAsync(token=os.environ['APIFY_TOKEN']) |
| 152 | |
| 153 | run = await client.actor('apify/web-scraper').call(run_input={ |
| 154 | 'startUrls': [{'url': 'https://example.com'}], |
| 155 | }) |
| 156 | |
| 157 | items = (await client.dataset(run['defaultDatasetId']).list_items()).items |
| 158 | ``` |
| 159 | |
| 160 | ## REST API (Any Language) |
| 161 | |
| 162 | For languages without an official client, use the REST API directly. |
| 163 | |
| 164 | ### Start a Run |
| 165 | |
| 166 | ``` |
| 167 | POST https://api.apify.com/v2/acts/{actorId}/runs |
| 168 | Authorization: Bearer <APIFY_TOKEN> |
| 169 | Content-Type: application/json |
| 170 | |
| 171 | { "star |