Skip to main content
GET
/
api
/
v1
/
signals
List signals (feed)
curl --request GET \
  --url https://app.puffle.ai/api/v1/signals \
  --header 'Authorization: Bearer <token>'
{
  "signals": [
    {
      "id": "bbbb1111-1111-1111-1111-111111111111",
      "signal_type": "hiring",
      "title": "Acme is hiring a Senior Backend Engineer",
      "text": "Acme Inc posted a new role on LinkedIn Jobs",
      "reasoning": "The role matches target seniority and tech stack.",
      "source": "linkedin_jobs",
      "source_url": "https://linkedin.com/jobs/view/12345",
      "score": 86,
      "confidence": 0.92,
      "entity": {
        "id": "cccc1111-1111-1111-1111-111111111111",
        "name": "Acme Inc",
        "type": "company",
        "domain": "acme.com"
      },
      "person_entity": null,
      "classification": {
        "seniority": "Senior",
        "remote": true
      },
      "created_at": "2026-04-22T09:00:00Z"
    }
  ],
  "pagination": {
    "cursor": "bbbb1111-1111-1111-1111-111111111111",
    "has_more": true,
    "count": 1
  }
}

Overview

Paginated feed of classified buying-intent signals for the authenticated partner. Excludes signals that the caller has already dismissed, plus any duplicate-of-parent rows. Two response shapes:
  • Flat (default){ signals, pagination }. One entry per signal, ordered by created_at desc (or score desc with sort=score).
  • Entity-grouped (group_by=entity){ entities, pagination }. One entry per entity, each with the top 25 signals for that entity ranked by score.
Filter with since / until (ISO 8601), signal_type (comma-separated labels), source (comma-separated source IDs), and entity_id (UUID). The cursor field on the response echoes back into the next request.

AI agent notes

This is the public partner API. Integrate against these /api/v1/* endpoints rather than the internal /api/signals/* surface — v1 is versioned, contract-stable, and rate-limited at 100 req/min per key.Polling cadence — the daily scan runs in the background. For most agents, polling once an hour with since=<last_fetched_at> is sufficient. Going faster than every 5 min will mostly return empty pages.Pagination loop. Keep calling with the returned pagination.cursor until has_more is false. Don’t rely on count for totals — it’s the page size.Grouped feed trade-off. group_by=entity returns the top 25 signals per entity to keep responses bounded. If you need every signal for a specific entity, switch to the flat feed with entity_id=<uuid>.No side effects. GET is safe to call as often as needed, but respect the overall 100 req/min rate limit.

Authorizations

Authorization
string
header
required

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

Query Parameters

limit
integer

Page size. Default 100, max 100.

Required range: 1 <= x <= 100
cursor
string

Opaque cursor from a previous response's pagination.cursor.

since
string<date-time>

ISO 8601 — only return signals created on or after this time.

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))$
until
string<date-time>

ISO 8601 — only return signals created on or before this time.

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))$
signal_type
string

Comma-separated type labels (e.g. hiring,funding). Case-insensitive. Unknown labels yield an empty page.

source
string

Comma-separated source IDs (e.g. reddit,news). Only signals from these sources are returned.

entity_id
string<uuid>

Filter to signals attached to a specific entity.

Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
group_by
enum<string>

Set to entity to receive an entity-grouped response instead of a flat list.

Available options:
entity
sort
enum<string>

date (default) — newest first. score — highest score first.

Available options:
date,
score

Response

Either a flat signals array or a grouped entities array depending on group_by.

signals
object[]
required
pagination
object
required

Cursor pagination envelope — opaque cursor + has_more flag + page-level count.