Internship Jobs Scraper — New Grad, Stage & Alternance Feed
Pricing
from $0.48 / 1,000 results
Internship Jobs Scraper — New Grad, Stage & Alternance Feed
Internship jobs scraper for Greenhouse, Lever, Ashby & SmartRecruiters boards. Returns internship, new-grad, apprenticeship, stage and Werkstudent postings with company, country, remote flag, dates and URL as JSON/CSV. From $0.48 per 1,000 results.
Pricing
from $0.48 / 1,000 results
Rating
0.0
(0)
Developer
Alexandre Manguis
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
10 days ago
Last modified
Categories
Share
This internship jobs scraper reads the public job-board APIs of Greenhouse, Lever, Ashby and SmartRecruiters, keeps only early-career postings (internships, new-grad, graduate programmes, apprenticeships, working students) and returns them as clean JSON, CSV or Excel. It can also return only the postings that are new since your last run.
What does it do?
Most career-page scrapers return every job of a company. This Actor does the opposite: it scans a built-in list of 60 verified US and EU employer boards (plus any boards you add), classifies each posting with a rule-based multilingual classifier (English, French, German, Spanish) and only pushes — and bills — early-career roles. Senior postings are never returned or charged.
Recognised types: internship, new_grad, graduate_program, apprenticeship, working_student, entry_level. Examples of terms it understands: intern, new grad, graduate programme, stage, alternance, apprentissage, Werkstudent, Praktikum, Ausbildung, prácticas.
Data source: the endpoints that Greenhouse, Lever, Ashby and SmartRecruiters publish so employers' jobs can be listed elsewhere. No login, no browser, no CAPTCHA.
Who is it for / use cases
- Job-bot builders: daily "new internships since yesterday" feed to Discord, Slack or Telegram using a schedule,
onlyNewand a webhook. - University career centres, bootcamps and student job boards: fill a board with fresh internship and graduate-programme postings.
- French / EU coverage: the classifier recognises stage, alternance, apprentissage and Werkstudent titles, and the
countriesfilter (e.g.FR,DE) was tested on a production run. The built-in boards are mostly English-language postings; add your own French/German employer boards viacompaniesfor more local-language offers. - Newsletters: filter by country, remote, season (e.g. "Summer 2027") or keyword.
- Recruiting analysts: track which companies open early-career programmes and when.
Features
- Early-career-only output, classified in EN / FR / DE / ES;
matchedTermshows which term triggered the match. - Four ATS supported: Greenhouse, Lever, Ashby, SmartRecruiters.
- Built-in seed list of 60 company boards, extendable with
ats:tokenentries or public board URLs. Invalid entries are skipped with a warning. - Filters: role types, countries (ISO codes), title/department keywords, remote only, posted within N days.
- Incremental mode (
onlyNew+stateKey): several schedules can keep separate "seen" lists. - Optional plain-text description.
- Respects your maximum charge per run; stops gracefully when it is reached.
Input
| Field | Type | Default | Description |
|---|---|---|---|
roleTypes | array | internship, new_grad, graduate_program, apprenticeship, working_student | Early-career types to keep (entry_level is also available). |
useDefaultCompanies | boolean | true | Scan the built-in company boards. |
companies | array | [] | Extra boards: greenhouse:stripe, lever:spotify, ashby:notion, smartrecruiters:BoschGroup or a public board URL. |
countries | array | [] | ISO 3166-1 alpha-2 codes to keep. Empty = all. Postings whose country is unknown are excluded when you set this. |
keywords | array | [] | A posting must contain at least one in its title or department. |
remoteOnly | boolean | false | Keep only postings flagged remote. |
postedWithinDays | integer | 30 | Published/updated in the last N days; 0 = no limit. Undated postings are kept. |
onlyNew | boolean | false | Return only postings not returned by a previous run with the same stateKey. |
stateKey | string | default | Name of the incremental state. |
includeDescription | boolean | false | Add the plain-text description (larger dataset, extra requests for Greenhouse and SmartRecruiters). |
maxResults | integer | 50 | Maximum postings returned (and billed), 1–10000. |
proxyConfiguration | object | Apify Proxy | Public APIs normally work without one; a datacenter proxy is a safe default. |
Example input:
{"roleTypes": ["internship", "apprenticeship", "working_student"],"countries": ["FR", "DE"],"companies": ["greenhouse:airbnb", "https://jobs.lever.co/spotify"],"postedWithinDays": 14,"onlyNew": true,"stateKey": "discord-fr-bot","maxResults": 200}
Output
One dataset row per early-career posting. Real sample from a production run (earlyCareerType: internship):
{"jobId": "greenhouse:stripe:8241260","title": "High School Internship, Software Engineering (Summer 2027)","company": "Stripe","ats": "greenhouse","boardToken": "stripe","earlyCareerType": "internship","matchedTerm": "Internship","location": "Seattle, San Francisco","country": "US","remote": false,"department": null,"employmentType": null,"seasonHint": "Summer 2027","degreeLevelHint": null,"language": "en","postedAt": "2026-09-30T15:38:09.000Z","updatedAt": "2026-10-02T03:54:21.000Z","jobUrl": "https://stripe.com/jobs/search?gh_jid=8241260","scrapedAt": "2026-10-05T20:59:23.667Z"}
Output fields & fill rates
Measured on the production medium run (40 postings, includeDescription: true, postedWithinDays: 0). Fill rates depend on what each ATS publishes.
| Field | Fill rate | Notes |
|---|---|---|
jobId, title, company, ats, boardToken, jobUrl, scrapedAt | 100% | jobId = <ats>:<boardToken>:<postingId> |
earlyCareerType, matchedTerm, language | 100% | Classifier output |
location, remote | 100% | |
country | 95% | Derived from the location text; null if unknown |
postedAt, updatedAt | 100% | null when the ATS gives no date |
description | 100% | Only with includeDescription: true |
seasonHint | 5% | Only when the title/description names a season or start date |
degreeLevelHint | 7.5% | bachelor / master / phd / bootcamp, only when mentioned |
department, employmentType | 0% | Not provided by the ATS boards in this run — do not rely on them |
isNew | — | Present (true) only when onlyNew is enabled |
How to use via API
Replace YOUR_APIFY_TOKEN with your own token and ACTOR_ID with this Actor's ID (shown on the Actor page).
curl
curl -X POST "https://api.apify.com/v2/acts/ACTOR_ID/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"roleTypes":["internship"],"countries":["FR"],"maxResults":50}'
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('ACTOR_ID').call({roleTypes: ['internship', 'new_grad'],onlyNew: true,stateKey: 'my-newsletter',maxResults: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.map((j) => `${j.company}: ${j.title} — ${j.jobUrl}`));
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("ACTOR_ID").call(run_input={"roleTypes": ["internship", "apprenticeship"],"countries": ["FR", "DE"],"onlyNew": True,"stateKey": "my-bot","maxResults": 100,})for job in client.dataset(run["defaultDatasetId"]).iterate_items():print(job["company"], job["title"], job["jobUrl"])
Daily bot recipe: create a schedule (e.g. every day), set onlyNew: true with a fixed stateKey, and add a webhook on "run succeeded" that fetches the dataset and posts it to Discord, Slack or Telegram.
Examples of each mode (real production runs)
| Mode | Input | Result |
|---|---|---|
| EU filter | roleTypes: internship, apprenticeship, working_student, graduate_program, countries: ["FR","DE"], maxResults: 20 | 20 items, 0 error rows, country filled 100%. First item: Databricks "Product Management Intern (2026) - Berlin", country: DE. Titles seen in this run were English; French/German-titled postings are matched by the classifier but depend on which boards publish them. |
First onlyNew run | onlyNew: true, stateKey: "qa-proof", maxResults: 10 | 10 items, all with isNew: true. |
Second onlyNew run (same stateKey) | identical input | 10 items, all isNew: true, and different postings from the first run (e.g. Stripe "Data Analyst, Intern" instead of "Software Engineer, Intern"): already-returned postings are skipped. |
Pricing
Pay per result: one event per early-career posting pushed to the dataset. Nothing is charged for postings that do not match, skipped boards or empty runs. Price per 1,000 results depends on your Apify plan:
| Plan | Per 1,000 results |
|---|---|
| FREE | $0.72 |
| BRONZE | $0.62 |
| SILVER | $0.55 |
| GOLD and above | $0.48 |
At the GOLD price this is below the cheapest comparable Store Actor we found ($0.60 per 1,000 at GOLD). On the production medium run, platform usage was well under $0.001 for the whole run (see TEST_REPORT.json). Set maxResults or a maximum charge to cap spending.
Troubleshooting
- Few or no results: widen
postedWithinDays(or set0), removecountries/keywords, or add more boards incompanies. Most postings on a board are not early-career, so a small board may have none. - Country filter drops postings: postings whose location has no recognisable country have
country: nulland are excluded whencountriesis set. - A board is skipped: the token may be wrong or the company moved to another ATS; a warning is logged and the run continues.
onlyNewreturns nothing on the second run: expected — nothing new was published. Use a differentstateKeyfor a separate list.department/employmentTypeare empty: these boards did not provide them in our tests.
FAQ
Which companies are covered? 60 built-in US and EU boards on Greenhouse, Lever, Ashby and SmartRecruiters, plus any boards you add. Coverage is a seed list, not every employer.
How accurate is the classification? It is rule-based with word-boundary matching and an exclusion list (e.g. "Internal", "International"). Rare title formats can be missed or misclassified; matchedTerm helps you audit.
Does it scrape LinkedIn, Indeed or Handshake? No. Only public ATS job-board endpoints, no login or bypass.
Is personal data collected? No candidate data. Only what employers publish on their public job boards; recruiter contacts are not extracted as fields. Descriptions are off by default.
Is it legal? The endpoints are published for syndicating job postings, but individual ATS terms may restrict bulk reuse. Output links back to the original posting; you are responsible for how you republish it.
Keywords
internship jobs scraper, new grad jobs api, internship api, graduate jobs feed, entry level jobs scraper, alternance offres, stage offres, werkstudent jobs, apprenticeship jobs, greenhouse jobs scraper, lever jobs scraper, ashby jobs scraper, early career jobs, summer internship 2027, student jobs feed
Hashtags
#internships #newgrad #jobs #earlycareer #alternance #werkstudent #greenhouse #lever #ashby #jobfeed #apify