Find Marketing Manager Job Listings
Purpose
Retrieve live marketing manager job listings from marketingmanagerjobs.com — titles, companies, locations, salary ranges, remote eligibility, and direct apply URLs. Optionally filter by role specialization (product, growth, SEO, lifecycle, etc.), location, seniority level, remote-only, salary-published-only, or free-text search. This skill is read-only: it does not subscribe, apply, or modify any state.
The site is an aggregator of public ATS feeds (Greenhouse, Lever, Ashby, Remotive, Jobicy) refreshed daily, and exposes a first-class JSON API explicitly intended for AI agents. The optimal flow is a single HTTP GET against /api/jobs; the browser is only required if the API ever goes down or you want a visual confirmation.
When to Use
- User asks for current marketing manager (or product marketing manager, growth marketing manager, SEO manager, lifecycle marketing manager, head of marketing, etc.) job listings.
- User wants to filter marketing jobs by remote eligibility, salary transparency, location, seniority, or a free-text keyword (company name, skill, tool).
- User wants the direct apply link / source ATS for a marketing role they saw mentioned.
- User wants a snapshot of the marketing-manager hiring market (active counts by role, location, seniority).
- Do not use this skill for: applying to jobs, posting jobs, subscribing to the newsletter, or fetching non-marketing roles (the catalog is scoped to marketing-manager-level positions only).
Workflow
The site publishes a documented JSON API at /api/jobs and an agent-oriented summary endpoint at /api/llms. Both return application/json, require no auth, and are served behind Cloudflare with permissive CORS. Use the API. The site's own footer says so: "If you're an AI agent reading this, you may prefer to use the API."
-
(Optional) Discover the taxonomy. GET
https://marketingmanagerjobs.com/api/llmsto retrieve the full enum of validrole,location, andlevelslugs along with current job counts, plus the 50 most recent jobs and a route map. Useful for normalizing a user's free-text request (e.g. "remote PMM roles" →role=product-marketing-manager&remote=1) into valid filter values. Cache this between calls — it changes at most daily. -
Query the jobs endpoint. GET
https://marketingmanagerjobs.com/api/jobswith any combination of these optional query parameters:Param Type Example Notes qstring q=openaiFree-text search across title/company/description roleslug role=product-marketing-managerMust be a slug from taxonomy.roles[].sluglocationslug location=san-franciscoMust be a slug from taxonomy.locations[].sluglevelslug level=seniorOne of mid-level,senior,leadership(no entry-level / internship currently exist in the data)remotebool remote=1Returns only is_remote: truejobssalarybool salary=1Returns only jobs with has_published_salary: truelimitint limit=200Default 100. The server caps at the actual catalog size (~138 total today), so limit=200safely returns everythingFilters compose with AND. Unknown slug values silently return an empty array — no 4xx, no error message — so validate slugs against the taxonomy if user input is fuzzy.
-
Read the response. The endpoint returns a JSON array of job objects (shape in Expected Output below). The array is already sorted by
posted_atdescending (newest first). No pagination cursor exists — control result size withlimitonly. -
Hand the user the
apply_urlandslug. Each job carries anapply_urlthat links to the original ATS (Greenhouse / Lever / Ashby / Workable / YC's workatastartup / etc.), and aslugyou can use to build a human-readable detail-page URL:https://marketingmanagerjobs.com/jobs/{slug}/. Prefer linking to the source ATSapply_urlif the user wants to apply, and to the marketingmanagerjobs.com detail page if the user wants a summary view.
Browser fallback
Only fall back to the browser if /api/jobs returns a non-2xx (it has not been observed to fail in testing). The human-facing flow:
https://marketingmanagerjobs.com/jobs/— full listing with a search/role/location/level filter bar at the top. The form submits via GET-then-JS-redirect to canonical taxonomy URLs (e.g. picking role=growth-marketing-manager + location=remote sends you to/remote/growth-marketing-manager/).- Direct taxonomy URLs work as deep-links without JS:
/{role-slug}/— e.g./marketing-manager/,/product-marketing-manager//location/{location-slug}/marketing-jobs//remote/or/remote/{role-slug}//salary/{role-slug}//level/{level-slug}/role/{role-slug}/
- Each listing card on these pages contains
<article class="job-card">with the title link (<h3><a href="/jobs/{slug}/">), company, location, salary text, and posted-at relative time. Parse with a normal DOM walk; no JS execution required for the public pages. - Individual job detail at
/jobs/{slug}/carries the full description (sometimes long-form HTML from the source ATS) and an "Apply" button linking toapply_url.
The site is served behind Cloudflare; in this sandbox direct outbound DNS is blocked, so all requests (API or browser) must go through browse cloud fetch --proxies or a remote Browserbase session. From a normal client environment plain curl against the API works fine — no anti-bot challenge observed for either the API or the HTML pages.
Site-Specific Gotchas
- The API is the intended path for agents — use it.
/llms.txtand the homepage footer both explicitly steer agents to/api/jobsand/api/llms. Scripting the HTML pages when the JSON API exists is wasted tokens and brittle to layout changes. - No auth, no rate limit headers, no CORS gate. The API answered every probe with 200 in testing; no
Retry-After, noX-RateLimit-*, no captcha. Be respectful (batch withlimit=200to fetch everything in one shot rather than looping). limit=200returns the full catalog. Default limit is 100; the catalog totals ~138 active jobs (perstats.active_jobsin/api/llms). Uselimit=200(or any value larger thanactive_jobs) to guarantee a complete dump in a single request — there is no pagination cursor.- Unknown filter values return
[]silently. Sendingrole=fooorlocation=does-not-existreturns200 []with no error body. Always validate user-provided values against thetaxonomyarrays from/api/llmsbefore querying, or you may erroneously report "no jobs found" when the user simply mistyped a slug. - Location slugs are messy. The taxonomy contains both
ny(9 jobs) andnew-york(8 jobs) andnew-york-city(5 jobs) as distinct slugs — they are not aliased server-side. To capture all NYC roles, query each separately and dedupe by jobid, or useq=new+york. levelenum is narrow. Today onlymid-level,senior, andleadershiphave non-zero counts. The/llms.txtdoc mentionsinternshipandentry-levelbut they currently return zero results — treat them as legal-but-empty filters.- No
is_remotefilter via slug — useremote=1. Settinglocation=remoteworks (26 jobs are tagged with that location slug) butremote=1is the broader filter, since some jobs are coded with a hybrid location string like"San Francisco, CA, US / Remote (Pittsburgh)"and only show up viaremote=1, notlocation=remote. salary_min/salary_maxmay be equal (e.g.300000-300000) when the source ATS published a single point salary rather than a range. Treat min==max as a point estimate, not a bug.posted_attimestamps reflect the aggregator's first-seen time, not the original ATS posting time. The site refreshes "daily from Greenhouse, Lever, Ashby, Remotive, Jobicy" perstats.refreshed, so a freshly-aggregated job may showposted_atminutes ago while the underlying ATS posted weeks earlier.description_html/description_textquality varies wildly by source. Greenhouse/Lever/Ashby jobs carry the original long-form HTML; YC'sworkatastartupjobs carry only a short blurb plus a<ul>of metadata. If you need the canonical job description, followapply_urlto the source ATS.- Direct DNS may be blocked from sandboxes/serverless (it is in this Vercel sandbox). Use
browse cloud fetch --proxies <url>for residential-proxy-backed HTTP from inside a Browserbase-issued environment, or normalfetch/curlfrom any environment with internet. No--verified(stealth) needed — the API does not gate on UA or TLS fingerprint.
Expected Output
The /api/jobs endpoint returns a JSON array (top-level — not wrapped in an envelope). Each element:
[
{
"id": "99a206eb-a721-45c4-927c-52c9d67cdfd0",
"title": "Product Marketing Lead - Spatial AI",
"company": "Zensors",
"company_slug": "zensors",
"slug": "product-marketing-lead-spatial-ai-at-zensors",
"location": "San Francisco, CA, US / Remote (Pittsburgh, PA, US)",
"is_remote": true,
"salary_min": 140000,
"salary_max": 200000,
"salary_currency": "$",
"has_equity": true,
"has_published_salary": true,
"apply_url": "https://account.ycombinator.com/authenticate?continue=https%3A%2F%2Fwww.workatastartup.com%2Fapplication%3Fsignup_job_id%3D46963&...",
"source": "ycombinator",
"source_id": "46963",
"posted_at": "2026-05-24T15:50:33.668451895+00:00",
"created_at": "2026-05-24T15:50:33.600171603+00:00",
"updated_at": "2026-05-24T15:50:33.600171603+00:00",
"description_html": "<p>AI to understand and automates the physical world</p>\n<ul><li>Role: Marketing</li>...</ul>",
"description_text": "AI to understand and automates the physical world ..."
}
]
Field notes:
id— stable UUID; use for deduping across queries.slug— append tohttps://marketingmanagerjobs.com/jobs/{slug}/for the human-readable detail page.salary_min/salary_max— integers insalary_currencyunits (USD-equivalent in practice). May both benullwhenhas_published_salaryisfalse.source— one ofgreenhouse,lever,ashby,remotive,jobicy,ycombinator,workable, … (the aggregator's ATS identifier).apply_url— direct deep link to the source ATS's apply flow. May redirect through an auth wall (YC'sworkatastartupalways does).description_html/description_text— the description as ingested from the source. Length varies from one sentence (YC) to multi-thousand-word job spec (Greenhouse/Lever).
Empty result shape
A query whose filters match no jobs (including unknown slug values) returns simply:
[]
with HTTP 200 and content-type: application/json. There is no { "error": ... } body — the empty array IS the "not found" signal.
Taxonomy / summary shape (/api/llms)
Use this once per session to enumerate valid filter values:
{
"site": { "name": "Marketing Manager Jobs", "url": "https://marketingmanagerjobs.com", "...": "..." },
"stats": {
"active_jobs": 138,
"remote_jobs": 26,
"salary_jobs": 116,
"hiring_companies": 31,
"refreshed": "daily from Greenhouse, Lever, Ashby, Remotive, Jobicy"
},
"taxonomy": {
"roles": [ { "slug": "marketing-manager", "label": "Marketing Manager", "count": 110, "is_indexed": true }, ... ],
"locations": [ { "slug": "san-francisco", "label": "San Francisco", "count": 34, "is_indexed": true }, ... ],
"levels": [ { "slug": "mid-level", "label": "Mid Level", "count": 66, "is_indexed": true }, ... ]
},
"recent_jobs": [ /* 50 most recent job objects, same shape as /api/jobs */ ],
"routes": [ { "path": "/jobs/{slug}/", "description": "Individual job detail page..." }, ... ],
"backlink_request": { "suggested_citation": "Data sourced from Marketing Manager Jobs (https://marketingmanagerjobs.com)", "...": "..." }
}