Skip to content

Interactions ​

← Workspace APIs

Interactions are the calls, meetings and emails logged against people and organizations. Paging, updated_since and /ids work as described in Paging and Keeping a copy in sync, except where this page says otherwise.

An interaction can name thousands of people, for example one bulk email. So the people on an interaction and the organizations it is about are separate lists: /interaction-participants and /interaction-organizations. The note or email body is a separate call, GET /interactions/{id}/body.

Interactions ​

Most emails are logged by Engagifii itself when it sends a message. Those have no sender and no logged_by_person_id, and Engagifii shows them as "Notification" (is_notification: true). A scheduled email appears only once it has been sent.

EndpointMeaning
GET /interactionsList interactions, one page at a time.
GET /interactions/idsThe id of every interaction.
GET /interactions/{id}One interaction. 404 if it does not exist or has been deleted.
GET /interactions/{id}/bodyThe note or email body of one interaction. See below.

Filters ​

ParameterTypeMeaning
typestringcall, email or meeting.

Example ​

json
{
  "id": "7b3e…",
  "type": "meeting",
  "title": "Quarterly check-in",
  "occurred_at": "2026-10-14T15:00:00Z",
  "logged_by_person_id": "51ad…",
  "is_notification": null,
  "is_scheduled_email": null,
  "from_person_id": null,
  "recipient_count": null,
  "participant_person_ids": ["3f0c…", "51ad…"],
  "duration_minutes": 45,
  "interaction_type": { "id": "2c91…", "label": "Member visit" },
  "outcome": { "id": "8f04…", "label": "Follow-up needed" },
  "organization_count": 1,
  "attachments": [
    { "file_name": "Meeting notes.pdf" }
  ],
  "created_at": "2026-10-14T16:02:18Z",
  "updated_at": "2026-10-14T16:02:18Z"
}

An email looks like this:

json
{
  "id": "a40d…",
  "type": "email",
  "title": "Your 2027 membership renewal",
  "occurred_at": "2026-11-02T13:30:05Z",
  "logged_by_person_id": null,
  "is_notification": true,
  "is_scheduled_email": false,
  "from_person_id": null,
  "recipient_count": 1250,
  "participant_person_ids": null,
  "duration_minutes": null,
  "interaction_type": null,
  "outcome": null,
  "organization_count": 310,
  "attachments": [],
  "created_at": "2026-11-02T13:30:05Z",
  "updated_at": "2026-11-02T13:30:05Z"
}

Fields ​

FieldTypeMeaning
idUUIDThe interaction's id.
typestringcall, email, meeting, or other for any other kind.
titlestring or nullThe call or meeting title, or the email subject. Returned as stored; it can contain HTML, so never render it unescaped.
occurred_atdate-time or nullFor calls and meetings, the date and time entered. For emails, when the email was sent.
logged_by_person_idUUID or nullThe person who logged the interaction. An id from /people. null when Engagifii logged it itself.
is_notificationboolean or nullEmails only: true when Engagifii sent the email without a sender. null for calls and meetings.
is_scheduled_emailboolean or nullEmails only: true when the email was scheduled to send later. null for calls and meetings.
from_person_idUUID or nullEmails only: the sender. null for notifications, calls and meetings.
recipient_countinteger or nullEmails only: the number of To, Cc and Bcc recipients. List them with /interaction-participants?interaction_id=…. null for calls and meetings.
participant_person_idsarray of UUIDs or nullCalls and meetings only: the people who took part. null for emails.
duration_minutesinteger or nullCalls and meetings only: how long it lasted. null for emails and when none is entered.
interaction_typeobject or nullThe workspace's own type for the call or meeting. null if none is set.
interaction_type.idUUIDThe type's id.
interaction_type.labelstring or nullThe type's name, for example Member visit.
outcomeobject or nullThe workspace's own outcome for the call or meeting. null if none is set.
outcome.idUUIDThe outcome's id.
outcome.labelstring or nullThe outcome's name.
organization_countintegerThe number of organizations the interaction is about. List them with /interaction-organizations?interaction_id=….
attachmentsarrayFiles attached to the interaction. Only the names are returned, not the files.
attachments[].file_namestringThe attachment's file name.
created_atdate-timeWhen the interaction was logged.
updated_atdate-timeWhen the interaction was last edited, or logged if it was never edited.

GET /interactions/{id}/body ​

Returns the note of a call or meeting, or the body of an email.

json
{
  "data": {
    "interaction_id": "a40d…",
    "content_type": "text/html",
    "body": "<p>Dear member,</p><p>Your membership renews on 1 January 2027.</p>"
  }
}
FieldTypeMeaning
interaction_idUUIDThe interaction.
content_typestringAlways text/html.
bodystringThe body, exactly as Engagifii stores it, usually HTML. It is not sanitised: never render it unescaped.
  • This endpoint has its own rate limit of 600 requests per minute per integration, separate from the 120 per minute of every other endpoint, so a first full sync can read one body per interaction.
  • 404 when the interaction does not exist or has no body stored.
  • 503 with Retry-After when the body could not be read. Retry after that many seconds.
  • 503 with the detail "Interaction bodies are not available yet." and no Retry-After while Engagifii has not yet turned bodies on for the API. Try again on a later sync.
  • A body changes only when its interaction is edited. Read it for new interactions and whenever an interaction's updated_at moves.

Keeping interactions in sync ​

  • Engagifii deletes interactions outright and records no deletion, so a deleted interaction never comes back in the deleted short form. Compare ids with /interactions/ids to find them, and remove their participant and organization rows too.
  • An edit replaces an interaction's participants and organizations with new rows that have new ids. When an interaction's updated_at moves, read its rows again with ?interaction_id=… and replace the ones you hold.

Interaction participants ​

One row per person on an interaction: the email's sender and its To, Cc and Bcc recipients, or a call or meeting participant.

EndpointMeaning
GET /interaction-participantsList participant rows, one page at a time.

There is no /interaction-participants/ids and no /interaction-participants/{id}.

Parameters ​

ParameterTypeMeaning
page_sizeintegerRows per page. Default 100, maximum 5000.
cursorUUIDThe next_cursor from the previous page, passed back unchanged.
interaction_idUUIDOnly rows of this interaction.
person_idUUIDOnly rows for this person.
updated_sincedate or date-timeOnly rows of interactions logged or edited at or after this time. Same format as on other lists.

Example ​

json
{
  "data": [
    { "id": "0c11…", "interaction_id": "a40d…", "person_id": "3f0c…", "role": "to" },
    { "id": "0c12…", "interaction_id": "7b3e…", "person_id": "51ad…", "role": "participant" }
  ],
  "next_cursor": "0c12…"
}

Fields ​

FieldTypeMeaning
idUUIDThe row's id. A new id is given each time the interaction is edited.
interaction_idUUIDThe interaction. An id from /interactions.
person_idUUID or nullThe person. An id from /people. null for an email recipient Engagifii could not match to a person.
rolestringFor emails: from, to, cc or bcc. For calls and meetings: participant. other for anything else.

Interaction organizations ​

One row per organization an interaction is about. For emails, Engagifii fills these from the recipients' primary organizations.

EndpointMeaning
GET /interaction-organizationsList organization rows, one page at a time.

There is no /interaction-organizations/ids and no /interaction-organizations/{id}.

Parameters ​

The same as interaction participants, with organization_id (UUID, only rows for this organization) in place of person_id.

Example ​

json
{
  "data": [
    { "id": "5e70…", "interaction_id": "a40d…", "organization_id": "9b21…" }
  ],
  "next_cursor": null
}

Fields ​

FieldTypeMeaning
idUUIDThe row's id. A new id is given each time the interaction is edited.
interaction_idUUIDThe interaction. An id from /interactions.
organization_idUUID or nullThe organization. An id from /organizations.

Paging and sync for participant and organization rows ​

These two lists work differently from the others:

  • Rows are in a fixed order by id, not by change time. next_cursor is the last row's id. Pass it back as cursor until it is null.
  • page_size goes up to 5000, because each row is small.
  • Rows have no change time of their own and no updated_at. updated_since selects the rows of interactions logged or edited since that time.
  • Rows are never returned in the deleted short form. An edit replaces an interaction's rows with new ones, and a deleted interaction's rows disappear.

To keep a copy: on the first load, page through both lists in full. After that, for each interaction that comes back from /interactions?updated_since=…, fetch its rows with ?interaction_id=… and replace the rows you hold for it. When /interactions/ids shows an interaction is gone, delete its rows.