Search jobs
POST /flan.jobs.v1.JobsService/List
Returns verified jobs matching a free-text query and structured filters.
Results are sorted by the sort parameter (relevance-weighted by default
when q is provided, newest otherwise).
Parameters
All request fields are optional. Send filters under query.filters using
proto3-JSON camelCase field names.
| Field | Type | Default | Description |
| ------------------------------- | ------- | ----------- | --------------------------------------------------------------------------------- |
| query.query | string | — | Free-text query. ≤ 200 characters. |
| query.filters.country | string | — | ISO 3166-1 alpha-2 code (e.g. US, GB, DE). Uppercased. |
| query.filters.city | string | — | City name. Matched against city_names. |
| query.filters.remote | boolean | — | Filter to remote-only (true) or non-remote (false). |
| query.filters.workMode | enum | — | One of remote, hybrid, onsite. |
| query.filters.employmentType | string | — | e.g. full_time, part_time, contract, internship, temporary. |
| query.filters.company | string | — | Match against company name. |
| query.filters.companyId | string | — | Match against the canonical company slug. |
| query.filters.seniority | string | — | e.g. intern, junior, mid, senior, lead, staff, manager, director. |
| query.filters.salaryMin | integer | — | Jobs with salary_max >= salary_min. |
| query.filters.salaryMax | integer | — | Jobs with salary_min <= salary_max. |
| query.filters.discoveredAfter | date | — | RFC3339 or YYYY-MM-DD. Jobs first seen at or after. |
| query.filters.verifiedAfter | date | — | RFC3339 or YYYY-MM-DD. Jobs last verified at or after. |
| query.filters.sort | enum | relevance | One of relevance, newest, recently_verified, salary_desc, company. |
| query.limit | integer | 25 | Page size. 1–100. |
| query.cursor | string | — | Opaque pagination cursor from pagination.nextCursor. |
Example
curl -X POST "https://api.useflan.app/flan.jobs.v1.JobsService/List" \
-H "Content-Type: application/json" \
--data '{"query":{"filters":{"country":"US","workMode":"remote","sort":"recently_verified"},"limit":3}}'
{
"data": [
{
"id": "018f3b21-4b2c-7e3d-9a40-23e8a1f2b3c4",
"slug": "senior-frontend-engineer-acme",
"title": "Senior Frontend Engineer",
"companyName": "Acme",
"companySlug": "acme",
"locationText": "Remote, US",
"remote": true,
"employmentType": "full_time",
"seniority": "senior",
"salary": {
"min": 140000,
"max": 180000,
"currency": "USD",
"period": "year"
},
"snippet": "Build the next generation of our customer dashboard…",
"sourcePlatform": "greenhouse",
"discoveredAt": "2026-06-18T14:20:00Z",
"lastVerifiedAt": "2026-06-21T08:30:00Z"
}
],
"pagination": { "nextCursor": "eyJwYWdlIjoyfN...", "hasMore": true }
}
Job card fields
| Field | Type | Description |
| ---------------- | -------------- | ---------------------------------------------------------------- |
| id | uuid | Stable job identifier. |
| slug | string | URL slug. May be empty. |
| title | string | Job title. |
| companyName | string | Display name of the company. |
| companySlug | string | URL slug for the company, if known. |
| locationText | string | Human-readable location. |
| remote | boolean | Whether the role accepts remote applicants. |
| employmentType | enum | full_time, part_time, contract, internship, temporary. |
| seniority | string | Seniority bucket. |
| salary | object | null | { min, max, currency, period }. |
| snippet | string | Short description excerpt. |
| sourcePlatform | string | ATS platform (e.g. greenhouse). |
| discoveredAt | datetime | When the job was first crawled. |
| lastVerifiedAt | datetime | When the job was last confirmed active. |
Job cards do not include a per-card
statusfield. The search index only contains active jobs, so all returned cards are implicitly active. UseJobsService.Getfor the full status.

