Skip to main content
GET
/
api
/
signals
/
feed
List signals in the feed
curl --request GET \
  --url https://app.puffle.ai/api/signals/feed \
  --header 'Authorization: Bearer <token>'
{ "signals": [ { "id": "aa111111-1111-1111-1111-111111111111", "source_id": "linkedin_jobs", "title": "Acme Corp is hiring a VP of Engineering", "label": "Hiring", "confidence": 0.92, "status": "new", "feedback": null, "signal_type_id": "bb111111-1111-1111-1111-111111111111", "color": "blue", "dismissed": false, "created_at": "2026-04-21T10:30:00Z", "normalized": { "url": "https://linkedin.com/jobs/view/123456", "company": "Acme Corp", "role": "VP of Engineering" }, "entity_company": "Acme Corp", "entity_person": null, "entity_id": "cc111111-1111-1111-1111-111111111111", "person_entity_id": null, "score": 87, "classification": { "reasoning": "Matches hiring signal type" }, "workflow_run": null } ], "has_more": true, "window_start": "2026-04-15T09:00:00Z" }

Overview

Returns the caller’s feed of classified signals. Supports two views — flat (view=signals) or entity-grouped (view=entities) — with a rolling time window controlled by since and days.
The canonical reference for this endpoint is List signals in the feed. This page is an alias that points at the same GET /api/signals/feed operation; consult the canonical page for the full schema, polling patterns, and agent notes.

AI agent notes

Agent flow. Poll this endpoint to detect new buying-intent signals on watched accounts. Dismissed signals and duplicates are filtered out server-side. Signals transition through a simple new then seen then dismissed lifecycle; only active, non-duplicate signals are returned.Follow up with dismissSignalFeed or feedbackSignalFeed to act on individual signals.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Query Parameters

view
enum<string>

signals (default) returns a flat list of classified signals; entities returns signals grouped by company/person with aggregates.

Available options:
signals,
entities
since
string<date-time>

ISO-8601 upper bound for the time window. Defaults to now. Combined with days to produce the lookback window.

Pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
days
integer

Number of days to look back from since. Defaults to 7. Clamped to the range 1-365.

Required range: 1 <= x <= 365

Response

Feed payload. Shape depends on view: signals array for view=signals, entities array for view=entities.

has_more
boolean
required

True when older signals/entities exist outside the current window — widen days to retrieve them.

window_start
string<date-time>
required

ISO-8601 lower bound of the window actually used.

Pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
signals
object[]
entities
object[]
total
integer

Entity count when view=entities.

Required range: 0 <= x <= 9007199254740991