Skip to main content
Optional. /tasks returns manager tasks — the to-dos your managers own. If you do not implement it, return 404 — HunterAI skips it and the sync still succeeds. It is incremental.

Purpose

A task is one to-do a manager owns in your CRM — a follow-up call, a document to send, a meeting to hold. HunterAI reads /tasks to compute manager-discipline metrics: overdue tasks, completion rate, and follow-up cadence. A task is linked to the lead or contact it concerns, so those metrics can be attributed per manager and per record.

Request

You must return tasks ordered by updated_at ascending. HunterAI advances its watermark page by page and relies on that order; an out-of-order page can cause older tasks on a later page to be skipped.

Response envelope

200 OK
The envelope (data, has_more, page, limit) is the same on every endpoint — see How sync works → The envelope. Only data and has_more are read.

Fields

Association

A task is linked to at most one entity, resolved in this exact order:
  1. If lead_id is present, the task is linked to that lead. lead_id wins even when contact_id is also present — contact_id is then ignored.
  2. If lead_id is absent and contact_id is present, the task is linked to that contact.
  3. If neither is present, the task is accepted and ingested, but linked to nothing.
A task linked to nothing is invisible in every report. It is ingested without error, but with no lead and no contact it attaches to no manager’s book of work and appears in no discipline metric — so it is almost never what you want. Send a lead_id (preferred) or a contact_id on every task.This differs from /calls: a call with neither lead_id nor contact_id is rejected and fails the calls entity, whereas an unassociated task is accepted and merely orphaned. Two similar endpoints, opposite behaviour — do not assume one from the other.

Timestamp format

due_at, completed_at, and updated_at accept a calendar date and time in these concrete forms:
  • With an explicit offset — 2025-07-05T09:00:00+05:00.
  • With a trailing Z for UTC — 2025-07-05T09:00:00Z.
  • With no zone at all — 2025-07-05T09:00:00, which is read as UTC.
  • The date and time may be separated by a T or by a single space (2025-07-05 09:00:00).
  • A bare date — 2025-07-05 — is accepted; the time becomes 00:00 UTC.
Prefer the explicit-offset form. An unparseable value becomes null for that field, and no error is raised — the task is still ingested. A task’s own created_at is not a timestamp field here; it is ignored entirely (see Fields the adapter ignores).
Consequence when this hits updated_at: a null updated_at carries no modification time, so the task cannot advance the watermark and is not selected by any later updated_since filter. In effect the task — and every future change to it — drops out of incremental sync. Keep updated_at a valid timestamp that advances on every change.

Fields the adapter ignores

Sending any of these has no effect — do not spend effort populating them:
  • created_atignored entirely. A task has no creation-time column; only updated_at, due_at, and completed_at are read. See Limitations → Fields dropped entirely.
  • task_type, duration, result — not part of this spec; dropped.
  • Any other key not listed in the Fields table — tasks retain no raw copy, so anything unlisted is dropped entirely.

Identity & cross-references

  • Identity: id is the stable primary key. HunterAI upserts by (connection, id), so a task’s id must never change — a changed id is ingested as a brand-new task.
  • lead_id → resolves against /leads.
  • contact_id → resolves against /contacts.
  • responsible_user_id → resolves against /users.
  • Association between the task and a lead or contact follows the Association rule above.

Incremental sync

/tasks is incremental. HunterAI sends updated_since; return only tasks whose updated_at is greater than or equal to it (inclusive — re-returning the boundary task is harmless, since the upsert is idempotent).
  • updated_at drives the per-entity watermark — the largest updated_at HunterAI has committed. The next run resumes from there.
  • You must return tasks ordered by updated_at ascending, so the watermark can advance page by page without skipping an older task on a later page.
  • updated_at must change on every modification of a task — completion, a due- date change, a reassignment, or a text edit. A change that does not advance updated_at falls at or below the watermark and is never pulled again.
See How sync works for the shared model.

Deletion behaviour

Tasks have no tombstone — there is no is_deleted on a task. Because the upsert only inserts and updates, a task you delete in your CRM, or simply stop returning, is not removed from HunterAI; its historical row persists. Marking a task is_completed: true records completion but does not delete it. Only leads support deletion, via is_deleted — see Limitations → Tombstones.

Failure modes

A page of tasks (up to 100 records) is validated and written as one transaction. The consequences:
  • A single malformed task fails the whole page. If any task on a page cannot be processed — a missing id, or an over-length id — none of the tasks on that page are saved. This is page-level, not per-record.
  • A failed page fails the tasks entity, not the whole sync. Because /tasks is optional, a page that fails takes the tasks entity down and reports it failed, but the overall sync still succeeds — unlike a required entity, whose failure fails the sync. Pages that already committed stay committed, and the next run resumes from the watermark.
  • A task with neither lead_id nor contact_id does not fail. It is accepted and ingested, just linked to nothing and therefore invisible in every report. This is the opposite of /calls, where an unassociated call fails the page.
  • An unparseable timestamp does not fail anything — the field becomes null and the task is still ingested. See the consequence for updated_at above.
  • 429, 5xx, and request timeouts are retried with exponential backoff up to 5 times, then the entity fails; a timeout is retried the same way as a 5xx. HunterAI applies its request rate limit per connection, so two connections to the same base URL are throttled independently.
  • A repeated or unbounded page — a page whose IDs match the previous page, or a run past the page ceiling — fails the entity. See How sync works → Paging.

If this endpoint is missing

/tasks is optional. Returning 404 skips it cleanly — the entity reports success with zero records and the overall sync still succeeds.
Without /tasks, HunterAI has no manager-discipline metrics — overdue tasks, completion rate, and follow-up cadence are all empty. Leads, contacts, calls, and attribution are unaffected.