# Guru.com API scraper — live freelance jobs, rich job detail, the category/skill taxonomy, and freelancer/provider profiles from Guru.com in clean PII-safe JSON: budget, skills, quotes, posted date, and provider ratings. No login required.

> Search live freelance JOBS across the whole Guru.com board. `query` is served SERVER-SIDE via Guru's own skill/keyword path — known skills are canonicalised from the shipped slug dictionary (`nodejs` → `node.js`), unknown terms use Guru's free-text match, and `data.match` reports which. Also browsable by `category`/`skills` and paginated by `offset`. Returns title, description, budget{type,min,max,currency}, skills[], quote count (bids_count), posted date, and url. No client PII.
> ReefAPI engine `guru` · 4 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/guru/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed or blocked calls are free.
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /guru/v1/search — 1 credit
Search live freelance JOBS across the whole Guru.com board. `query` is served SERVER-SIDE via Guru's own skill/keyword path — known skills are canonicalised from the shipped slug dictionary (`nodejs` → `node.js`), unknown terms use Guru's free-text match, and `data.match` reports which. Also browsable by `category`/`skills` and paginated by `offset`. Returns title, description, budget{type,min,max,currency}, skills[], quote count (bids_count), posted date, and url. No client PII.

**Parameters:**
- `query` (string, optional) — What to search Guru's whole job board for, SERVER-SIDE — a skill (`wordpress`, `nodejs`, `data entry`) or any free-text term (`excel`, `translation`). Known skills are canonicalised first (`nodejs` → `node.js`); anything else is handed to Guru's own keyword match. `data.match` says which of the two happened. A term Guru finds nothing for returns NOT_FOUND, never an empty 200.
- `category` (enum, optional) — Top-level category slug for server-side scoping (see the `categories` action). One of: programming-development, design-art, writing-translation, sales-marketing, business-finance, engineering-architecture, administrative-secretarial, legal, education-training, other. [one of: programming-development, design-art, writing-translation, sales-marketing, business-finance, engineering-architecture, administrative-secretarial, legal, education-training, other]
- `skills` (array, optional) — Skill slug to scope the search server-side, with or without a `category` (e.g. skills=['php'], or category=programming-development + skills=['php']). First value used. When BOTH `skills` and `query` are sent, `skills` picks the server-side path and `query` is applied on top as a client-side filter.
- `limit` (integer, optional, default 30) — How many jobs to return (1–80). Use `offset` to page.
- `offset` (integer, optional, default 0) — Pagination offset (0–5000); skip this many results. Works with `query`/`skills`/`category` (Guru pages the skill path too). Ignored only in the client-side fallback (`match`=`recent_feed_filter`), which always scans from the newest posting.

**Returns:** projects[]{id, title, description, type, budget{type,min,max,currency}, skills[], category, bids_count, posted_at, posted_relative, url}, returned, offset, search_term, resolved_skill, match, server_side, note

**Example request body:**
```json
{
  "limit": 8
}
```

### POST /guru/v1/project — 1 credit
Full detail for one Guru.com job by URL, slug, or numeric id — title, description, budget{type,min,max,currency}, skills[], employment type, posted date, valid-through, and the job's location requirement (country). No client PII.

**Parameters:**
- `id` (string, required) — The job to fetch: the full Guru job URL or the `<slug>/<id>` path (both are returned by `search` as `url` / `seo_url`). A BARE numeric id will not work — Guru serves the detail page only at /jobs/<slug>/<id> and answers a bare id with its login wall.

**Returns:** project{id, title, description, type, budget{...}, skills[], posted_at, client_country, detail{valid_through, employment_type}, url}

### POST /guru/v1/user — 1 credit
PUBLIC business profile of a Guru.com freelancer/provider by profile URL or handle: display name, headline, country, skills, and rating summary. PII (email/phone/legal-name/address) is NEVER returned.

**Parameters:**
- `username` (string, required) — The freelancer/provider to fetch: a Guru profile URL or handle. Returns the PUBLIC business profile only — no email / phone / legal-name / address (those are never returned).

**Returns:** user{username, display_name, tagline, profile_description, country, city, skills[], reputation{overall_rating, reviews}, avatar, profile_url}

### POST /guru/v1/categories — 1 credit
List the top-level Guru.com freelance job categories (Programming, Design, Writing…) — the browse taxonomy for scoping a `search`.

**Parameters:** none

**Returns:** categories[]{id, name, seo_url}, returned

## More
- Try it live, no code: https://reefapi.com/playground?engine=guru
- Human docs page: https://reefapi.com/docs/guru
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
