Docs

Everything for using the product day to day, and everything for building against the API - one live index, updated continuously from real employer career pages.

Getting started

The web app needs nothing beyond signing in. The API needs a Pro or Ultimate plan and a key.

  1. Sign in at jobs.guaqai.me and complete onboarding - your work authorisation, categories and location answers drive matching and eligibility filtering automatically; nothing else on this page is required to use the feed.
  2. For API access: upgrade to Pro or Ultimate from your Profile screen.
  3. Open Profile → API access and click Create key. The key (guaq_sk_...) is shown exactly once - copy it immediately. Losing it means revoking and issuing a new one; the plaintext is never stored, so nobody, including us, can show it to you again.
  4. Send it as Authorization: Bearer guaq_sk_... on every request.
curl -H "Authorization: Bearer guaq_sk_..." \
  "https://jobs.guaqai.me/v1/jobs?domain=tech&location_scope=india&limit=10"

How matching works

The feed you see in the app is scored per-person against your résumé and profile answers. The API is not - it is a plain filtered read of the same underlying rows, with no similarity score, because a script or a notebook has no résumé to score against.

In the app, seniority and category preferences carry real weight in ranking - much more than a raw keyword match - because they are things you stated explicitly, and a title alone (with no description text behind most listings) is a thin, noisy signal on its own. A stated fact always outranks a deduced one.

Remote & visa eligibility

"Remote" is not one thing, and the feed does not treat it as one. Two independent questions decide whether a role is actually reachable for you:

  • Where the work happens - on-site, hybrid, or remote (work_mode / work_arrangement).
  • What makes you allowed to take it - one of three routes, all of which can apply at once and are chosen as checkboxes in the app, never a single either/or toggle:
    • Authorized - countries you are already permitted to work in (your onboarding answer). A stated refusal to hire outside your country is respected even on a remote posting: "US Remote" still requires US work authorisation.
    • Sponsored - abroad, if the employer sponsors a visa. Ranked by how explicitly the posting says so, never by a guess dressed as a fact: a posting that states sponsorship always outranks one merely judged likely, and a stated refusal is always excluded outright.
    • Borderless - remote for a foreign employer with no visa involved at all (an employer-of-record or contractor arrangement). Deliberately narrow: this requires the posting to actually say it hires globally, never just "remote" plus a contract role - a great many ordinary remote-but-domestic contract postings would otherwise be miscategorised as visa-free.
Via the API, use visa=stated for postings that explicitly say they sponsor, visa=likely to widen to ones judged probable from context (an inferred signal, never presented as a fact), or visa=refused for postings that explicitly rule it out. Omit it and every row is returned regardless of what it says about visas.

Posted vs. seen

Two different clocks, both preserved rather than collapsed into one.

posted_at is the employer's own stated date, when the posting states one - null when it does not, never defaulted to "today". scraped_at is when this platform first found the row; last_seen_at is the most recent time it was re-confirmed still live on the employer's board. A posting can be freshly re-confirmed (last_seen_at just now) while having been originally posted weeks ago (posted_at) - that is normal, and the two should not be read as contradicting each other.

Telegram alerts

Connect a Telegram chat from Profile → Manage alerts to get new matches pushed to you instead of checking the feed. Provide your chat ID (message @userinfobot to get it, after pressing Start on our bot first - Telegram refuses to message a chat that has never started a conversation with the bot), send a test, and toggle alerts on. Disabling alerts keeps your chat ID on file so turning them back on needs no re-entry.


Agents

Choose your setup: Remote MCP (Server-Sent Events & Streamable HTTP), Public OAuth 2.0 Code Flow, Universal Agent Skill, Claude Code Plugin Marketplace, Google Antigravity, Cursor, Windsurf, Cline/Roo, or CLI.

Why Bundled Connectors (Skills + CLI) Beat Raw MCP:
• Zero Parameter Hallucination: Raw MCP only exposes parameter names; LLMs guess invalid values like visa=yes (must be stated, likely, or refused) or location_scope=in (must be india). The bundled Skill teaches the exact filter taxonomy.
• Zero Permission Hangs: Project-scoped (.mcp.json) configurations require interactive approval prompts that silently stall if opened from subfolders. User-scoped connectors and Skills run immediately.
• Execution Fallback: When JSON-RPC bridges disconnect or time out, agents with terminal tools execute npx -y employed-mcp CLI seamlessly without failing the user request.
curl -o guaq_client.py https://jobs.guaqai.me/v1/client
curl -o guaq_cli.py    https://jobs.guaqai.me/v1/cli
# both saved beside each other - the CLI imports the shared client
export GUAQ_API_KEY=guaq_sk_...
python guaq_cli.py jobs --domain tech --location-scope india --limit 10

1. Remote MCP Server: SSE & Streamable HTTP

Connect directly over the web without installing Python or local node dependencies. Compatible with Claude Desktop, Claude for Work, and remote agent hosts:

# Server-Sent Events (SSE) Transport:
URL:    https://jobs.guaqai.me/mcp/sse
Header: Authorization: Bearer guaq_sk_... (or OAuth Bearer token)

# Streamable HTTP (Stateless JSON-RPC):
POST:   https://jobs.guaqai.me/mcp

In claude_desktop_config.json or any remote MCP client config:

{
  "mcpServers": {
    "employed-remote": {
      "url": "https://jobs.guaqai.me/mcp/sse",
      "transport": "sse",
      "headers": { "Authorization": "Bearer guaq_sk_..." }
    }
  }
}

2. Public OAuth 2.0 Authorization Code Flow

For applications, Claude Connectors, or agent platforms requiring standard OAuth 2.0 authentication alongside direct API keys:

Authorization URL: https://jobs.guaqai.me/oauth/authorize
Token URL:         https://jobs.guaqai.me/oauth/token
Scopes:            read:jobs

# Social Profile & Connected Accounts (via Clerk getUserOauthAccessToken):
GET /api/user/social-profile   # Returns verified GitHub, Google, or LinkedIn profile data

3. Universal Agent Skills (Claude Code, Codex, Cursor, Antigravity)

Install the universal Agent Skill teaching any LLM the exact ATS query taxonomy:

# Universal Skills CLI (Claude Code, Cursor, Windsurf, etc.)
npx skills add buddywhitman/resume-cv --skill employed-jobs

# OpenAI Codex
npx agent-skills-cli add buddywhitman/resume-cv --agent codex --skill employed-jobs

4. Claude Code Plugin Marketplace (Recommended)

Install both the MCP tools and Agent Skill in one step via Claude Code's plugin manager:

# Add our official marketplace, then install the employed plugin:
/plugin marketplace add buddywhitman/resume-cv
/plugin install employed@employed-marketplace

# Or run globally via user scope (zero approval prompts everywhere):
claude mcp add --scope user employed --env GUAQ_API_KEY=guaq_sk_... -- npx -y employed-mcp
# (Windows PowerShell: quote the "--" separator: claude mcp add --scope user employed ... "--" npx -y employed-mcp)

5. Google Antigravity (AGY) Plugin

Antigravity automatically discovers the bundled plugin in your workspace under .agents/plugins/employed/. To install globally across all workspaces:

# Symlink or copy to Antigravity global plugins:
# macOS/Linux:  ~/.gemini/config/plugins/employed
# Windows:      %USERPROFILE%\.gemini\config\plugins\employed

6. Cursor Rules & MCP

Cursor automatically reads our bundled rule in .cursor/rules/employed.mdc. To enable native MCP tool calling, add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "employed": {
      "command": "npx",
      "args": ["-y", "employed-mcp"],
      "env": { "GUAQ_API_KEY": "guaq_sk_..." }
    }
  }
}

7. Windsurf Cascade Rules & MCP

Windsurf reads .windsurfrules from the workspace. Add MCP server to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "employed": {
      "command": "npx",
      "args": ["-y", "employed-mcp"],
      "env": { "GUAQ_API_KEY": "guaq_sk_..." }
    }
  }
}

8. Cline & Roo Code (VS Code Extensions)

Add to cline_mcp_settings.json or roo_code_mcp_settings.json:

{
  "mcpServers": {
    "employed": {
      "command": "npx",
      "args": ["-y", "employed-mcp"],
      "env": { "GUAQ_API_KEY": "guaq_sk_..." },
      "disabled": false,
      "autoApprove": ["api_meta", "search_jobs", "count_jobs", "get_job", "list_companies", "company_profile", "market_signal"]
    }
  }
}

9. ChatGPT & Custom GPTs (OpenAPI 3.1 Actions)

Import our public OpenAPI 3.1 specification directly into ChatGPT Builder Actions:

Schema URL:  https://jobs.guaqai.me/openapi.json
Auth Type:   API Key -> Bearer (Header: Authorization: Bearer guaq_sk_...)
Privacy URL: https://jobs.guaqai.me/privacy

10. Standalone CLI & Smithery / Multi-Client Installer

Query live postings directly from your shell or configure any client interactively:

# Smithery automated installer:
npx -y @smithery/cli mcp add employed-mcp

# Interactive multi-client installer:
npx -y mcp-add employed-mcp

# Standalone CLI execution:
export GUAQ_API_KEY=guaq_sk_...
npx -y employed-mcp jobs --domain tech --location-scope india --limit 10
npx -y employed-mcp count --company "Jane Street" --role-type new_grad
npx -y employed-mcp company "Stripe"
npx -y employed-mcp signals gcc

11. Direct Python (Stdlib-Only, No Node)

On locked-down environments without Node or npm registry access, download the Python files directly:

mkdir -p ~/guaq && cd ~/guaq
curl -o guaq_client.py https://jobs.guaqai.me/v1/client
curl -o guaq_mcp.py    https://jobs.guaqai.me/v1/mcp
claude mcp add --scope user employed --env GUAQ_API_KEY=guaq_sk_... -- python3 /Users/you/guaq/guaq_mcp.py
# Windows: "command": "python", "args": ["C:/Users/you/guaq/guaq_mcp.py"]
# Either way: paths must be absolute - MCP hosts do not start in your folder.
# Restart the host after editing its config.

Marketplaces & Browse UIs

How Employed is discovered and listed across agent directories, plugin marketplaces, and GUI stores.

1. Claude Connectors & Claude Code Marketplace

Claude.ai Connectors Browse UI: Anthropic curates certified connectors in Claude for Work/Enterprise. Our remote hosted SSE endpoint (https://jobs.guaqai.me/mcp/sse), Public OAuth 2.0 flow (/oauth/authorize & /oauth/token), and published Privacy Policy/Terms satisfy Anthropic developer connector partnership requirements.

Claude Code Default Marketplace: By default, Claude Code queries the official Anthropic plugin registry. Anyone can discover and install our connector immediately by adding the marketplace (/plugin marketplace add buddywhitman/resume-cv). To appear in the default un-namespaced browse list, submit a PR to the official Claude Code plugin index repo referencing buddywhitman/resume-cv.

Smithery & Community Registries: Employed is configured with smithery.yaml at repository root and npm package, indexable via Smithery (smithery.ai), Glama (glama.ai/mcp), PulseMCP (pulsemcp.com), and AgentSkills (agentskills.io).

2. Google Antigravity (AGY) Customizations

Local & Project UI: Antigravity automatically detects bundled plugins in .agents/plugins/employed/.

Global Settings UI: Copying or symlinking to ~/.gemini/config/plugins/employed makes Employed show up globally across all Antigravity workspaces and plugin management UIs.

Ecosystem Registry: Contributed via the Antigravity community plugin index.

3. ChatGPT / OpenAI Codex & GPT Store

OpenAI deprecated legacy plugins in favor of Custom GPTs with Actions in the GPT Store. Anyone can publish a verified Custom GPT using Employed in 4 steps:

  1. Create GPT: Open ChatGPT → Explore GPTs → Create. Title: "Employed - Live ATS Job Search & Radar".
  2. Import Action: Under Actions, choose "Import from URL" and input https://jobs.guaqai.me/openapi.json. Set Authentication to Bearer or OAuth 2.0.
  3. Verify Domain: Under Builder Profile, verify jobs.guaqai.me via DNS TXT record (openai-domain-verification=...).
  4. Publish to GPT Store: Add Privacy Policy URL (https://jobs.guaqai.me/privacy) and publish to "Public". The GPT will appear in search results across ChatGPT.

Example Prompts

Because Employed indexes live positions directly from 17+ ATS platforms with deep deterministic metadata (days open, posting flow, tri-state visa verification, function mix, GCC intensity), prompts can uncover insights impossible on standard aggregators.

1. The "Acute Hiring Pain" Cold-Pitch Arbitrage

Standard job seekers apply to the freshest postings alongside thousands of applicants. This prompt targets roles where the employer has acute hiring bottlenecks and is flexible on requirements.

Inspect <Employer>'s hiring profile using company <Employer>. Find all engineering roles where days_open exceeds 45 days. Identify the specific tech stack and requirements for those prolonged vacancies, and draft a high-leverage outreach pitch directly addressing that hiring bottleneck.

2. The "Visa Truth-Teller" (Bypassing Sponsorship Ghosting)

Most job aggregators show generic "equal opportunity" disclaimers, causing visa-requiring applicants to waste hours applying to employers that silently auto-reject at ATS intake.

Find early-career backend engineering roles in the US where visa is strictly stated (contractually stated sponsorship, not inferred), with yoe_min <= 2. Exclude any listing where work_mode is remote unless it explicitly supports borderless hiring. Give me the direct apply ATS URLs.

3. Stealth Corporate Expansion & Offshore GCC Radar

ATS job creation is the earliest public leading indicator of corporate strategy, often appearing months before quarterly earnings calls.

Run signals gcc and identify multinational enterprises with the highest hiring acceleration in Indian Global Capability Centers over the past 8 weeks. For the top 3, check company <Name> to analyze their local function_mix (core engineering vs operations). Which legacy enterprises are quietly migrating core R&D offshore?

4. The Non-Tech Enterprise Campus Arbitrage

Thousands of students compete for the same Big Tech campus portals. Meanwhile, Fortune 500 industrial and retail giants have massive engineering budgets and far lower applicant density.

Query live campus listings using jobs with --campus true --grad-year 2026 --domain industrial,retail,energy --role-type new_grad. Group them by employer and highlight which ones require zero prior years of experience (yoe_min=0) and state relocation assistance.

5. Startup Runway & Stealth Freeze Detector

Evaluate startup offer stability and private market health by checking real hiring momentum.

Check <StartupName> using company <StartupName>. Analyze their 8-week posting_flow and avg_days_open. Has their rate of new postings dropped to zero while existing roles sit unclosed? Tell me whether the hiring velocity indicates acceleration, steady replacement, or an impending stealth freeze.

6. Tech Stack Migration & Enterprise Rewrite Radar

Discover established enterprises quietly modernizing their architecture to Rust, Go, or Kubernetes for B2B devtool sales, recruiting, or contract bidding.

Query the live index for companies in finance or healthcare with active postings requiring tech=rust or tech=kubernetes. Check their seniority_mix and longest_open_roles. Which established enterprises are undergoing major architectural rewrites, and which specific teams are leading the initiative?

API overview

One plain, filtered, cursor-paginated read of the live jobs index. No résumé scoring, no 1,500-row scoring window - every row your filters match is reachable, in a stable order, resumable with a cursor.

Absent filters never exclude. Every parameter below is optional, and omitting one always widens the result, never narrows it by a default you did not ask for. The one place this needs care is visa - most postings say nothing about sponsorship at all, and that silence is not a "no".

Base URL: https://jobs.guaqai.me/v1. Machine-readable index (no key required) at /v1.

Official client libraries & specifications: Python Client (/v1/client) · Python CLI (/v1/cli) · Python MCP Server (/v1/mcp) · OpenAPI 3.1 (/openapi.json) · Markdown Docs (/docs.md).

Authentication

Any one of these three, checked in this order:

MethodExample
Authorization headerAuthorization: Bearer guaq_sk_...
Custom headerX-API-Key: guaq_sk_...
Query parameter?api_key=guaq_sk_...

The header form is recommended - a URL with a key in it ends up in shell history and server logs. The query form exists because it is the only one that works pasted straight into a browser tab.

Keys are shown once, at creation, and only the SHA-256 hash is ever stored. If you lose one, revoke it from Profile and issue a new one - there is no way for support to recover a lost plaintext key, by design.

Plans & quota

The API is a paid surface - there is no free-tier API access. Every response carries X-RateLimit-Used and X-RateLimit-Limit headers so a script can back off before being refused rather than after.

Pro

500 calls/day
  • Max 100 rows per page
  • No bulk export
  • No market signals

Ultimate

2,000 calls/day
  • Max 1,000 rows per page
  • Bulk export (jsonl/csv/parquet)
  • No market signals

Organisation seat

per tier
  • Max 5,000 rows per page
  • Bulk export included
  • Market signals included

Quota is counted server-side, per key, per UTC day - not per account and not per IP, so one leaked key can be revoked without touching every other key you hold, and one address behind a shared NAT is never throttled by someone else's usage.

Filter reference

Every filter below applies to /v1/jobs, /v1/jobs/count, /v1/companies, and /v1/export - the same WHERE the row count, the row list, and the bulk export all agree on. List-valued filters accept either repeated params (?domain=tech&domain=finance) or one comma-separated value (?domain=tech,finance) - both are equivalent.

ParamTypeRequiredBehaviour
qstringoptional Substring match against title OR company (case-insensitive).
companystring listoptional Exact match (case-insensitive), any of the given names.
target_idstring listoptional Exact match on the internal source-board id.
domainstring listoptional industry_domain - see /v1/meta for the full vocabulary.
categorystring listoptional Taxonomy path (e.g. engineering/software). A parent path matches every child path AND the parent's own uncategorised rows - dropping the parent's own rows is how a category filter quietly loses real jobs.
role_typestring listoptional internship, new_grad, junior, mid, senior, lead_exec, founding_engineer.
employment_typestring listoptional full_time, part_time, internship, contract, and the others in /v1/meta.
senioritystring listoptional The employer's own stated seniority word (e.g. "vp", "principal"), when present - different from the normalised role_type ladder.
leadershipstring listoptional ic or manager. Orthogonal to seniority - a Staff Engineer and an Engineering Manager sit at the same rung and are different jobs.
org_typestring listoptional startup, midsize, mnc, unspecified.
educationstring listoptional education_req - bachelors, masters, phd, unspecified, etc.
location_scopestring listoptional Lowercase market bucket: india, us, uk, sg, or a lowercase ISO code for anywhere else (de, ca, jp…); also remote / multiple / unspecified. India is india (not in), the UK is uk (not gb).
work_modestring listoptional on_site, hybrid, remote, unspecified - maps to the work_arrangement field in the response.
citystring listoptional Substring match against the free-text location, including known spelling variants (e.g. Bangalore/Bengaluru) - never exact-equality, since the source text is scraped and unnormalised.
techstring listoptional Overlap against tech_stack (case-insensitive).
visaenumoptional stated (posting explicitly says it sponsors) · likely (stated OR judged probable - an inferred signal) · refused (explicitly rules it out). Omitted, every row matches regardless of what it says about sponsorship.
campusbooleanoptional true/1/yes or false/0/no. Restricts to (or excludes) postings sourced from a student/early-careers board.
yoe_minintegeroptional Keeps roles that ask for at least this many years (job.yoe_min ≥ value) - i.e. this raises the floor and excludes junior roles below it.
yoe_maxintegeroptional Keeps roles that ask for at most this many years (job.yoe_min ≤ value) - i.e. this caps how senior a role's stated requirement may be.
grad_yearintegeroptional Matches a role whose primary cohort year equals this, or whose full list of named cohorts includes it (some postings name more than one, e.g. "2026/2027 batch").
seen_afterISO dateoptional last_seen_at ≥ this date - postings re-confirmed live on/after this date.
scraped_afterISO dateoptional scraped_at ≥ this date - postings first discovered on/after this date. Use this, not posted_at (which reflects the employer's own possibly-older date), when what you want is "new to the index since I last checked".
activebooleanoptional, default true false includes roles that have since been retired/closed as well as live ones.
limitintegeroptional, default 50 Rows per page. Capped at your plan's max_page_size - see Plans. Above the cap, the endpoint returns 403 rather than silently truncating.
cursorintegeroptional The next_cursor from a previous page. Pages by descending id, which stays correct under concurrent inserts - a new row gets a higher id and simply is not in a page you already fetched.

Endpoints

GET/v1/jobs

The filtered, paginated list. Accepts every filter in the reference above plus limit and cursor.

{
  "data": [ { "id": 8123456, "company": "Acme Corp", "title": "Backend Engineer",
              "url": "https://...", "location": "Bengaluru, India",
              "posted_at": "2026-09-10", "scraped_at": "2026-09-11T03:12:00Z",
              "last_seen_at": "2026-09-13T02:30:00Z", "is_active": true,
              "industry_domain": "tech", "category_path": "engineering/software/backend",
              "role_type": "mid", "seniority_label": null, "leadership": "ic",
              "employment_type": "full_time", "yoe_min": 3, "grad_year": null,
              "education_req": "bachelors", "clearance_req": "none",
              "work_arrangement": "hybrid", "location_scope": "india",
              "visa_supported": null, "visa_likelihood": 0.15, "visa_basis": "country_prior",
              "relocation_supported": false, "tech_stack": ["python", "postgresql"],
              "org_type": "startup", "is_campus": false, "target_id": "acme-corp",
              "inferred_signals": ["visa"] } ],
  "next_cursor": 8123455,
  "has_more": true
}
GET/v1/jobs/count

Same filters as /v1/jobs, no pagination params. Kept as a separate call because it is the expensive half of a page, and most callers paging through a result do not want to pay for a full count on every page.

{ "count": 4821 }
GET/v1/jobs/{id}

One posting by its integer id. Same field shape as one item of /v1/jobs's data array. 404 if the id does not exist.

GET/v1/companies

Employers matching the same filters, grouped, with their live role count - the list a caller needs to know what a subsequent company= filter will actually match. Accepts limit (default 200, max 5,000) plus the standard filters.

{ "data": [ { "company": "Acme Corp", "open_roles": 42,
    "last_seen": "2026-09-13T02:30:00Z", "geographies": 6 } ] }
GET/v1/companies/{name} any paid plan

One employer's hiring profile, computed live from their current open postings. URL-encode the company name.

{
  "company": "Acme Corp", "open_roles": 42, "distinct_locations": 6,
  "avg_days_open": 18.4,
  "seniority_mix": { "mid": 20, "senior": 12, "new_grad": 10 },
  "function_mix": { "engineering": 25, "sales": 8, "operations": 9 },
  "top_cities": { "bengaluru": 15, "remote": 9 },
  "tech_stack": { "python": 14, "kubernetes": 9 },
  "longest_open_roles": [ { "title": "Staff SRE", "location": "Remote", "days_open": 61 } ],
  "posting_flow": {
    "company": "Acme Corp",
    "series": [ { "week": "2026-08-24", "posted": 6 } ],
    "window_days": 56, "survivorship_safe": true,
    "caveat": "Counts roles by the employer's own posted_at. Only postings still live now are counted, so older weeks undercount by however many of that week's roles have since closed."
  }
}

All counts are over currently-live postings only - this is a snapshot, not a historical archive of every role ever posted.

GET/v1/export Ultimate / org

Bulk pull of the same filters, streamed - not assembled in memory, so a 300k-row export does not require buffering the whole result set. Add format=jsonl|csv|parquet (default jsonl). Parquet needs pyarrow on the server side; if unavailable the endpoint returns 503 with a message to use jsonl/csv instead, both of which pandas and polars read directly.

curl -H "Authorization: Bearer guaq_sk_..." \
  "https://jobs.guaqai.me/v1/export?domain=tech&format=parquet" -o jobs.parquet
GET/v1/signals/{name} Organisation seat only

Market-intelligence views over the live index, sold per organisation seat rather than as a consumer add-on. name is one of:

NameParamsWhat it returns
overviewnoneMarket-wide summary plus scrape-panel health.
technologieslimitTechnology adoption ranking across live postings.
vendorscategoryATS/vendor market share within a category; categories listed in the response.
flowcompany, weeksPosting velocity over time, optionally scoped to one company.
indianoneIndia-specific hiring overview.
gcclimitGlobal-capability-centre hiring intensity by employer.
quantcityQuant/finance talent market signals.
it_servicesnoneHeadcount-proxy signal for IT-services firms.
semisnoneSemiconductor hiring-cycle signal.
basketsnonePre-defined NSE-listed sector baskets.
sectortickers (required), labelA custom index built from the given tickers.
function_mixticker (required)How one company's hiring mix by function has shifted.

An individual Pro/Ultimate key gets 403 upgrade_required here - signals ship with an organisation seat. Contact hello@guaqai.me.

GET/v1/meta

Your own plan, quota, and the exact vocabularies the filters above accept - the authoritative list, since these are extended over time.

{
  "tier": "ultimate", "scope": "user",
  "entitlements": { "api_calls_per_day": 2000, "max_page_size": 1000,
                    "bulk_export": true, "signals": false },
  "calls_today": 42, "quota": 2000,
  "job_fields": [ "id", "company", "title", "..." ],
  "domains": [ "tech", "finance", "..." ],
  "role_types": [ "internship", "new_grad", "junior", "mid", "senior", "lead_exec", "founding_engineer" ],
  "employment_types": [ "full_time", "..." ],
  "cities": [ "bangalore", "..." ]
}

Job field reference

Every field /v1/jobs, /v1/jobs/{id}, and /v1/export return. Adding a field here is additive and safe to depend on; a field is never silently renamed or removed once shipped.

FieldTypeMeaning
idintegerStable row id. Use as the pagination cursor.
companystringEmployer name.
titlestringPosting title, cleaned of location/date/salary text some sources mash in.
urlstringThe apply link.
locationstring or nullFree-text, as scraped - not normalised, which is why city= filters by substring rather than equality.
posted_atstring (YYYY-MM-DD) or nullEmployer-stated date. null means not stated - never defaulted to today.
scraped_attimestampWhen this platform first found the row.
last_seen_attimestampMost recent re-confirmation that the posting is still live.
is_activebooleanFalse once the posting is retired/closed.
industry_domainstringCoarse field, e.g. tech, finance, life_sciences - see /v1/meta.
category_pathstring or nullFiner taxonomy path, e.g. engineering/software/backend.
role_typestringSeniority rung - internship, new_grad, junior, mid, senior, lead_exec, founding_engineer.
seniority_labelstring or nullThe employer's own word (e.g. "vp"), kept alongside the normalised ladder since the two don't always agree.
leadershipstring or nullic or manager; unknown for roles where it doesn't clearly apply (e.g. Product Manager).
employment_typestringfull_time, part_time, internship, contract, and others - see /v1/meta.
yoe_minintegerMinimum years of experience the posting asks for. 0 for internship/new_grad.
grad_yearinteger or nullNamed graduation cohort, when the posting states one.
education_reqstringbachelors, masters, phd, unspecified, etc.
clearance_reqstringA stated security-clearance requirement, or "none".
work_arrangementstring or nullon_site, hybrid, remote, or unspecified.
location_scopestring or nullLowercase market bucket: india, us, uk, sg, or a lowercase ISO code for anywhere else (de, ca, jp…); also remote / multiple / unspecified. India is india (not in), the UK is uk (not gb).
visa_supportedboolean or nullTri-state: true = posting states it sponsors, false = posting states it does not, null = not mentioned. Never a fact fabricated from silence.
visa_likelihoodfloat or null0–1 estimate used only when visa_supported is null - an inference, not a statement.
visa_basisstring or nullWhich signal produced the likelihood estimate.
relocation_supportedbooleanWhether the posting states relocation assistance.
tech_stackstring arrayCanonical technology/skill tokens detected in the posting.
org_typestring or nullstartup, midsize, mnc, or unspecified.
is_campusbooleanSourced from a student/early-careers board rather than the employer's general listing.
target_idstringInternal id of the source board this posting came from - useful for grouping postings by source.
inferred_signalsstring arrayWhich of the above fields were DEDUCED rather than read directly from the posting text (e.g. ["visa","education"]) - a stated fact is always ranked above a deduced one wherever this applies.

Errors

Every error is JSON with an error string. Some carry extra context - upgrade_required and tier when a plan is the blocker, quota/used when it's the daily limit.

StatusMeaning
400Malformed filter value (e.g. a non-integer yoe_min).
401Missing, malformed, unknown, or revoked API key.
403Key is valid but the plan doesn't include this endpoint, or limit exceeds your plan's page-size cap.
404The id/company/signal named doesn't exist.
429Daily quota exhausted. Resets at 00:00 UTC.
503A dependency needed for this request isn't available on this deployment (e.g. Parquet export without pyarrow installed).

Get help

Two ways to reach us, and one way to track what happens after.

  • Sign in and raise a ticket from Profile → Support. You'll see the full reply thread and current status right there - nothing gets lost in an inbox.
  • Email support@guaqai.me directly for anything that doesn't need an account, including sign-in problems.
  • Enterprise / market-intelligence enquiries: hello@guaqai.me.