POST /api/ctgoodjobs/jobs/search
Price: 20 credits
Search CTgoodjobs (Hong Kong job board) listings by keyword and a full set of board filters: job function and sub-area, district or region, industry, employment term, education, career level, benefits, work model, vertical channel with its service types, salary range, years of experience, publication window, employer, job ids, curated tag, and application-mode flags. Returns job cards with id, url, title, employer (id, name, profile url, logo), publication and expiry timestamps, salary, experience range, highlights, job areas, work locations with coordinates and Chinese names, employment types, career levels and listing flags. One filter set yields at most 3000 listings, so wide sweeps have to be segmented by function, district or keyword.
Search the Hong Kong job board CTgoodjobs. Filter by keyword plus search_mode (all text, title, title + company + skills, or company only), job_function and job_area, location (district) and region, industry, employment_type, education, career_level, benefit, work_model, channel (NGO, graduate, civil service, finance, IT, part-time and other verticals) together with ngo_service_type / graduate_job_type / civil_service_type, salary_unit with salary_from and salary_to in HKD, experience_from and experience_to in years, post_date, company (employer id), job (specific job ids), tag, and the flags is_cv_optional, has_great_benefits, is_whatsapp_apply, is_ct_message, is_crawled and has_salary_shown. The board matches salary, experience and education inclusively: an ad whose declared range overlaps the requested one is returned, and so is an ad that declares nothing at all, so these three narrow the result set without guaranteeing every result states the value. A location filter also returns ads tagged with the administrative district that contains the requested one. Each result carries id, url, job_title, company_id, company_name, company_url, image, published_at, expires_at, salary, experience_from/to, highlights, job_areas, locations (with latitude, longitude and name_zh), employment_types, career_levels and listing flags. Any one filter set exposes at most 3000 listings; segment by job_function, location or keyword to go wider. tag only accepts the board's own curated tags (the slugs behind its related-search links, such as sales-manager); anything else is refused with 412 rather than answering with an unfiltered result set.
access-token string requiredtimeout integer — Max scrapping execution timeout (in seconds) (default: 300; min: 20; max: 1500)count integer required — Max result count (examples: 20; min: 1; max: 3000)keyword string — Search keyword (default: ""; examples: "sales manager")search_mode string — Which part of the ad the keyword is matched against (default: "Y"; one of: "Y", "JC", "J", "C")sort string — Result ordering; relevance only applies when a keyword is set (default: "2"; one of: "1", "2")job_function array nullable — Top-level job functions (matched as OR) (one of: "001", "048", "007", "004", "013", "052", "041", "015", "010", "017", "018", "002", "021", "022", "025", "051", "026", "003", "027", "028", "039", "029", "049", "032", "037", "038", "050", "043")job_area array nullable — Job sub-areas inside a function (matched as OR) (one of: "201", "101", "202", "204", "205", "500", "114", "403", "408", "210", "501", "212", "214", "409", "460", "505", "216", "218", "112", "285", "480", "250", "107", "502", "242", "294", "547", "546", "289", "548", "544", "133", "543", "284", "241", "251", "481", "545", "542", "243", "108", "293", "541", "249", "225", "463", "461", "462", "551", "406", "407", "166", "123", "118", "120", "259", "121", "258", "399", "418", "535", "540", "536", "537", "538", "539", "554", "555", "170", "556", "419", "420", "557", "558", "464", "559", "421", "560", "422", "262", "263", "126", "127", "130", "423", "128", "129", "131", "465", "561", "562", "563", "564", "565", "566", "567", "568", "569", "111", "570", "571", "572", "573", "574", "575", "576", "466", "467", "135", "468", "469", "549", "492", "278", "493", "275", "550", "494", "276", "279", "274", "136", "503", "495", "496", "277", "410", "411", "412", "413", "102", "414", "415", "531", "301", "533", "529", "141", "305", "459", "309", "303", "144", "532", "315", "316", "458", "534", "530", "310", "300", "311", "312", "143", "313", "302", "314", "528", "138", "482", "396", "139", "321", "456", "322", "140", "470", "323", "504", "427", "164", "177", "148", "324", "325", "326", "328", "428", "515", "506", "507", "395", "508", "155", "509", "156", "404", "472", "329", "330", "516", "332", "149", "336", "473", "471", "333", "337", "103", "431", "433", "434", "220", "435", "436", "437", "438", "439", "150", "339", "510", "151", "152", "511", "474", "344", "346", "347", "446", "440", "441", "153", "442", "356", "357", "444", "358", "359", "487", "522", "525", "497", "521", "165", "520", "519", "489", "523", "518", "527", "524", "490", "526", "552", "106", "512", "553", "429", "475", "154", "513", "206", "146", "476", "171", "448", "157", "447", "449", "477", "169", "483", "499", "498", "484", "162", "486", "363", "364", "366", "450", "368", "451", "115", "453", "378", "384", "385", "163", "398", "454", "455", "386", "387", "514", "517", "394", "425", "479", "426", "172", "391", "392", "176", "173", "174")location array nullable — Work districts (matched as OR); ads tagged with the administrative district containing the requested one match too (one of: "121", "097", "041", "001", "002", "003", "004", "005", "089", "006", "011", "154", "131", "164", "102", "159", "017", "160", "155", "025", "162", "043", "045", "048", "161", "051", "053", "055", "057", "062", "066", "103", "163", "068", "069", "073", "098", "074", "100", "087", "140", "090", "169", "009", "010", "013", "079", "019", "021", "023", "128", "156", "027", "028", "143", "029", "034", "145", "035", "036", "022", "042", "044", "168", "167", "122", "047", "166", "052", "058", "060", "142", "063", "170", "070", "077", "080", "083", "165", "091", "144", "093", "092", "141", "185", "187", "012", "015", "016", "175", "189", "184", "137", "182", "024", "031", "032", "110", "146", "173", "134", "124", "125", "181", "039", "127", "157", "126", "049", "050", "174", "176", "054", "152", "061", "151", "186", "099", "104", "065", "180", "105", "071", "150", "178", "188", "072", "179", "172", "076", "171", "078", "081", "082", "147", "183", "084", "148", "177", "190", "094", "149", "138", "116", "136", "115", "109", "133", "119", "112", "120", "129", "800", "132", "108", "130", "123", "135", "139", "117", "113", "114", "111", "118", "193", "101", "008", "014", "192", "018", "153", "107", "037", "158", "191", "106")region array nullable — Whole work regions (matched as OR with location) (one of: "1_r", "2_r", "3_r", "4_r", "5_r", "6_r")industry array nullable — Employer industries (matched as OR) (one of: "101", "102", "113", "104", "141", "124", "169", "111", "178", "179", "112", "177", "116", "180", "117", "105", "103", "119", "175", "120", "114", "181", "133", "134", "118", "152", "137", "138", "115", "142", "171", "148", "132", "173", "129", "151")employment_type array nullable — Employment terms (matched as OR) (one of: "001", "002", "003", "004", "005", "006", "007")education array nullable — Required education levels (matched as OR); ads stating no requirement match any value (one of: "007", "001", "002", "003", "004", "005", "006")career_level array nullable — Career levels (matched as OR) (one of: "001", "002", "004", "006")benefit array nullable — Advertised benefits (matched as OR) (one of: "001", "002", "009", "023", "025", "035", "029", "003", "036", "020", "024", "004", "032", "027", "026", "030", "031", "005", "033", "022", "006", "018", "017", "028", "007", "008", "015", "016", "021", "034", "019", "014", "013", "011", "012")work_model string nullable — On-site or hybrid/work-from-home (one of: "001", "002")channel string nullable — Vertical channel the ad is published in (one of: "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", "013", "014", "015", "016", "017", "018", "020")ngo_service_type array nullable — Social-service areas; requires channel=004. The board matches this one loosely: 24 of 30 sampled results declared the requested area (one of: "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", "022", "013", "014", "015", "016", "017", "018", "019", "020", "021")graduate_job_type array nullable — Graduate programme types; requires channel=017 (one of: "501", "502", "503", "504")civil_service_type array nullable — Public-sector employer types; requires channel=020 (one of: "601", "602", "603", "604", "605", "606")salary_unit string nullable — Salary basis for salary_from/salary_to (one of: "MON", "HR")salary_from number nullable — Lower bound of the advertised salary range in HKD; ads without a published salary match too (min: 0)salary_to number nullable — Upper bound of the advertised salary range in HKD; ads without a published salary match too (min: 0)experience_from integer nullable — Lower bound of required years of experience; ads stating no requirement match too (min: 0; max: 20)experience_to integer nullable — Upper bound of required years of experience; ads stating no requirement match too (min: 0; max: 20)post_date string nullable — Published within the last period (one of: "1", "2", "3")company string nullable — Employer id, or an employer URL containing it (examples: "00001885")job array nullable — Restrict the result set to specific job ids (examples: ["09520465"])tag string nullable — Curated search tag as used in related-search links; a tag the board does not publish is refused with 412 instead of silently widening the search (examples: "sales-manager"; minLength: 1)is_cv_optional boolean nullable — Only ads that accept an application without a CV; the board does not support excluding them (one of: true)has_great_benefits boolean nullable — Only ads flagged by the board as offering great benefits; the board does not support excluding them (one of: true)is_whatsapp_apply boolean nullable — Only ads that accept applications over WhatsApp; the board does not support excluding them (one of: true)is_ct_message boolean nullable — Only ads with in-platform employer chat; the board does not support excluding them (one of: true)is_crawled boolean nullable — Only ads aggregated from an employer site rather than posted directlyhas_salary_shown boolean nullable — Only ads that publish a salary figure@type string (default: "CtgoodjobsJobCard")id string requiredurl string requiredjob_title string requiredcompany_id string nullablecompany_name string nullablecompany_url string nullableimage string nullablepublished_at integer nullableexpires_at integer nullablesalary object nullable@type string (default: "CtgoodjobsSalary")display string nullablemin number nullablemax number nullablecurrency string nullableunit string nullableis_negotiable boolean nullablehas_commission boolean nullableexperience_from integer nullableexperience_to integer nullablehighlights array (default: [])job_areas array (default: [])@type string (default: "CtgoodjobsJobArea")id string nullablename string requiredfunction string nullablearea string nullableurl string nullablefunction_url string nullableskill_tag_path string nullablelocations array (default: [])@type string (default: "CtgoodjobsJobLocation")id string nullablename string requiredname_zh string nullablelatitude number nullablelongitude number nullableemployment_types array (default: [])@type string (default: "CtgoodjobsTaxonomyItem")id string nullablename string requiredurl string nullablecareer_levels array (default: [])@type string (default: "CtgoodjobsTaxonomyItem")id string nullablename string requiredurl string nullableis_promoted boolean nullableis_boosted boolean nullableis_featured boolean nullableis_high_salary boolean nullableis_fresh_grad boolean nullableis_cv_optional boolean nullableis_whatsapp_apply boolean nullableis_ct_message boolean nullableis_crawled boolean nullable422 — The request body did not validate Check the fields against this schema. A URN with the wrong prefix is the most common cause.408 — The request ran past its time limit Raise `timeout` in the request body, up to the maximum this endpoint documents. Lowering `count` or turning off the `with_*` flags also helps, because less work finishes sooner.412 — The requested tag is not one the board publishes Retrying will not help: either the entity does not exist, or the input points at a different one.429 — Too many requests: a rate limit or a usage window is exhausted When the response carries an X-Retry-After header, wait that many seconds and retry: the same number is in the body as `detail.retry_after`, and the limit clears once that window passes. The message in the body names the limit that was hit.500 — Something broke on our side Retrying will not help. If it keeps happening, send us the X-Request-ID from the response headers.529 — Rate limit reached, or the endpoint is overloaded Wait at least 30 seconds, then retry.X-Error — Error message text (present only on error)X-Request-ID — Unique request identifierX-Execution-Time — Execution time in secondsX-Result-Count — How many records the body carries. 0 means an empty result, which is a normal answer and not by itself an error. A non-zero count can come back together with X-Error when the failure happened partway through — read this header and X-Error independently.X-Total-Available-Results — How many records exist for this query, when the endpoint can say. On a `dry_run` request this is the answer and the body is empty. It saturates: the endpoint's documented maximum means 'at least that many', any smaller number is exact.X-Warning — Present when the request body carried keys this endpoint does not document. They were ignored, so any filter you meant to apply through them did not apply. Check the spelling against this schema and retry.X-Retry-After — Seconds to wait before retrying. Present only on 429.