Gupy Jobs Scraper - Jobs, Companies, Locations & Deadlines
Pricing
from $1.00 / 1,000 job results
Gupy Jobs Scraper - Jobs, Companies, Locations & Deadlines
Scrape public jobs from Gupy.io by keyword, state, city, workplace type, job type, company, PWD, and feedback badge. Extract rich job details, company information, locations, application deadlines, and badge data.
Pricing
from $1.00 / 1,000 job results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
2
Monthly active users
10 days ago
Last modified
Categories
Share
Gupy.io Jobs Scraper: Job Listings, Companies & Application Deadlines
Gupy.io Jobs Scraper turns Gupy.io, a Brazilian job board and recruitment platform, into a clean jobs data feed. Search by keyword, Brazilian state, city, workplace type, job type, exact company career page, PWD accessible jobs, or feedback badge companies, or paste portal search links and direct Gupy job links. Turn on full detail enrichment for the complete per job record, sort results newest, oldest, or by company, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.
Why This Scraper?
- Two ways to find jobs. Run a filtered search (keyword, state, city, workplace type, job type, company, PWD only, feedback badge only) or paste portal search links and direct Gupy job links. Direct job links are always fetched in full, whatever the detail toggle is set to.
- Optional full detail enrichment. Turn on Fetch details to add the complete per job record. The detail enrichment charge only applies to a job that actually reaches the dataset, not to every detail page fetched. Jobs from direct Gupy job links are always fully fetched, so they carry the detail enrichment charge even with Fetch details off.
- Sort after collection. Order saved jobs newest, oldest, or by company name, A to Z.
- Full catalogue pagination by default. The walk covers every result page unless you cap it, and leading pages that were all collected before are skipped past rather than ending the walk. See the pagination notes below for the cases where a walk can still end early.
- Survives interruptions. A run that gets migrated or restarted mid walk reloads its already collected jobs and ids, so they are not saved twice, detail fetched again, or charged again.
- Resume across separate runs. Paste a previous run or dataset ID to keep pulling a large catalogue over several runs without re saving jobs you already have.
- Built for schedules. Incremental mode classifies every job as NEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED against the last run of the same search, so a recurring schedule returns only what changed.
Use Cases
- Recruiters and talent teams: watch a set of companies' Gupy career pages for new openings by keyword, state, or workplace type.
- Job boards and aggregators: mirror Gupy listings for a state, city, or workplace type into your own catalogue.
- Workforce and HR analytics: run the same search on a schedule with Incremental mode and track how postings and requirements change over time.
- Accessibility focused services: filter for PWD marked listings across many companies at once.
- Automation and agent builders: pipe new listings straight into Notion, Linear, or Airtable through the MCP connector field.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
id | 3050001 |
name | "Analista de Sistemas Pleno" |
jobUrl | "https://sample-company.gupy.io/job/eyJqb2JJZCI6MzA1MDAwMX0=" |
description | "<p>Full HTML job description as published.</p>" |
descriptionPlainText | "Full job description, converted to plain text." |
city | "São Paulo" |
state | "São Paulo" |
stateCode | "SP" |
country | "Brasil" (filled when the job's state is Brazilian, or always with Fetch details on; empty when the listing does not say, since jobs from other Latin American countries are listed too) |
jobType | "vacancy_type_effective" |
workplaceType | "hybrid" |
isRemoteWork | false |
publishedAt | "2026-08-01T12:00:00.000Z" |
applicationDeadline | "2026-09-15T23:59:59.000Z" |
expireDays | 17 |
careerPageName | "Sample Company" |
careerPageDisplayName | "Sample Company" (same value as careerPageName) |
careerPageUrl | "https://sample-company.gupy.io" |
hasFriendlyBadge | true |
badgeIsPWD | false |
skills | ["Comunicação", "Excel"] |
detailFetched | true (only when Fetch details was on, or the job came from a direct job link) |
source | the complete source record as returned by the API |
scrapedAt | "2026-09-29T09:00:00.000Z" |
Every record also carries a long list of schema compatibility fields shared with other job board actors, such as prerequisites, benefits, companyLinkedin, and jobImage. Gupy's public data does not populate these, so they are always null on every record.
How to Use
- Pick a mode:
search(use the filters below) orurl(paste portal search links or direct Gupy job links). - In search mode, set the keyword, state, city, workplace type, job type, company, PWD, and feedback badge filters you need, and turn on Fetch details if you want the full per job record.
- Set Max items (and Max pages or Page size if needed) to control run size and cost, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Search by keyword, state, and workplace type:
{"searchTerm": "developer","state": "São Paulo","workplaceTypes": ["remote"],"sortBy": "newest","maxItems": 20}
One company's career page, with full detail per job:
{"companies": ["Sample Company"],"fetchDetails": true,"maxItems": 50}
Paste links (portal search and a direct job page):
{"mode": "url","urls": ["https://portal.gupy.io/job-search/term=developer&state=Bahia","https://sample-company.gupy.io/job/eyJqb2JJZCI6MzA1MDAwMX0="],"maxItems": 10}
Recurring monitoring of the same search, including jobs that disappear:
{"searchTerm": "developer","incrementalMode": true,"emitExpired": true,"maxItems": 0}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/gupy-io-scraper").call(run_input={"searchTerm": "developer", "state": "São Paulo"})for job in client.dataset(run["defaultDatasetId"]).iterate_items():print(job["name"], job["careerPageDisplayName"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/gupy-io-scraper').call({ searchTerm: 'developer', state: 'São Paulo' });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How Max items and Max pages shape a run
Max items is a soft cap on saved rows (default 20, 0 means unlimited). Max pages defaults to 0, meaning the walk covers every result page; a positive number stops the walk after that many API pages, whichever limit is reached first. Gupy's own reported result total is not a reliable stop signal once a search has many matches, so the walk instead relies on a page coming back empty, coming back shorter than requested, or containing no job the run has not already collected (after earlier pages of that same search did add new jobs). Fewer rows than Max items may still come back when the chosen source and filters simply match fewer live jobs.
A known limitation of that last stop rule. "Already collected" is judged against everything this run holds, not just the current search: jobs from earlier links in the same run, and jobs reloaded by Resume. So a search can stop before its real last page, with no error, in two cases:
- Several overlapping search links in one run (URL mode). If a later link finds some new jobs, then hits a full page of jobs an earlier link already returned, that later link stops there and its deeper pages are skipped. Search mode builds a single search and is not affected by this case. Run overlapping links as separate runs.
- Resume after new jobs were posted. When
resumeFromRunId(or an automatic restart after a platform migration) replays a search whose first pages now hold a few newly posted jobs ahead of the ones already collected, the next page of already collected jobs ends the walk, so jobs beyond the earlier stopping point are not reached. If a resumed run returns far fewer jobs than expected, run the search again without Resume instead.
Resume and recurring updates
- Resume (
resumeFromRunId) continues a catalogue walk from an earlier run that finished and saved its jobs, for example one stopped by Max items: paste its run or dataset ID and jobs already collected there (matched by job ID) are skipped, so this run only appends new ones. Jobs are written to the dataset only when a run finishes, so a run that was aborted or failed partway has nothing to resume from; resurrect that run instead, and it reloads its own saved progress. An unreadable run or dataset ID fails the run immediately, before any scraping starts. - Incremental mode (
incrementalMode) is for scheduling this same search again and again. Each run classifies every job against the last run's state for that search (kept automatically, or under your ownstateKey) and adds achangeType:NEW(not seen before),UPDATED(a field changed, listed inchangedFields),UNCHANGED(nothing changed, suppressed unlessemitUnchangedis on),REAPPEARED(was marked EXPIRED, found again), orEXPIRED(tracked before, not found in a run that fully scanned this search, only produced whenemitExpiredis on). Every job also carriesfirstSeenAtandlastSeenAt.EXPIREDis only ever computed when the run reaches the natural end of the walk; a run capped by Max items or Max pages, or one started withresumeFromRunId, skips it for that run and keeps the previous state as is. One exception to watch for: an early stop caused by overlapping search links (described above) still counts as reaching the natural end, so withemitExpiredon, a URL mode run with several overlapping links can mark still live jobsEXPIRED. Keep each tracked search to one link per run if you rely onEXPIRED. TurningincrementalModeon together withresumeFromRunIdfails the run if that search already has saved incremental state; remove one of the two, or set a differentstateKey. With Incremental mode off, output is exactly as before.
Send results into your apps (MCP connectors)
Optionally pipe the scraped jobs into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human readable summary of each job, not the full JSON. Each job becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where job pages should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (filters below) or url (portal search links and direct Gupy job links). |
searchTerm | string | (empty) | Job title, skill, or keyword. Leave empty to scrape all jobs matching the other filters. |
state | string | (empty) | Brazilian state filter. Leave empty for all states. |
cities | array | [] | Exact Gupy city names. Leave empty for all cities. |
workplaceTypes | array | [] | Remote, hybrid, or on site jobs. Leave empty for all workplace types. |
jobTypes | array | [] | Gupy vacancy type values (full time, apprentice, internship, trainee, and more). Leave empty for all job types. |
companies | array | [] | Exact Gupy career page names. Leave empty for all companies. |
pwdOnly | boolean | false | Return only jobs marked for people with disabilities. |
friendlyBadgeOnly | boolean | false | Return only jobs from companies with Gupy's feedback badge. |
urls | array | [] | Portal search URLs or direct Gupy job URLs. Used only when Mode is url. |
fetchDetails | boolean | false | Fetch the full per job record before saving each result (search mode and portal search URLs only; direct job URLs are always fetched in full and always carry the detail enrichment charge). Adds the detail enrichment charge per enriched job actually saved. |
sortBy | string | newest | Sort saved jobs after collection: newest, oldest, or company (A to Z). |
maxItems | integer | 20 | Maximum matching rows to save. 0 means unlimited. Fewer rows may come back when the source and filters match fewer live jobs. |
maxPages | integer | 0 | Leave at 0 to walk every result page. A positive number stops the walk after that many API pages. |
pageSize | integer | 100 | API page size, from 1 to 100. |
resumeFromRunId | string | (none) | A previous run ID or dataset ID to continue a full catalogue walk. Jobs already collected there are skipped. |
incrementalMode | boolean | false | Track this search's results between scheduled runs and classify each job as NEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED. |
stateKey | string | (none) | Name an incremental mode baseline explicitly. Leave empty to derive one automatically from the search filters. |
emitUnchanged | boolean | false | Incremental mode only. Also return (and bill) jobs unchanged since the last tracked run. |
emitExpired | boolean | false | Incremental mode only. Also return (and bill) jobs tracked before but no longer found, after a run that fully scans the search. |
mcpConnectors | array | (none) | Optionally send the scraped jobs into the apps you already use, via MCP connectors. Leave empty to skip. |
notionParentPageUrl | string | (none) | Notion connector only: page under which job pages are created. |
maxNotifyListings | integer | 50 | Cap on jobs written to each connector per run. Does not affect the dataset. |
proxyConfiguration | object | Apify Proxy | Connection settings. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"id": 3050001,"code": "9001-3050001","name": "Analista de Sistemas Pleno","jobUrl": "https://sample-company.gupy.io/job/eyJqb2JJZCI6MzA1MDAwMX0=","description": "<p>Full HTML job description as published.</p>","descriptionPlainText": "Full job description, converted to plain text.","prerequisites": null,"city": "São Paulo","state": "São Paulo","stateCode": "SP","country": "Brasil","countryCode": "BR","jobType": "vacancy_type_effective","workplaceType": "hybrid","isRemoteWork": false,"publishedAt": "2026-08-01T12:00:00.000Z","applicationDeadline": "2026-09-15T23:59:59.000Z","expireDays": 17,"companyId": 9001,"companySubdomain": "sample-company","careerPageName": "Sample Company","careerPageDisplayName": "Sample Company","careerPageUrl": "https://sample-company.gupy.io","hasFriendlyBadge": true,"badgeIsPWD": false,"skills": ["Comunicação", "Excel"],"sourceQuery": { "searchTerm": "developer", "state": "São Paulo", "cities": [], "workplaceTypes": [], "jobTypes": [], "companies": [], "pwdOnly": false, "friendlyBadgeOnly": false },"detailFetched": true,"source": {},"scrapedAt": "2026-09-29T09:00:00.000Z"}
Plan Requirement
The default connection setting (Apify Proxy) works out of the box and is recommended for reliability. If you switch it off and see repeated source errors, turn it back on under Connection.
FAQ
How much does it cost?
You pay per job saved, plus a one time actor start fee, with the detail enrichment charge added for each job whose full record was fetched and that actually reaches the dataset: every job when Fetch details is on, and always for jobs from direct Gupy job links. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape Gupy.io?
This actor collects only publicly available job listings. You are responsible for how you use it: follow Gupy.io's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.
Can I get only new or changed jobs on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only NEW, UPDATED, and REAPPEARED jobs for that search, and unchanged ones are not billed unless you turn on Emit unchanged.
Why did my run return fewer jobs than I expected?
Max items and Max pages both cap a run, and Gupy's own reported result total is not a reliable signal once a search has many matches. Raise Max items, raise or clear Max pages, or set Max pages to 0, to walk the whole result set. Two cases can also end a search early without an error: several overlapping search links in one URL mode run, and a Resume run after new jobs were posted. Both are described under "How Max items and Max pages shape a run" above.
Why did my run fail instead of returning an empty dataset?
Two situations fail the run outright rather than returning an empty dataset: pasting a Resume from a previous run ID that this Apify account cannot read (checked before any scraping starts), and turning on Incremental mode together with Resume from a previous run when that search already has saved incremental state. Fix the ID, or remove one of the two settings, and run it again.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear, or Airtable.
🔗 Want more jobs data?
Pair this actor with these related scrapers from the same team:
| 💼 RemoteOK Jobs Scraper Scrape RemoteOK jobs by keyword or job URL. Extract title, company, location, remote... | 💼 Monster Jobs Scraper Scrape Monster.com job listings from search and direct job URLs. Extract full... |
| 💼 Jora Jobs Scraper Scrape Jora.com job listings across supported countries by keyword, filters, or URL... | 💼 Dice.com Scraper Scrape tech job listings from Dice.com by keyword, filters, or URL. Extract job titles... |
| 💼 Jobs.cz Scrape Czech job listings from Jobs.cz. Search builder (keyword, location, field, salary... | 💼 We Work Remotely Scraper Extract current remote job listings from weworkremotely.com. Use keyword search or WWR... |
💬 Support & custom scrapers
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com or message Telegram @abotapi.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.