iCIMS Jobs Without an Official API
A career site in, structured requisitions out, on either of the two public iCIMS surfaces.
When to use this skill
- The user searched for iCIMS API documentation and found nothing they can sign up for.
- They want live postings from employers they do not work for.
- They are feeding a job board, a market-intel dashboard, or a recruiting tool.
- They have a company name but not the career-site URL.
Not for: monitoring the same employers on a schedule and reacting to changes. Use the companion apify-icims-job-monitor skill, which is far cheaper for that. See references/actor-index.md.
Why there is no official option
iCIMS sells integration access to its own customers. If the employer is not your employer, the public career site is the surface you have, and every one of those sites is laid out differently. This Actor normalizes both public layouts into one row shape, so a company that moves between them does not break your pipeline.
What you get
One dataset row per job. result_type separates job rows from error rows:
url (canonical and slug-free, safe as a dedupe key), id (the employer's own requisition number)
title, organization, organization_url, category
description_text, description_html, description_markdown
employment_type, locations_derived, remote_derived, latitude, longitude
date_posted, date_updated, date_validthrough, salary_raw
apply_url, additional_fields (the employer's own labelled extras, such as travel or visa notes)
tenant, source_surface, source_domain, source_url, scraped_at
Field names follow common job-feed conventions, so an existing normalizer usually ingests them unchanged.
Prerequisites
The Actor
Run it with the Apify CLI
One career site, full detail:
apify actors call "johnvc/icims-careers-api" -i '{"startUrls":[{"url":"https://careers-rambus.icims.com"}],"descriptionFormat":"text","maxJobsPerSite":25}' \
--json \
--user-agent apify-awesome-skills/apify-icims-jobs-api \
2>/dev/null
Company names instead of URLs, for a watchlist:
apify actors call "johnvc/icims-careers-api" -i '{"companies":["rambus","maxlinear"],"descriptionFormat":"text","maxJobsPerSite":10}' \
--json \
--user-agent apify-awesome-skills/apify-icims-jobs-api \
2>/dev/null
Engineering roles only, markdown descriptions:
apify actors call "johnvc/icims-careers-api" -i '{"startUrls":[{"url":"https://careers-rambus.icims.com"}],"keywords":["engineer"],"descriptionFormat":"markdown"}' \
--json \
--user-agent apify-awesome-skills/apify-icims-jobs-api \
2>/dev/null
Confirm live pricing and the input schema before a large batch:
apify actors info "johnvc/icims-careers-api" --json \
--user-agent apify-awesome-skills/apify-icims-jobs-api \
2>/dev/null
Every call carries the three flags this repo expects: --json, --user-agent apify-awesome-skills/apify-icims-jobs-api, and 2>/dev/null.
Run it from Claude or another AI agent (MCP)
The Actor is MCP-ready. Add the hosted server URL:
https://mcp.apify.com/?tools=actors,docs,johnvc/icims-careers-api
Then ask, for example: "Pull the open engineering roles from Rambus and tell me which ones are remote." MCP setup docs: https://docs.apify.com/platform/integrations/mcp
Workflow
- Start with one employer and
maxJobsPerSite set low, so you see the row shape before you pay for a full crawl.
- Prefer
descriptionFormat: "text" unless you need markup. It roughly halves the payload.
- Use
companies when you have names, startUrls when you have addresses. You can pass both in one run; results are deduplicated.
- Dedupe downstream on
url, which is canonical and does not change when the employer edits a job title.
- Check
result_type before treating a row as a job.
Inputs
startUrls (array of {url}): portal root, sitemap URL, search URL, single job URL, or a career site on the employer's own domain
companies (array of strings): company names, resolved to iCIMS tenants for you
newerThan (string): ISO date, timestamp, or a window like 24h, 7d, 2w
cutoffField (enum updated, posted, default updated)
includeDetails (boolean, default true): false gives list-only rows
descriptionFormat (enum both, text, html, markdown, default both)
keywords (array of strings): title filter
maxJobsPerSite (integer, default 0 meaning no limit)
maxJobs (integer, default 0 meaning no limit)
detailConcurrency (integer, default 5, max 10)
proxyConfiguration (object): off by default, only needed for tenants that restrict traffic by network
Cost
Billing is pay per event, plus a negligible platform fee per dataset row. Confirm live prices with the info command above rather than trusting a number copied here.
- Charged per job row delivered, with a small charge to start a run.
- A single mid-size employer, roughly 50 jobs with full detail, lands in the small change range.
- Turning on
proxyConfiguration moves rows onto a higher-priced event, because proxied job pages are served uncompressed and cost real money to fetch. Leave it off unless a site actually needs it.
Suggested confirmation thresholds: warn the user over about $5; get explicit confirmation over about $20. Present cost as "around $X", never a guarantee.
Honest limits
- Public career-site data only. Nothing behind an employer login, no applicant or candidate data.
- Salary appears only when the employer publishes it in the posting. Nothing is inferred or estimated.
- Some tenants restrict traffic by network and return an
ip_gated error row. A proxy sometimes helps and sometimes does not, because the restriction is often an allowlist rather than a bot block.
- There is no directory of every iCIMS employer. You bring the company list.
- Error rows still cost a dataset item and the run still costs its start charge.
Troubleshooting
tenant_not_found: the employer retired that career site. Check whether they moved to a new URL.
not_icims: the domain is a career site, just not an iCIMS one.
ip_gated: the tenant restricts by network. Try proxyConfiguration, and accept that it may not clear.
- Zero rows and zero errors: the employer genuinely has no open jobs, or your
keywords filter matched nothing.
- Unexpected duplicates: dedupe on
url, not on title.
See references/gotchas.md for cost guardrails and error recovery, and references/actor-index.md for the Actor routing table.
Related Actors
1---2name: apify-icims-jobs-api3description: Pull live job postings from any iCIMS career site with the Apify iCIMS Careers API Actor (johnvc/icims-careers-api). iCIMS ships no public read API for postings, so this is the icims api most teams end up needing. Give it a career-site URL or just a company name and get structured rows back, each with title, the employer's own requisition id, organization, locations, employment type, posted and updated dates, salary when published, description as text or HTML or markdown, and the apply link. It covers both public iCIMS surfaces, the classic careers-tenant.icims.com portals and the modern iCIMS career sites hosted on the employer's own domain, and works out which one a company uses on its own. Use when the user wants iCIMS jobs, an ats api for recruiting or market data, job data for a board or aggregator, or to scrape job postings from a career site. Pay per job returned, MCP-ready for Claude and other AI agents.4license: MIT5---67# iCIMS Jobs Without an Official API89A career site in, structured requisitions out, on either of the two public iCIMS surfaces.1011## When to use this skill1213- The user searched for iCIMS API documentation and found nothing they can sign up for.14- They want live postings from employers they do not work for.15- They are feeding a job board, a market-intel dashboard, or a recruiting tool.16- They have a company name but not the career-site URL.1718Not for: monitoring the same employers on a schedule and reacting to changes. Use the companion apify-icims-job-monitor skill, which is far cheaper for that. See `references/actor-index.md`.1920## Why there is no official option2122iCIMS sells integration access to its own customers. If the employer is not your employer, the public career site is the surface you have, and every one of those sites is laid out differently. This Actor normalizes both public layouts into one row shape, so a company that moves between them does not break your pipeline.2324## What you get2526One dataset row per job. `result_type` separates `job` rows from `error` rows:2728- `url` (canonical and slug-free, safe as a dedupe key), `id` (the employer's own requisition number)29- `title`, `organization`, `organization_url`, `category`30- `description_text`, `description_html`, `description_markdown`31- `employment_type`, `locations_derived`, `remote_derived`, `latitude`, `longitude`32- `date_posted`, `date_updated`, `date_validthrough`, `salary_raw`33- `apply_url`, `additional_fields` (the employer's own labelled extras, such as travel or visa notes)34- `tenant`, `source_surface`, `source_domain`, `source_url`, `scraped_at`3536Field names follow common job-feed conventions, so an existing normalizer usually ingests them unchanged.3738## Prerequisites3940- Apify account (sign up at https://apify.com?fpr=9n7kx3&fp_sid=skillrepo).41- Authentication via `apify login`, or an `APIFY_TOKEN` environment variable (Apify Console, Settings, Integrations).4243## The Actor4445- Store page: https://apify.com/johnvc/icims-careers-api?fpr=9n7kx3&fp_sid=skillrepo46- Actor ID: `johnvc/icims-careers-api`47- Pricing: pay per event; see the cost section below and `references/gotchas.md` for live-price commands.4849## Run it with the Apify CLI5051One career site, full detail:5253```bash54apify actors call "johnvc/icims-careers-api" -i '{"startUrls":[{"url":"https://careers-rambus.icims.com"}],"descriptionFormat":"text","maxJobsPerSite":25}' \55 --json \56 --user-agent apify-awesome-skills/apify-icims-jobs-api \57 2>/dev/null58```5960Company names instead of URLs, for a watchlist:6162```bash63apify actors call "johnvc/icims-careers-api" -i '{"companies":["rambus","maxlinear"],"descriptionFormat":"text","maxJobsPerSite":10}' \64 --json \65 --user-agent apify-awesome-skills/apify-icims-jobs-api \66 2>/dev/null67```6869Engineering roles only, markdown descriptions:7071```bash72apify actors call "johnvc/icims-careers-api" -i '{"startUrls":[{"url":"https://careers-rambus.icims.com"}],"keywords":["engineer"],"descriptionFormat":"markdown"}' \73 --json \74 --user-agent apify-awesome-skills/apify-icims-jobs-api \75 2>/dev/null76```7778Confirm live pricing and the input schema before a large batch:7980```bash81apify actors info "johnvc/icims-careers-api" --json \82 --user-agent apify-awesome-skills/apify-icims-jobs-api \83 2>/dev/null84```8586Every call carries the three flags this repo expects: `--json`, `--user-agent apify-awesome-skills/apify-icims-jobs-api`, and `2>/dev/null`.8788## Run it from Claude or another AI agent (MCP)8990The Actor is MCP-ready. Add the hosted server URL:9192`https://mcp.apify.com/?tools=actors,docs,johnvc/icims-careers-api`9394Then ask, for example: "Pull the open engineering roles from Rambus and tell me which ones are remote." MCP setup docs: https://docs.apify.com/platform/integrations/mcp9596## Workflow97981. Start with one employer and `maxJobsPerSite` set low, so you see the row shape before you pay for a full crawl.992. Prefer `descriptionFormat: "text"` unless you need markup. It roughly halves the payload.1003. Use `companies` when you have names, `startUrls` when you have addresses. You can pass both in one run; results are deduplicated.1014. Dedupe downstream on `url`, which is canonical and does not change when the employer edits a job title.1025. Check `result_type` before treating a row as a job.103104## Inputs105106- `startUrls` (array of `{url}`): portal root, sitemap URL, search URL, single job URL, or a career site on the employer's own domain107- `companies` (array of strings): company names, resolved to iCIMS tenants for you108- `newerThan` (string): ISO date, timestamp, or a window like `24h`, `7d`, `2w`109- `cutoffField` (enum `updated`, `posted`, default `updated`)110- `includeDetails` (boolean, default true): false gives list-only rows111- `descriptionFormat` (enum `both`, `text`, `html`, `markdown`, default `both`)112- `keywords` (array of strings): title filter113- `maxJobsPerSite` (integer, default 0 meaning no limit)114- `maxJobs` (integer, default 0 meaning no limit)115- `detailConcurrency` (integer, default 5, max 10)116- `proxyConfiguration` (object): off by default, only needed for tenants that restrict traffic by network117118## Cost119120Billing is pay per event, plus a negligible platform fee per dataset row. Confirm live prices with the info command above rather than trusting a number copied here.121122- Charged per job row delivered, with a small charge to start a run.123- A single mid-size employer, roughly 50 jobs with full detail, lands in the small change range.124- Turning on `proxyConfiguration` moves rows onto a higher-priced event, because proxied job pages are served uncompressed and cost real money to fetch. Leave it off unless a site actually needs it.125126Suggested confirmation thresholds: warn the user over about $5; get explicit confirmation over about $20. Present cost as "around $X", never a guarantee.127128## Honest limits129130- Public career-site data only. Nothing behind an employer login, no applicant or candidate data.131- Salary appears only when the employer publishes it in the posting. Nothing is inferred or estimated.132- Some tenants restrict traffic by network and return an `ip_gated` error row. A proxy sometimes helps and sometimes does not, because the restriction is often an allowlist rather than a bot block.133- There is no directory of every iCIMS employer. You bring the company list.134- Error rows still cost a dataset item and the run still costs its start charge.135136## Troubleshooting137138- `tenant_not_found`: the employer retired that career site. Check whether they moved to a new URL.139- `not_icims`: the domain is a career site, just not an iCIMS one.140- `ip_gated`: the tenant restricts by network. Try `proxyConfiguration`, and accept that it may not clear.141- Zero rows and zero errors: the employer genuinely has no open jobs, or your `keywords` filter matched nothing.142- Unexpected duplicates: dedupe on `url`, not on title.143144See `references/gotchas.md` for cost guardrails and error recovery, and `references/actor-index.md` for the Actor routing table.145146## Related Actors147148- Workday Careers API: https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3&fp_sid=skillrepo149- Google Jobs Scraper: https://apify.com/johnvc/Google-Jobs-Scraper?fpr=9n7kx3&fp_sid=skillrepo150- LinkedIn Company API: https://apify.com/johnvc/linkedin-company-api?fpr=9n7kx3&fp_sid=skillrepo151- Crunchbase Company API: https://apify.com/johnvc/crunchbase-company-api?fpr=9n7kx3&fp_sid=skillrepo