Search for freelancers and view profiles.
Actions:
- search: Search freelancer profiles. Params: query (string — the ROLE or intent as a short phrase, e.g. "WordPress developer" or a job title; it is keyword AND-matched against profile text, so keep it short. Do NOT list skill keywords here — pass those as skills. Putting the same terms in both query and skills double-filters and over-narrows the results; prefer skills for concrete technologies and leave query for the role, or omit query when skills already capture the need), skills (array of string — each is matched as a structured skill filter/facet like the marketplace UI, not concatenated into the free-text query. Skills are AND-matched; if requiring all of them yields no matches the tool relaxes the broadest skill by ontology and retries, falling back to list order when the ontology cannot rank them, so list the most important first. The response then carries a note naming which skills were relaxed and which are still required — relay it so the user knows what was given up), rate_min (number), rate_max (number) (each must be greater than 0; rate_min cannot exceed rate_max; omit a bound to leave it open), country (string), state (string — filter by location state/region), regions (array of string — continents: Africa, Americas, Antarctica, Asia, Europe, Oceania), subregions (array of string — UN subregions, e.g. Northern America, Western Europe, South-Eastern Asia), talent_type (freelancer/agency — freelancer returns independent freelancers, agency returns agencies), job_success_min (number, 0-100 — minimum Job Success Score. The marketplace UI offers three standard choices: "Any job success" (omit this filter), "80% & up" (job_success_min=80), and "90% & up" (job_success_min=90) — offer these presets when the user asks to filter by job success; any other 0-100 value is also accepted, values outside 0-100 are rejected), top_rated (boolean — filter to Top Rated freelancers), top_rated_plus (boolean — filter to Top Rated Plus), rising_talent (boolean — filter to Rising Talent), contract_to_hire (boolean — open to contract-to-hire), offers_consultations (boolean — offers consultations), timezones (array of string — Upwork timezone labels, e.g. "UTC-05:00 Eastern Time (US & Canada)", "UTC+00:00 London" — NOT IANA names), languages (array of string — language codes, e.g. en, es), english_level (basic/conversational/fluent/native, or a rank number 1-4 — minimum English proficiency), earnings_min (number), earnings_max (number) (total earned amount range, USD; each must be > 0), no_earnings (boolean — freelancers with no earnings yet), hours_billed_min (number), hours_billed_max (number) (hours-billed range), total_jobs_min (number), total_jobs_max (number) (completed-jobs range), title (string — filter by freelancer title), limit (integer, 1–10, default 10), offset (number, default 0 — must be >= 0). All filters are optional. Each result has two distinct IDs: 'personId' (use it as freelancerId for invite_freelancer) and 'profile_key' (starts with ~, use it for get_profile). Do not interchange them. For hiring via manage_offers create_draft, first call get_profile with profile_key to obtain vendor_org_uid, then pass vendor_user_id=personId and vendor_org_uid. Each result includes job_success_score (the freelancer's Job Success Score, 0-100) when available — the same scale as the job_success_min filter. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.
- get_profile: Get a freelancer's public profile: skills, employment and education history, job aggregates (completed jobs, total earnings, feedback), portfolio projects when readable — check portfolio_available and relay the note when it is false — and the per-contract work history in work_history (AGEX-1733): each contract's title, dates, status, amount earned and the client's review. Check work_history_available and relay work_history_note when it is false; an absent section is NOT evidence the freelancer has no contracts. Params: profile_key (string — starts with ~ e.g. ~01abc123, from search results) or person_id (string — the numeric user.id returned by list_client_proposals); supply either one. Returns vendor_org_uid (the freelancer's org for hiring, pass it to manage_offers create_draft) and vendor_org_type (individual/agency) when available.
- smart_search: Recommend freelancers for one of the client's own job postings, ranked by Upwork's own matching for that job — the same list the "Invite freelancers" page shows. Prefer this over find_freelancers action=search whenever the client has a job posting: the ranking uses the whole posting, not a keyword query. Params: job_id or job_posting_id (string, required — a numeric owned posting ID from get_job_posting action=list; the posting must belong to the selected organization), query (string, optional — free text that RE-RANKS the recommendations toward those terms. It is a relevance boost, not a filter: the list stays the same size and may still contain profiles that do not mention the terms, so do not promise the user it excludes anything. Use the real filters below when they need a hard constraint), skills (array of string, optional — folded into the same free-text boost; the posting's own skills already inform the ranking), available_now (boolean), hire_me_now (boolean), country (string), state (string), region (string — continent, e.g. Europe), subregion (string — UN subregion), languages (array of string — language codes, e.g. en, es), english_level (basic/conversational/fluent/native, or a rank 1-4), job_success_min (number, 0-100 — the UI presets are 80 and 90), top_rated (boolean), top_rated_plus (boolean), rising_talent (boolean), rate_min / rate_max (number — hourly rate range), earnings_min / earnings_max (number — total earned, USD), hours_billed_min / hours_billed_max (number), limit (integer, 1–10, default 10), offset (number, default 0), use_job_category (boolean, default false — set true to additionally scope results to the job's own category, as the Invite Freelancers page's preselected filter does. The job id already drives the ranking, so this only narrows the pool; it is not needed for relevance). WHEN PRESENTING RESULTS, show for each freelancer the fields that are present, because these are what the Upwork page itself shows and the user is comparing against it: name, title, country, hourly_rate, total_earnings (already bucketed for display, e.g. "$50K+" — present it as given, never as an exact figure), job_success_score (as a Job Success percentage), top_rated (the talent badge — Top Rated Plus, Top Rated or Rising Talent), available_now, and recommendation_reason. Do not silently drop the badge or the earnings when they are present. A row with boosted=true is a PAID AD PLACEMENT: say so using boosted_label, and never present it as a purely earned ranking — organic_position gives the rank it would have held unpaid. When preselected_filters is present, tell the user which filters came from their job post and that they can be dropped. Results are LEAN CARDS: no description, no skills list. Call get_profile with profile_key for full detail. person_id is the freelancerId for invite_freelancer; profile_key (starts with ~) is for get_profile. Do not interchange them. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.
- smart_search_keywords: Keyword search for freelancers built from a job posting's skills. SUPERSEDED by action=smart_search, which asks Upwork for the actual recommendations for the job; use this only when explicitly asked to compare the two rankings. It reads the posting's classification skills, folds them into one free-text query and runs the generic freelancer search, so it cannot surface recommendation reasons or boosted placements. Params: job_id or job_posting_id (string, required — owned posting ID from get_job_posting action=list).