KasarKasar Docs
API Reference

Activity

Retrieve the activity feed for any CRM record, including interactions, tasks, and notes — as independently paginated sections or one merged timeline.

The activity endpoint returns a unified feed of everything that happened on a record. It aggregates interactions (emails, meetings), tasks, and notes into a single response. You can request the data as independently paginated sections (the default) or as one merged chronological timeline.

Get Activity Feed

GET /api/v1/activity/{object}/{id}

Returns the activity feed for a specific record.

Path Parameters

ParameterTypeDescription
objectstringThe object name (e.g. contacts, companies)
idUUIDThe record ID

Query Parameters

ParameterTypeDefaultDescription
viewstringsectionsResponse shape. sections returns three independently paginated sections. timeline merges all items into one chronological feed.
includestringinteractions,tasks,notesComma-separated list of sections to include. Accepted values: interactions, tasks, notes.
channelstring--Filter interactions by channel (e.g. email, meeting, linkedin, whatsapp). Only affects the interactions section.
cursorstring--Pagination cursor for the interactions section, taken from a previous response's next_cursor.
limitinteger20Number of items per section, or total items in the merged timeline (max 50).

Interactions are only tracked on contacts and companies. On any other object, the interactions section is returned with available: false and a reason, never a silently empty list.

Example Request

curl -X GET "https://kasar.app/api/v1/activity/contacts/550e8400-e29b-41d4-a716-446655440000?include=interactions,tasks,notes&channel=email&limit=10" \
  -H "Authorization: Bearer ksr_a1b2c3d4e5f6..."

Response (sections view)

The top level always includes a record reference. Each included section is an object with items, total, has_more, and (when more items remain) next_cursor:

{
  "record": {
    "object_name": "contacts",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "display": "Alice Martin"
  },
  "interactions": {
    "available": true,
    "items": [
      {
        "id": "a1b2c3d4-...",
        "channel": "email",
        "date": "2025-03-10T14:22:00Z",
        "direction": "inbound",
        "subject": "Follow-up on proposal",
        "preview": "Hi Alice, I wanted to circle back on the proposal we discussed…",
        "participants": null
      }
    ],
    "total": 34,
    "has_more": true,
    "next_cursor": "eyJvZmZzZXQiOjEwLCJsaW1pdCI6MTB9"
  },
  "tasks": {
    "items": [
      {
        "id": "e5f6a7b8-...",
        "title": "Send updated contract",
        "status": "open",
        "due_date": "2025-03-15",
        "priority": "urgent",
        "assignee": { "id": "b2c3d4e5-...", "display": "Bob Dupont" },
        "date": "2025-03-15"
      }
    ],
    "total": 5,
    "has_more": false
  },
  "notes": {
    "items": [
      {
        "id": "c3d4e5f6-...",
        "title": "Call recap",
        "preview": "Alice confirmed budget approval for Q2…",
        "author": { "id": "b2c3d4e5-...", "display": "Bob Dupont" },
        "date": "2025-03-09T11:05:00Z"
      }
    ],
    "total": 2,
    "has_more": false
  }
}

Sections that are not listed in the include parameter are omitted from the response entirely.

Section item shapes

Each section normalizes its rows into a compact shape:

  • interactionsid, channel, date, direction, subject, preview (plain-text snippet, max 200 chars), participants, thread_id (the conversation the message belongs to).
  • tasksid, title, status (open or done), due_date, priority, assignee ({ id, display } or null), date.
  • notesid, title, preview, author ({ id, display } or null), date.

When the interactions section is unavailable (object is not contacts or companies), it is returned as:

{
  "interactions": {
    "available": false,
    "reason": "Interactions are only tracked on contacts and companies.",
    "items": [],
    "total": 0,
    "has_more": false
  }
}

Response (timeline view)

With view=timeline, the three sources are merged into one chronologically descending timeline (capped at limit). Each entry carries a kind (interaction, task, or note) plus that type's normalized fields. Per-section totals are summarized in counts:

curl -X GET "https://kasar.app/api/v1/activity/contacts/550e8400-...?view=timeline&limit=20" \
  -H "Authorization: Bearer ksr_a1b2c3d4e5f6..."
{
  "record": {
    "object_name": "contacts",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "display": "Alice Martin"
  },
  "interactions_available": true,
  "counts": {
    "interactions": 34,
    "tasks": 5,
    "notes": 2
  },
  "timeline": [
    {
      "kind": "task",
      "id": "e5f6a7b8-...",
      "title": "Send updated contract",
      "status": "open",
      "due_date": "2025-03-15",
      "priority": "urgent",
      "assignee": { "id": "b2c3d4e5-...", "display": "Bob Dupont" },
      "date": "2025-03-15"
    },
    {
      "kind": "interaction",
      "id": "a1b2c3d4-...",
      "channel": "email",
      "date": "2025-03-10T14:22:00Z",
      "direction": "inbound",
      "subject": "Follow-up on proposal",
      "preview": "Hi Alice, I wanted to circle back on the proposal we discussed…",
      "participants": null
    }
  ],
  "has_more": true
}

In timeline view, interactions_available reflects whether the interactions source was usable for this object (omitted when interactions is not included). has_more is true if any underlying section still has more items.

Filtering by Channel

Use the channel parameter to narrow down interactions. This only affects the interactions section; tasks and notes are returned unfiltered.

curl -X GET "https://kasar.app/api/v1/activity/companies/99aabb00-...?include=interactions&channel=meeting" \
  -H "Authorization: Bearer ksr_a1b2c3d4e5f6..."

Pagination

In sections view, each section reports has_more and, when there are more items, a next_cursor. The interactions section's cursor can be passed back as the cursor query parameter to fetch the next page of interactions:

curl -X GET "https://kasar.app/api/v1/activity/contacts/550e8400-...?cursor=eyJvZmZzZXQiOjEwLCJsaW1pdCI6MTB9" \
  -H "Authorization: Bearer ksr_a1b2c3d4e5f6..."

When a section's has_more is false, you have reached its last page (and no next_cursor is present).

Error Responses

StatusCodeDescription
400MISSING_REQUIRED_FIELDThe object name or record ID was not provided
400INVALID_OBJECTThe object name does not exist (response includes available_values)
400RECORD_NOT_FOUNDNo visible record found with the given ID
401UNAUTHORIZEDInvalid or missing API token

On this page