Daily new-jobs check for agents
Run the same search once a day and get only the jobs that are new since the last run, with postedSince and nextSince.
The most common thing an agent does with Trawle is a scheduled check: "tell me about new frontend jobs in Copenhagen every morning." The API is built for this.
How it works
Every search response includes nextSince, the time of that search. Store it. On the next run, send it back as postedSince, and you get only jobs that Trawle first saw after your previous run.
{
"query": { "roles": ["frontend-engineer"], "places": [2618425] },
"postedSince": "2026-10-30T07:00:00.000Z"
}No overlap and no gaps: a job first seen between two runs shows up in exactly one of them.
Run once a day
Trawle scans every employer board once a day, starting early in the morning (UTC). dataDate in each response says when the data last changed. Running more often than daily just returns empty results; running less often is fine, because postedSince catches up on everything since the stored time.
A complete run
type State = { since?: string };
async function dailyCheck(state: State) {
const jobs = [];
let cursor: string | null = null;
let nextSince: string | undefined;
do {
const response = await fetch("https://trawle.com/v1/jobs/search", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: { roles: ["frontend-engineer"], places: [2618425] },
postedSince: state.since,
cursor,
limit: 100,
}),
});
const page = await response.json();
jobs.push(...page.jobs);
cursor = page.nextCursor;
nextSince ??= page.nextSince; // keep the first page's value
} while (cursor);
state.since = nextSince; // store only after the run succeeded
return jobs;
}On the first run there is no stored time. Leave out postedSince and you get every matching open job, or use query.posted: "1d" (or "7d") to start with a short window.
Tips
- Store
nextSincefrom the first page, and only after the whole run succeeds. If a run fails, the next one picks up from the older time and nothing is lost. - Keep the query identical between runs. A changed query with an old
postedSinceonly returns jobs new since then, not every match for the new query. postedSincecounts from when Trawle first saw the job (firstSeenAt), not the employer's "date posted", which is often unreliable.- Reposts count as new: a job taken down and posted again under a new id has a new
firstSeenAt. Addquery.reposts: "hide"to skip them, or checkrepostCount. - The MCP server offers the same pattern as a
daily_job_searchprompt. See MCP for agents.