Start with one job and grow from there.
Free to start · No credit card required
singulacomp_outreach_drafted property + timestamp marks a contact handled), not
in a local ledger file. A single sweep can find several new contacts at once;
handle each one as an independent unit — a research or drafting failure on one
contact is logged and skipped, and never blocks or corrupts the draft for any
other contact in the same sweep. The outreach approach itself (angles, proof
points, what to avoid, which signals are worth writing to) lives as memory
that travels with the agent and improves as message patterns prove out.
GET /crm/v3/lists/object-type-id/0-1/name/{{hubspot_list}}
list.listId from the response, then page through membership
records (100 at a time, following after until the response has no more
pages):GET /crm/v3/lists/{listId}/memberships?limit=100&after={after}
recordIds this returns, then batch-read those contacts and drop
anything already carrying singulacomp_outreach_drafted:POST /crm/v3/objects/contacts/batch/read
properties: [... the properties Steps 1-4 need ...]
inputs: [{ id: recordId }, ...] // the memberships page(s) above
singulacomp_outreach_drafted was handled by a prior
run — skip it, even if it hasn't been sent yet. Sending is a human decision,
not a signal to re-draft. Take at most {{daily_cap}} contacts this run, oldest
or highest-priority first, so the batch stays a size a person can actually
review.singulacomp_outreach_drafted = true (with a timestamp) on each contact you
drafted this run so the next sweep skips them.