Accupass Public Events
Pricing
$1.50 / 1,000 results
Accupass Public Events
Public Accupass events from the paginated listing API, with optional public event details.
Pricing
$1.50 / 1,000 results
Rating
0.0
(0)
Developer
Stone Jade
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Node.js 20 ESM Apify SDK v3 Actor. Uses HTTP only, with no browser, login or cookies. Lists public Taiwan Accupass events using POST https://api.accupass.com/v3/search/SearchEvents, relevance sort (sortBy: "4"), and zero-based pages of 25. Stops at the reported total or maxItems; duplicate event IDs are removed. Each page is written in one dataset batch.
Example input:
{"keyword":"建築","maxItems":100,"fetchDetails":false,"includeAds":false,"includeOrganizerContact":false,"proxy":{"useApifyProxy":false}}
keyword defaults to empty; maxItems defaults to 1000 and must be a positive integer. fetchDetails defaults to false. includeAds defaults to false, excluding entries with isAD: true before detail requests and the item limit. Set it to true to include advertisements. Output URLs have utm_* tracking parameters removed; other query parameters and fragments are preserved. includeOrganizerContact defaults to false and only takes effect with details enabled. proxy accepts Apify proxy configuration or custom proxy URLs; direct connections are the default. The previous proxyConfiguration input is also accepted for compatibility.
Listing output includes event ID, title, public event URL, dates, timezone, city, event place type, tags, image, likes, page views, external link metadata and advertisement metadata. Views and likes are never reported as attendance; unavailable registration and attendee counts remain null. Detail-only fields remain null or empty in listing mode.
Details add plain-text description, venue/address, organizer name and public URL, category, and available ticket offers/price range. Offers depend on public structured data; missing offers remain empty, and a minimum registration-button price has an unknown maximum. These are not a guarantee of current availability or a complete ticket inventory. Only organizer email/phone explicitly published in organizer data are emitted when contact is enabled. No attendee personal data is extracted. Descriptions are public event content, not an email/contact discovery mechanism.
Dates in both modes use ISO 8601 with +08:00 (Taiwan time), preserving the source instant. Categories come only from visible page category labels, with whitespace folded: for example Food & Drink, Outdoor, and Science & Tech. Internal category keys and the literal None are never used; missing visible labels produce []. Visible online labels take precedence over structured location metadata, and online events always have address: null and venue: null. Offline venue text is copied from public structured data and can contain directions rather than a venue name. Listing images can be thumbnails; detail images use the public page image.
For output compatibility, unavailable fields remain explicit: registrationCount and attendeeCount are always null because this scraper has no public count source. redirectUrl, linkUrl, advertIdNumber, and utm are optional API metadata and are null when the API does not supply them; they are not inferred from other fields. ticketPrices is [] unless public Event JSON-LD supplies offers (none of the 30 independent QA pages did). A registration button supplies only priceRange.min, leaving priceRange.max null. These fields do not promise ticket inventory, attendance statistics, or a known maximum price.
The default key-value store receives OUTPUT and RUN_SUMMARY at the end, including failed scraping runs. Both contain items (successfully saved dataset records), total (the last API-reported search total, or null if unavailable), mode (list or detail), truncated, failed, and detailFailures (detail pages that could not be fetched). OUTPUT is the compact summary; RUN_SUMMARY also contains request, timing and memory counters plus detailFallbacks (pages saved with listing fields after missing Event JSON-LD). On successful runs, truncated marks stopping at maxItems with remaining eligible records or unread pages, or stopping 20 seconds before ACTOR_TIMEOUT_AT. A fully traversed search is not truncated merely because ads or duplicates were excluded; the API total is before those exclusions. On failed runs it is true when saved items are below a known total, or null when the total is unknown. Summaries describe saved batches, not a guarantee of completeness under changing search results.
The Actor checks api.accupass.com/robots.txt before listing and also checks www.accupass.com/robots.txt when details are requested. It honors disallow rules and crawl delays for its AccupassPublicEventsActor identity. Missing robots (404/410) allow access; other failures stop the run. Redirects are not followed. Detail requests run in waves of up to two; after any 429 subsequent waves use one. 429s have up to two retries with exponential backoff and Retry-After support. Listing and robots HTTP errors fail the run. A detail network or HTTP failure keeps that event's listing fields, sets detailError to the error message, and counts it in detailFailures; missing Event JSON-LD still uses the structure fallback. In-flight requests may finish after a 429. Failed runs can retain previously written page batches. Zero output fails the run, including a legitimate search with no matches.
Responses are capped at 5 MiB using got download progress cancellation, including decompressed bodies. Detail parsing reuses one page DOM and releases the HTML after parsing. Missing Event JSON-LD logs a warning and saves the listing item with null detail fields. Memory diagnostics log RSS, heap used, external memory and array buffers in bytes after Actor initialization, after input/proxy setup, after each list page, every ten detail attempts, and at the end. Each record includes a phase label.
The final summary logs request count (including robots and retries), saved items, 429 count, decoded response-body bytes (not billed proxy/wire bytes), mean detail operation duration including waits/retries, and elapsed seconds. processRssSampledPeakBytes replaces rssMemoryPeak: it records this Node process's RSS sampled every 100 ms and at request/completion boundaries during scraping, in bytes. processRssLifetimePeakBytes records the OS process RSS high-water mark (process.resourceUsage().maxRSS * 1024), including startup before scraping. Synchronous parsing can block timer samples, so use the lifetime value for the process peak. Neither metric is a platform/container memory measurement. A reported 175 MiB versus platform 125 MiB cannot be explained by MB/MiB conversion alone; the historical platform sampling/accounting data is needed to establish that difference. Memory defaults to 256 MB; the local 50-detail measurement below checks the 128 MiB target, while platform initialization, dataset writes and other page contents can change usage.
Price
What 1,000 events cost you: $1.50 in total. Events are charged at $0.0015 per saved event ($1.50 per 1,000), with no run-start fee — you pay only for events actually saved to the dataset. There is currently no other Accupass scraper on the Apify Store, so this is the only priced option for Accupass event data.
Failed detail rows are still charged
Billing uses the pay-per-event apify-default-dataset-item event, which charges every row pushed to the dataset at the full per-event price. Rows with detailError (detail fetch failed) and rows with detailSkipped: true (reason deadline) are still written, so they are charged at the normal per-event price. OUTPUT.detailFailures and OUTPUT.detailSkipped count them.
Run locally with Node.js 20:
npm installnpm testnpm start
To measure 50 live details with a 100 MiB V8 heap and at most one request start per second (including robots and listing), run:
node --max-old-space-size=100 scripts/measure-memory.js
This uses the main scraper and Apify imports without platform initialization or dataset storage; it reports sampled RSS and the OS peak RSS.
Historical slicing experiment (subsequently reverted): on 2026-10-14, Node.js 20.19.2, two fresh processes ran that command (50 live details, 54 requests each, no 429s):
| Measurement | Before | After slicing |
|---|---|---|
| OS lifetime peak RSS, bytes | 118,681,600 | 118,743,040 |
| OS lifetime peak RSS, MiB | 113.18 | 113.24 |
| 10 ms harness sampled peak RSS, bytes | 118,681,600 | 118,329,344 |
| Elapsed seconds | 54.771 | 61.673 |
| Response body bytes | 8,967,548 | 8,964,739 |
Both process peaks were below 128 MiB (134,217,728 bytes), and also below decimal 128 MB. This pair does not demonstrate an RSS reduction: the OS peak increased by 61,440 bytes (0.06 MiB). Live response contents and GC/allocator timing differ; tests ran in a separate process during the after measurement. The saved detail fixture shrank from 208,230 to 148,833 bytes before DOM construction (28.5%), with all output fields identical in fixture tests, including opt-in organizer contact. Raw logs: docs/memory-before.log, docs/memory-after.log. This local harness includes Apify imports but does not measure Actor initialization, platform memory accounting or dataset storage.
To isolate startup memory without live requests, run:
APIFY_LOCAL_STORAGE_DIR=/tmp/accupass-memory-diagnostic node --expose-gc scripts/diagnose-startup-memory.js
A local Node.js 20.19.2 run with Apify 3.7.2 measured the following RSS (MiB, rounded). Dynamic imports expose memory allocated before the normal startup log:
| Phase | RSS MiB |
|---|---|
| Node baseline | 49.7 |
| After Apify import | 90.4 |
| After request module / got import | 102.5 |
| After hpagent import | 102.5 |
| After parser / Cheerio import | 108.9 |
| After scraper import | 109.2 |
| After Actor.init | 110.0 |
| After input / direct proxy setup | 110.9 |
| After custom proxy configuration | 111.2 |
| Saved list body buffered | 111.3 |
| Saved list body parsed | 111.4 |
Imports dominate early RSS in this measurement. Cheerio loads even for list-only runs because the parser imports it at module scope. The 16,089-byte saved list fixture added about 0.25 MiB across buffering and mapping; the scraper processes one list page at a time and clears response bodies after reading them. Larger live pages, concurrent detail bodies/DOMs, SDK dataset storage, and the growing deduplication set can add memory later. Releasing the fixture and forcing GC reduced heap used from about 31.0 to 20.6 MiB, while RSS stayed high (113.8 MiB): RSS includes runtime/native allocations and retained allocator pages, so heap release need not immediately reduce RSS. These sequential measurements include allocation/GC timing effects; they are indicative rather than isolated package benchmarks. Direct and custom proxy configuration were measured locally; managed Apify proxy initialization and live dataset writes were not measured.
Use Apify local input storage or the Apify platform input editor. The Dockerfile uses apify/actor-node:20 and installs from the lockfile. Tests use saved fixtures and simulated HTTP responses; they do not measure live rate limits or guarantee future API/HTML compatibility. The listing endpoint and cost/rate observations come from /workspace/tuning/2026-10-14-accupass-ratelimit.md; site behavior may change. API and detail parse errors fail clearly rather than silently emitting empty output.