For developers

Joonow jobs API and MCP server

Open jobs from career sites and applicant tracking systems in Brazil, the companies that are hiring and the Joonow Job Market Index, as JSON or right inside your AI assistant. Free and read-only.

  • JSON REST API

    Search with the same filters as the website, plus jobs, companies and the Index, with OpenAPI.

  • MCP server

    Claude, ChatGPT, Copilot and Cursor look up jobs in the conversation.

  • Free, with limits

    Works without a key. A free key raises the limits.

On this page
  1. Start in one minute
  2. Endpoints
  3. Search filters
  4. Pagination
  5. Errors
  6. Keys and limits
  7. MCP server for AI assistants
  8. How to credit Joonow

Start in one minute

Search works without a key or sign-up. Copy and run it in your terminal:

curl "https://www.joonow.com/api/v1/jobs?q=analista%20de%20dados&l=Campinas&work=Remote&limit=5"

The response has the jobs, the total, the next page cursor and how to credit Joonow:

{
  "data": [
    {
      "id": "k3j9x2m4pq",
      "title": "Analista de dados",
      "url": "https://www.joonow.com/pt-br/vaga/analista-de-dados-k3j9x2m4pq",
      "applyUrl": "https://www.joonow.com/go/k3j9x2m4pq",
      "company": { "id": "0f5rb3kg49", "name": "Acme", "url": "https://www.joonow.com/pt-br/empresas/acme-0f5rb3kg49", "logo": null },
      "location": { "city": "Campinas", "region": "SP", "country": "BR" },
      "workModel": "Remote",
      "employmentType": "FullTime",
      "seniority": "Professional",
      "salary": { "min": 6000, "max": 8000, "currency": "BRL", "period": "Month" },
      "language": "pt",
      "postedAt": "2026-10-28T12:00:00Z",
      "native": false
    }
  ],
  "total": 214,
  "totalIsLowerBound": false,
  "nextCursor": "djEuMi4xYzJm...",
  "attribution": { "text": "Vagas via Joonow", "url": "https://www.joonow.com/pt-br/vagas?q=analista%20de%20dados" }
}

Endpoints

All of them are GET and return JSON. Links in the responses are absolute and canonical: use them as they come.

EndpointWhat it returns
GET /api/v1/jobsSearch of open jobs, with filters and cursor pagination.
GET /api/v1/jobs/{id}One job, with the description as text and as clean HTML.
GET /api/v1/companies/{id}A company with open jobs: totals, cities, job titles, published salaries and the first page of jobs.
GET /api/v1/companies/{id}/jobsA company's open jobs, with cursor pagination.
GET /api/v1/market-indexThe latest edition of the Joonow Job Market Index (or the month's preliminary numbers).
GET /api/v1/market-index/{yyyy-MM}One monthly edition of the Index.
GET /api/v1/market-index/editionsThe list of published editions.
GET /api/v1/trends/storieslatest Joonow Trends pieces (data stories, daily brief, Candidate Voice Survey)
GET /api/v1/trends/insights?role=&city=what changed for a role and a city
GET /api/v1/openapi.jsonThe API description in OpenAPI 3.1, to generate clients and test.

Search filters

The same as the website search. Filters with several values accept the key repeated (work=Remote&work=Hybrid) or comma-separated values; any of them matches.

ParameterValues
qKeywords or a short phrase: job title, skill or company (up to 200 characters).
lCity or Brazilian state (UF), for example Campinas or SP. Up to 12.
workRemote, Hybrid, OnSite or Anywhere (remote jobs open to anyone; with country, also remote jobs from abroad open to that country).
typeFullTime, PartTime, Contractor, Temporary, Intern, Volunteer, PerDiem or Other.
levelApprentice, Intern, Entry, Operational, Professional, Management or Executive.
daysPosted in the last N days, from 1 to 365.
salaryMinimum monthly salary in the search currency (currency); only jobs with a published salary in that currency match, no exchange rates.
sortrelevance (default), date (newest) or salary (highest salary).
langLanguage of the jobs: pt, en or es. Without it, all.
limitJobs per page, from 1 to 50 (default 20).
cursorThe nextCursor value from the previous response.
countryCountry of the jobs (ISO 3166-1 alpha-2, Americas only: BR, US, MX, CA, AR...), like the country's section on the website. Without it, all of the Americas.
currencyCurrency of salary and of sort=salary (ISO 4217: BRL, USD, MXN, CAD...). Without it, the country's currency; without country, BRL.

Pagination

Every response has nextCursor. For the next page, repeat the same search with cursor=value. A cursor only works for the same search and the same limit, and null means the last page. As on the website, search goes up to 50 pages: to go further, narrow the filters.

Errors

Errors use the problem+json format (RFC 9457), always with a stable code field and, for a parameter, the param field.

codeStatusWhen it happens
invalid_parameter400A parameter has an invalid value (the param field says which).
invalid_cursor400The cursor is malformed or belongs to another search.
invalid_api_key401The key sent does not exist, was revoked or is malformed.
job_not_found404The job does not exist or is already closed.
company_not_found404The company does not exist or has no open jobs.
edition_not_found404That edition of the Index is not published yet.
rate_limited429Over the per-minute limit. Wait for the Retry-After time.
daily_quota_exceeded429The key is over its daily quota, which resets at midnight UTC.
search_unavailable503Search is down for a moment. Try again after Retry-After.

Keys and limits

Without a key, the API and the MCP server already work, with limits per IP. With a free key, the limits go up and you can follow the usage in your account.

AccessPer minutePer day
No key, API10 per IPno daily quota
No key, MCP30 per IPno daily quota
Free key6010,000

Create the key in your account and send it in the X-Api-Key header (or Authorization: Bearer). It is shown only once; keep it somewhere safe and never publish it. Create my key

curl -H "X-Api-Key: jnk_..." "https://www.joonow.com/api/v1/jobs/k3j9x2m4pq"

Every response has RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset; with a key, also X-Daily-Limit and X-Daily-Remaining. Over the limit, the response is 429 with Retry-After.

MCP server for AI assistants

The Model Context Protocol (MCP) lets AI assistants look up Joonow in the middle of a conversation: "find remote data analyst jobs" becomes a real search, with each job's link. The server is remote, read-only and needs no sign-in.

Address (streamable HTTP):

https://www.joonow.com/mcp

Tools

  • search_jobs: searches jobs by title, country, place, work model, contract, seniority, date and salary.
  • get_job: returns one full job by id or link.
  • get_company: returns a company that is hiring, with numbers and its first jobs.
  • market_index: returns the month's Joonow Job Market Index numbers.
  • market_insights: what changed for a role or a city: the role x-ray, who is hiring and the Joonow Trends stories.
  • latest_stories: the latest Joonow Trends pieces, each with three quotable sentences and the link.

How to connect

Claude Code

claude mcp add --transport http joonow https://www.joonow.com/mcp
claude mcp add --transport http joonow https://www.joonow.com/mcp --header "X-Api-Key: jnk_..."

VS Code (.vscode/mcp.json)

{
  "servers": {
    "joonow": { "type": "http", "url": "https://www.joonow.com/mcp" }
  }
}

Cursor (~/.cursor/mcp.json)

{
  "mcpServers": {
    "joonow": { "url": "https://www.joonow.com/mcp" }
  }
}

Claude: in Settings › Connectors, add a custom connector with the address above.

ChatGPT: in Settings › Apps & Connectors, turn on developer mode and create a connector with the address above.

With a key, the MCP limits are your key's: send the X-Api-Key header, as in the Claude Code example.

How to credit Joonow

When you show the data, show "Jobs via Joonow" with a link next to the jobs and use each job's link (url) and apply link (applyUrl) as the API returns them. Refresh stored jobs within 24 hours. Reselling the data, in whole or in part, is not allowed.

API terms