iCIMS Careers Portal Scraper for icims.com
Pricing
from $0.75 / 1,000 results
iCIMS Careers Portal Scraper for icims.com
Collects job postings from any iCIMS careers portal on icims.com: title, company or brand, department, employmentType, postedAt, apply URL, and the location split out of the portal's country-state-city code. Follows the portal's own paginator, so a 1,000-posting site comes back in full.
Pricing
from $0.75 / 1,000 results
Rating
0.0
(0)
Developer
String
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
15 days ago
Last modified
Categories
Share
What does iCIMS Job Board Scraper do?
It walks a company's iCIMS careers portal and writes one row per posting on the job search, following the portal's own paginator until the postings run out. Each row carries the posting id, title, the company or brand the role sits under, the category, the position type, the posted date, the apply URL, and the location split out of the code iCIMS writes it in.
An iCIMS portal is addressed by subdomain, not by a path. Every tenant gets its own host, so
https://careers-emcorgroup.icims.com and https://careers-eastwestbank.icims.com are two different
portals. Pass the URL or just the subdomain.
Two things about iCIMS shape how this works:
- Every tenant renders job cards from the same platform build, so the card markup is a stable contract across all of them. What differs is which fields a tenant switches on and what it calls them.
- iCIMS serves the branded wrapper with zero cards unless the request presents iframe fetch metadata. That is not a URL parameter. Without those headers a portal listing 1,450 postings answers with a 98 KB shell and nothing in it.
No iCIMS account, cookie or API key is used. This is the job search a logged-out visitor sees.
What data does it extract?
| Field | Type | Description |
|---|---|---|
jobId | string | iCIMS's posting id, taken from the job URL. Stable, so use it to de-duplicate |
title | string | The posting title. Falls back to the anchor's title attribute when a tenant drops the heading |
company | string | From whichever company field the tenant publishes: Company, Subsidiary, Brand, Business Unit, Facility and similar. null when the portal publishes none |
tenant | string | The portal subdomain, for example careers-emcorgroup |
location | string | Verbatim, in the iCIMS code country-state-city. A posting open in several places lists them all, pipe-separated |
city | string | From that code, describing the first location listed |
state | string | From that code |
country | string | From that code |
isRemote | boolean | From the tenant's workplace field where it has one, otherwise from the location text. null when neither is present |
department | string | From the tenant's category field: Category, Function, Department, Job Family, Area of Interest and similar |
employmentType | string | From the tenant's type field: Position Type, Employment Type, Full/Part Time and similar |
postedAt | string | YYYY-MM-DD, or YYYY-MM-DDTHH:MM:SS when the portal publishes a time. Local wall clock, see the FAQ |
jobUrl | string | Direct link to the posting |
boardUrl | string | https://<tenant>.icims.com |
sourceUrl | string | The search page the row was read from |
collectedAt | string | ISO 8601 timestamp of the run |
How the fields are matched
Every value on an iCIMS card is labelled in the markup, either by a field-label span in the card
header or by a term in the header tag list. This Actor reads those labels and maps them onto contract
fields, rather than trusting positions. Tenants also prefix labels with the form section they came from
(Requisition Post Information* : Posted Date), so the label is reduced to its last colon segment
before matching.
The practical result: a portal that calls its category column Function and another that calls it
Area of Interest both land in department, and a field a tenant does not publish comes back null
instead of holding some other column's value.
Why scrape iCIMS careers portals?
iCIMS is where high-volume employers run their hiring: construction and trades, healthcare systems, retail chains, regional banks, manufacturers. These are not the companies you find well covered on technology-focused boards, and the postings are frequently hourly or site-based roles that aggregators index unevenly.
- Track requisition volume at a facility or region level using
location, which iCIMS codes precisely. - Watch a competitor's plant, store or clinic openings by the postings that appear before them.
- Feed a staffing agency's pipeline with fresh requisitions from a defined employer list.
- Segment by
employmentTypeto separate full-time headcount from seasonal or per-diem demand. - Supply labour-market research that needs employers outside the technology sector.
- Build local candidate-facing job boards for a metro area from the employers who actually hire there.
How to use it
- Open the company's "careers" or "search jobs" link. If the address bar shows something like
careers-<company>.icims.com, that host is the portal. - Put the URL, or just the subdomain, into Job boards. Up to 100 portals per run.
- Set Maximum results. This matters more here than on a single-request board, because a large portal can hold thousands of postings and pagination is where the requests go.
- Leave Concurrency at 3 unless you are collecting many portals and want to finish sooner.
- Start the run, then export as JSON, CSV, Excel or XML, or pull the dataset over the API.
maxItems is a budget shared across every portal in the input, and each portal stops paginating as
soon as the run can no longer keep the rows. A hundred portals under a thousand-row cap fetch a
thousand rows, not a hundred portals in full.
Input
| Field | Type | Default | Description |
|---|---|---|---|
boards | array of strings | required | iCIMS portal URLs or tenant subdomains. Between 1 and 100 entries |
maxItems | integer | 1000 | Cap on dataset rows, up to 50,000. Shared across all portals |
concurrency | integer | 3 | Portals fetched in parallel, up to 5 |
{"boards": ["https://careers-emcorgroup.icims.com","careers-eastwestbank"],"maxItems": 2000,"concurrency": 3}
A host outside icims.com is rejected and reported as you wrote it, rather than fetched.
Output
One row per job card. Illustrative shape:
{"jobId": "28417","title": "Journeyman Electrician","company": "EMCOR Group","tenant": "careers-emcorgroup","location": "US-PA-Wilkes-Barre","city": "Wilkes-Barre","state": "PA","country": "US","isRemote": false,"department": "Skilled Trades","employmentType": "Regular Full-Time","postedAt": "2026-07-14T09:32:00","jobUrl": "https://careers-emcorgroup.icims.com/jobs/28417/journeyman-electrician/job","boardUrl": "https://careers-emcorgroup.icims.com","sourceUrl": "https://careers-emcorgroup.icims.com/jobs/search?ss=1&searchRelation=keyword_all&in_iframe=1&pr=0","collectedAt": "2026-08-20T09:14:02.118Z"}
A posting open in several places keeps all of them in location, pipe-separated, and the three geo
fields describe the first one. A tenant that writes locations outside the coded form leaves those three
null with the raw string still in location.
Each run also writes a SUMMARY record with the item count, the failure count, and every page that
failed with its error.
How much does it cost?
Pay per event, charged once per result row written to the dataset. The current rate is on this Actor's pricing tab, and a portal that cannot be read writes no rows and costs nothing.
Unlike a single-request board feed, an iCIMS portal is paginated, so requests scale with rows. That is
what maxItems is really controlling: set it to what you intend to use.
Runs started from an Apify free plan stop at 250 requests and 250 results and say so in the run
status. Any paid plan runs the full input and your maxItems. The limit binds on requests as well as
rows because these fetches run on our own infrastructure, which Apify does not reimburse for free-plan
runs.
Using it with the Apify API
import { ApifyClient } from "apify-client";const client = new ApifyClient({ token: "<YOUR_APIFY_TOKEN>" });const run = await client.actor("usestring/icims-jobs").call({boards: ["https://careers-emcorgroup.icims.com"],maxItems: 2000,concurrency: 3});const { items } = await client.dataset(run.defaultDatasetId).listItems();const byState = items.reduce((counts, job) => {const key = job.state ?? "unknown";counts[key] = (counts[key] ?? 0) + 1;return counts;}, {});console.log(byState);
The run's SUMMARY record, in the same run's key-value store, lists anything that failed.
Is it legal to scrape iCIMS careers portals?
A careers portal exists to be found. Employers publish these pages for candidates and search engines, and this Actor reads what an anonymous visitor's browser is served. No login, no session cookie, no API key, nothing gated.
The rows describe requisitions rather than people. There are no applicant records, no application counts and no recruiter contact details in the output.
What you are permitted to do with the collected data still depends on your jurisdiction and on any terms you have accepted. Treat this section as context, not legal advice.
Related actors
- Workday Job Board Scraper covers the other enterprise ATS you will hit constantly in the same employer set.
- Taleo Job Board Scraper covers Oracle Taleo, still common at large employers that have not migrated.
- Greenhouse Job Board Scraper returns a whole board in one request for technology-sector employers.
- Indeed Job Listings Scraper is the better starting point when you want a labour market rather than named employers.
- Glassdoor Jobs Scraper pairs postings with the employer reputation data candidates read.
FAQ
How do I find a company's iCIMS portal? Click "careers" or "search jobs" on the company's site and
look at the host in the address bar. iCIMS portals are always <tenant>.icims.com, where the tenant is
a name the company chose, often prefixed with careers-. Both the full URL and the bare subdomain work
as input.
How many postings does one request return? It varies. iCIMS lets each tenant set its own page size,
so this Actor follows the portal's rel="next" link until the rows run out or the budget does, to a
ceiling of 200 pages per portal. That ceiling exists so a paginator that never terminates cannot
consume a whole run.
Why are company, department and employmentType sometimes empty? Because the tenant did not
put them on the job card. iCIMS lets each employer choose which fields appear and what to call them, so
those three are filled only when a matching labelled field is present.
Is postedAt in UTC? No, and it is deliberately not stamped as though it were. iCIMS renders the
posting time in the portal's own timezone and never states which one, so the value is kept as a local
wall-clock stamp rather than given an invented offset. Dates in M/D/YYYY form are read as en-US,
which is what these portals write.
Does it open each posting's detail page? No. The full JobPosting structured data lives on the
detail page, one fetch per posting, and this Actor stays on the search results. Follow jobUrl for the
description, requirements and any structured data the tenant publishes there.
What if a portal's paginator points somewhere else? A rel="next" link that leaves the portal's own
host is not followed. The paginator is markup the tenant controls, and following it off-host would mean
proxying a stranger's site under this Actor's pricing.
Can I search or filter within a portal? Not from the input. The run collects the portal's unfiltered job search and you filter the dataset afterwards, which is usually cheaper than one run per filter.
Feedback
If a portal comes back empty, or a field lands in the wrong column, open an issue from this Actor's Store page and include the portal host. Label mapping is the part most likely to need a new alias, and a named portal is all it takes to add one.