> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mokaru.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Search Jobs

> Search job listings in the Mokaru database

## Overview

The Search Jobs endpoint lets you programmatically query job listings from the Mokaru database. It is the starting point for most automation workflows - search for relevant positions, then pipe the results into your application tracker or external tools.

**Common use cases:**

* **AI agent job hunting** - connect Claude Desktop, GPT, or any AI agent to search for jobs on your behalf. The agent can evaluate listings against your preferences and automatically create applications for the best matches.
* **n8n and Make workflows** - build automated pipelines that search for new jobs on a schedule, filter by your criteria, and push results to Slack, Notion, or a spreadsheet.
* **Custom job boards** - pull listings into your own interface or internal tool. Combine multiple searches (different roles, locations) into a single view.
* **Market research** - track hiring trends by querying specific job titles or locations over time. Monitor how many positions a company has open or how salary ranges shift.

Each search returns up to 25 results per page. To paginate, pass the `nextCursor` from a response back as `cursor` on the next request (opaque token - do not construct it yourself). The `hasMore` field tells you whether additional pages are available.

Free-tier users receive results from the Mokaru database, which is refreshed daily with popular job titles. Plus users get additional results from external providers (JSearch, Fantastic.jobs), giving broader coverage for niche roles or less common locations.

The response includes an `id` field for each listing. Pass this as `jobListingId` when creating an application to automatically link salary data and publisher information.

<Note>
  **Scope required:** `jobs:search` | **Rate limit:** 30 requests/min
</Note>

## Request

```bash theme={null}
POST /v1/jobs/search
```

### Body Parameters

<ParamField body="query" type="string" required>
  Job search keywords (e.g. "software engineer", "product manager")
</ParamField>

<ParamField body="location" type="string">
  City, state, or country (e.g. "San Francisco", "Remote")
</ParamField>

<ParamField body="country" type="string">
  Two-letter ISO country code (e.g. `DE`, `US`, `GB`) for strict country filtering
</ParamField>

<ParamField body="remote" type="boolean">
  Legacy shortcut for `workArrangement: "remote"`. Prefer `workArrangement(s)`
</ParamField>

<ParamField body="workArrangement" type="string">
  Work model: `remote`, `hybrid`, or `onsite`
</ParamField>

<ParamField body="workArrangements" type="string[]">
  Multi-select work model (OR). Takes precedence over `workArrangement`
</ParamField>

<ParamField body="employmentType" type="string">
  Filter by type: `FULLTIME`, `PARTTIME`, `CONTRACTOR`, `INTERN`
</ParamField>

<ParamField body="employmentTypes" type="string[]">
  Multi-select employment type (OR). Takes precedence over `employmentType`
</ParamField>

<ParamField body="datePosted" type="string">
  Filter by recency: `day`, `3days`, `week`, `month`
</ParamField>

<ParamField body="salaryMin" type="number">
  Minimum annual salary in the job currency. Only matches jobs with disclosed salary
</ParamField>

<ParamField body="salaryRanges" type="string[]">
  Annualised salary bands (OR), open-ended allowed: `"30000-50000"`, `"150000-"`
</ParamField>

<ParamField body="requireSalary" type="boolean">
  Only return jobs that disclose a salary
</ParamField>

<ParamField body="benefits" type="string[]">
  Require these benefits to be present (e.g. `["remote work", "health insurance"]`)
</ParamField>

<ParamField body="includeCompanies" type="string[]">
  Restrict results to these company names (case-insensitive substring match)
</ParamField>

<ParamField body="excludeCompanies" type="string[]">
  Hide listings from these companies (case-insensitive substring match)
</ParamField>

<ParamField body="includeKeywords" type="string[]">
  Require all of these keywords to appear in title or description
</ParamField>

<ParamField body="excludeKeywords" type="string[]">
  Exclude jobs whose title or description contains any of these keywords
</ParamField>

<ParamField body="includeTitles" type="string[]">
  At least one of these substrings must appear in the job title
</ParamField>

<ParamField body="excludeTitles" type="string[]">
  None of these substrings may appear in the job title
</ParamField>

<ParamField body="jobLevels" type="string[]">
  Seniority inferred from the title (OR): `entry`, `junior`, `mid`, `senior`, `lead`
</ParamField>

<ParamField body="sources" type="string[]">
  Restrict to specific ATS providers by exact source key (e.g. `greenhouse`, `ashby`, `workday`)
</ParamField>

<ParamField body="languages" type="string[]">
  Required job languages by English name (OR), e.g. `["English", "German"]`
</ParamField>

<ParamField body="experienceMin" type="number">
  Minimum years of required experience stated by the job
</ParamField>

<ParamField body="experienceMax" type="number">
  Maximum years of required experience stated by the job
</ParamField>

<ParamField body="visaSponsorship" type="boolean">
  Only jobs that explicitly offer visa sponsorship
</ParamField>

<ParamField body="securityClearance" type="boolean">
  Match jobs that explicitly require a security clearance
</ParamField>

<ParamField body="directApplyOnly" type="boolean">
  Only jobs whose apply-link points to the employer's own ATS
</ParamField>

<ParamField body="excludeGhostJobs" type="boolean">
  Hide likely-stale "ghost" jobs (posted 60+ days ago or repeatedly recycled)
</ParamField>

<ParamField body="limit" type="number" default="25">
  Results per page (max 100)
</ParamField>

<ParamField body="cursor" type="string">
  Opaque pagination cursor from the previous response's `nextCursor`. Omit on the first page; pass it back unchanged
</ParamField>

### Example

```bash theme={null}
curl -X POST "https://api.mokaru.ai/v1/jobs/search" \
  -H "Authorization: Bearer mk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "software engineer",
    "location": "San Francisco",
    "remote": true,
    "datePosted": "week"
  }'
```

## Response

<ResponseField name="data" type="array">
  Array of job listings

  <Expandable>
    <ResponseField name="id" type="string">Unique job ID (use for `jobListingId` when creating applications)</ResponseField>
    <ResponseField name="title" type="string">Job title</ResponseField>
    <ResponseField name="company" type="string">Company name</ResponseField>
    <ResponseField name="companyLogo" type="string">Company logo URL</ResponseField>
    <ResponseField name="companyWebsite" type="string">Company website URL</ResponseField>
    <ResponseField name="location" type="string">Job location</ResponseField>
    <ResponseField name="city" type="string">City</ResponseField>
    <ResponseField name="state" type="string">State or province</ResponseField>
    <ResponseField name="country" type="string">Country code</ResponseField>
    <ResponseField name="isRemote" type="boolean">Whether the job is remote</ResponseField>
    <ResponseField name="employmentType" type="string">Employment type</ResponseField>
    <ResponseField name="applyLink" type="string">Direct application URL</ResponseField>
    <ResponseField name="applyIsDirect" type="boolean">Whether the apply link goes directly to the employer</ResponseField>
    <ResponseField name="publisher" type="string">Source publisher (e.g. LinkedIn, Indeed)</ResponseField>
    <ResponseField name="description" type="string">Full job description (HTML)</ResponseField>
    <ResponseField name="highlights" type="object">Qualifications, responsibilities, and other highlights</ResponseField>
    <ResponseField name="benefits" type="array">List of job benefits</ResponseField>
    <ResponseField name="salaryMin" type="number">Minimum salary</ResponseField>
    <ResponseField name="salaryMax" type="number">Maximum salary</ResponseField>
    <ResponseField name="salaryPeriod" type="string">Salary period (yearly, monthly, hourly)</ResponseField>
    <ResponseField name="postedAt" type="string">ISO 8601 posting date the results sort by (newest first). From the employer/ATS when provided, otherwise when Mokaru first saw the job</ResponseField>
    <ResponseField name="firstSeenAt" type="string">ISO 8601 date Mokaru first indexed the listing (useful for spotting recycled/reposted jobs)</ResponseField>
    <ResponseField name="republishCount" type="number">How many times the posting date was bumped forward (recycled-listing signal)</ResponseField>
    <ResponseField name="source" type="string">ATS provider key the job was ingested from (e.g. `greenhouse`, `ashby`, `workday`)</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="count" type="number">Number of jobs returned in this page (same as `data.length`, max 25)</ResponseField>
<ResponseField name="total" type="number">Alias of `count` for shape uniformity - NOT the grand total across all pages</ResponseField>
<ResponseField name="hasMore" type="boolean">Whether more pages are available</ResponseField>
<ResponseField name="nextCursor" type="string">Opaque cursor for the next page. Pass back as `cursor`. `null` when `hasMore` is false</ResponseField>

```json theme={null}
{
  "data": [
    {
      "id": "clx1234...",
      "title": "Senior Software Engineer",
      "company": "Acme Corp",
      "companyLogo": "https://...",
      "companyWebsite": "https://...",
      "location": "San Francisco, CA",
      "city": "San Francisco",
      "state": "CA",
      "country": "US",
      "isRemote": true,
      "employmentType": "Full-time",
      "applyLink": "https://acme.com/careers/123",
      "applyIsDirect": false,
      "publisher": "LinkedIn",
      "description": "<p>We are looking for a Senior Software Engineer...</p>",
      "highlights": { "qualifications": ["..."], "responsibilities": ["..."] },
      "benefits": ["Health insurance", "401k"],
      "salaryMin": 150000,
      "salaryMax": 200000,
      "salaryPeriod": "yearly",
      "postedAt": "2026-03-10T00:00:00.000Z"
    }
  ],
  "total": 142,
  "hasMore": true,
  "page": 1,
  "source": "database"
}
```

<Info>
  **Plus users** get results from external job providers (JSearch, Fantastic.jobs) in addition to the Mokaru database. The database is refreshed daily with the top 35 most popular job titles.
</Info>
