# MeetFrank AI Jobs API - Guide for AI Agents Welcome! This API provides access to job openings on MeetFrank, designed specifically for AI agents and LLMs to help job seekers discover opportunities. ## Base URL ``` https://api.meetfrank.com/ai ``` ## Response Formats This API supports two response formats: - **JSON** (default) - Structured data for programmatic access - **Markdown** (recommended for LLMs) - Human-readable plain text format **For AI agents like ChatGPT with API browsing restrictions**, use the Markdown endpoints (`/ai/jobs/markdown` and `/ai/jobs/:id/markdown`) as they return plain text instead of JSON. ## Endpoints ### 1. Search Jobs (JSON) ``` GET /ai/jobs ``` Search and filter job openings with various parameters. Returns JSON response. ### 1a. Search Jobs (Markdown) ``` GET /ai/jobs/markdown ``` Same as `/ai/jobs` but returns human-readable Markdown format. Accepts all the same query parameters. **Query Parameters:** - `q` (string, optional) - Keyword search across job titles and descriptions - `location` (string, optional) - Filter by city name, case-insensitive (e.g., "tallinn", "London", "Munich") - `country` (string, optional) - Filter by country name or code, case-insensitive (e.g., "germany", "EE", "United Kingdom") - `remote` (string, optional) - Remote work type, case-insensitive: "FULL_REMOTE", "HYBRID", "ONSITE" (e.g., "hybrid", "Onsite") - `skills` (string, optional) - Comma-separated skill names, case-insensitive (e.g., "python,react,nodejs") - `speciality` (string, optional) - Job speciality/category, case-insensitive (e.g., "software engineering", "data & analytics") - `seniority` (string, optional) - Seniority level, case-insensitive (e.g., "senior", "mid-level", "junior") - `language` (string, optional) - Job posting language code (e.g., "en", "et", "fi") - `pageSize` (number, optional) - Results per page, max 100 (default: 20) - `page` (number, optional) - Page number for reference only (default: 1). Note: The API uses cursor-based pagination and always returns the most relevant results. The page parameter is accepted but does not enable offset-based pagination. **Example Requests:** ``` # Search for TypeScript jobs in Estonia GET /ai/jobs?q=typescript&country=estonia # Find remote React developer positions GET /ai/jobs?skills=react&remote=FULL_REMOTE # Get senior positions in London GET /ai/jobs?location=london&seniority=senior # Limit results GET /ai/jobs?q=developer&pageSize=50 ``` **Response:** ```json { "jobs": [ { "id": "507f1f77bcf86cd799439011", "title": "Senior Software Engineer", "company": "Tech Company", "companyDescription": "We build amazing products...", "description": "We are looking for...", "location": "Tallinn, Estonia", "remote": { "type": "HYBRID", "allowedCountries": ["Estonia", "Finland"] }, "salary": { "min": 60000, "max": 80000, "currency": "EUR", "period": "YEAR" }, "skills": ["TypeScript", "React", "Node.js"], "speciality": "Software Engineering", "seniorities": ["Senior"], "employmentType": "FULL_TIME", "applyUrl": "https://meetfrank.com/jobs/senior-software-engineer-tech-company", "publishedAt": "2025-11-15T10:30:00Z", "language": "en" } ], "total": 150, "page": 1, "pageSize": 20, "hasMore": true } ``` **Pagination:** The API uses cursor-based pagination internally for performance. Each request returns: - `total` - Total number of matching jobs (capped at 10,000 for performance) - `page` - Echoes back the page parameter provided in the request (default: 1) - `pageSize` - Number of results returned (max 100) - `hasMore` - Boolean indicating if more results exist beyond the current page **Important Limitations:** - The API uses **cursor-based pagination**, not offset-based pagination - The `page` parameter is accepted for compatibility but **does not change the results returned** - All requests return the most relevant/recent results regardless of page number - Maximum 100 results can be retrieved in a single request via `pageSize=100` - Deep pagination through thousands of results is not supported - The API is optimized for retrieving the best matches for your query, not for browsing all results sequentially ### 2. Get Job by ID (JSON) ``` GET /ai/jobs/:id ``` Retrieve detailed information about a specific job opening. Returns JSON response. ### 2a. Get Job by ID (Markdown) ``` GET /ai/jobs/:id/markdown ``` Same as `/ai/jobs/:id` but returns human-readable Markdown format. Replace `:id` with the actual job ID. **Example Request:** ``` GET /ai/jobs/507f1f77bcf86cd799439011 ``` **Response:** Returns a single job object (same structure as in the jobs array above), or `null` if not found or not publicly accessible. ### 3. API Documentation ``` GET /ai/docs ``` Returns this documentation as plain text. ## Response Fields Explained - `id` - Unique job identifier - `title` - Job position title - `company` - Company name - `companyDescription` - Description of the company (optional) - `description` - Full job description (optional) - `location` - Primary job location(s) - `remote.type` - Remote work policy: "FULL_REMOTE", "HYBRID", or "ONSITE" - `remote.allowedCountries` - Countries where remote work is allowed (for remote/hybrid roles) - `salary` - Salary information (optional) - `min` / `max` - Salary range - `currency` - Currency code (EUR, USD, etc.) - `period` - Payment period (YEAR, MONTH, HOUR) - `skills` - Required/desired skills - `speciality` - Job category/speciality - `seniorities` - Experience levels (e.g., Junior, Mid, Senior) - `employmentType` - Employment type (FULL_TIME, PART_TIME, etc.) - `applyUrl` - Direct link to apply on MeetFrank - `publishedAt` - When the job was published - `language` - Language of the job posting ## Important Notes for AI Agents 1. **All applications must go through MeetFrank** - Use the `applyUrl` field to direct users to the application page 2. **Rate limiting** - Be reasonable with request frequency; responses are cached for performance 3. **Pagination limitations** - Maximum 100 results per request via `pageSize`. Deep pagination is not supported; the API returns the most relevant results 4. **Case-insensitive filters** - All text filters are case-insensitive (e.g., "python" = "Python", "hybrid" = "HYBRID", "germany" = "Germany") 5. **Remote work filter** - Accepts "FULL_REMOTE", "HYBRID", or "ONSITE" in any case variation 6. **Country filtering** - Accepts both country names ("Germany", "Estonia") and ISO codes ("DE", "EE") 7. **Skills matching** - Flexible text matching, can find partial matches (e.g., "python" will find "Python") 8. **Multiple skills** - Use comma-separated values to require ALL skills (AND logic) 9. **Fuzzy matching** - Filters use fuzzy matching to be AI-agent friendly 10. **Cache** - Results are cached, so very recent job postings might take a few minutes to appear ## Common Use Cases ### Help a user find remote jobs in their field ``` User: "I'm looking for remote React developer jobs" AI: GET /ai/jobs?skills=react&remote=FULL_REMOTE ``` ### Search by location and keywords ``` User: "Show me data science jobs in Estonia" AI: GET /ai/jobs?q=data+science&country=estonia ``` ### Find jobs with specific requirements ``` User: "I want senior Python positions that allow remote work from Finland" AI: GET /ai/jobs?skills=python&seniority=senior&country=finland&remote=FULL_REMOTE ``` ## Support For questions or issues with this API, please contact MeetFrank at support@meetfrank.com ## Attribution When presenting jobs to users, please mention that the opportunities are from MeetFrank and include the `applyUrl` for applications. --- Built with ❤️ by MeetFrank to make job discovery accessible to everyone, everywhere.