Candidate List Events
Candidate List Events
Candidate list events tell you when a list is created, changed or deleted, and when candidates are added to or removed from it. They fire for every change, whether it was made through the Candidates API or by someone using Popp.
If you keep lists in sync with your own system, use these events with the /v1/candidates/lists endpoints. Every event carries the list's externalId and says whether the change came from the API or from a user, so you can skip the echo of your own writes.
Available Events
| Event | Description |
|---|---|
CANDIDATE_LIST_CREATED | A list was created |
CANDIDATE_LIST_UPDATED | A list's title, description, owner or externalId changed |
CANDIDATE_LIST_DELETED | A list was deleted |
CANDIDATE_LIST_MEMBERSHIP_UPDATED | Candidates were added to or removed from a list |
Who made the change: source
sourceEvery candidate list event carries source:
| Value | Meaning |
|---|---|
API | The change was made through the Candidates API with an API key |
USER | The change was made by someone using Popp |
source identifies the channel, not the caller. Every API key in your organization reports API, so if several of your systems call the API, compare the event with what you sent before you skip it.
Fields on every event
| Field | Type | Description |
|---|---|---|
recordId | string | The Popp id of the list |
organizationId | string | Your organization ID |
id | string | The Popp id of the list (same as recordId) |
externalId | string | null | Your own id for the list. Null when none is set |
title | string | The list's name |
description | string | null | The list's description |
userId | string | The Popp id of the user who owns the list |
owner | string | null | Email of the user who owns the list. Null when it can't be found, for example when that user no longer exists |
source | string | API or USER (see above) |
createdAt | string | When the list was created (ISO 8601) |
updatedAt | string | When the list was last updated (ISO 8601) |
CANDIDATE_LIST_CREATED
Sent when a list is created. A list created in Popp has no externalId yet. To link it to your own record, set one with PATCH /v1/candidates/lists/{id}, using the recordId from this event.
Payload
{
"event": "CANDIDATE_LIST_CREATED",
"eventId": "evt_abc123",
"eventTimestamp": "2026-10-06T10:00:00.000Z",
"data": {
"recordId": "list_abc123",
"organizationId": "org_123456",
"id": "list_abc123",
"externalId": null,
"title": "Senior engineers",
"description": null,
"userId": "user_789",
"owner": "[email protected]",
"source": "USER",
"candidateProfilesCount": 0,
"createdAt": "2026-10-06T10:00:00.000Z",
"updatedAt": "2026-10-06T10:00:00.000Z"
}
}candidateProfilesCount is the number of candidates on the list. It is also sent on CANDIDATE_LIST_UPDATED and CANDIDATE_LIST_DELETED.
CANDIDATE_LIST_UPDATED
Sent when a list's title, description, owner or externalId changes. The payload carries the list as it is after the change, with the same fields as CANDIDATE_LIST_CREATED.
Adding or removing candidates does not send this event. Those changes send CANDIDATE_LIST_MEMBERSHIP_UPDATED.
When you set or change a list's externalId through the API, this event carries the new value with source: "API".
CANDIDATE_LIST_DELETED
Sent when a list is deleted. The payload carries the list as it was before deletion, with the same fields as CANDIDATE_LIST_CREATED, so you can match it to your own record by externalId.
CANDIDATE_LIST_MEMBERSHIP_UPDATED
Sent when candidates are added to or removed from a list. One request sends one event, listing the candidates it changed.
Payload
{
"event": "CANDIDATE_LIST_MEMBERSHIP_UPDATED",
"eventId": "evt_def456",
"eventTimestamp": "2026-10-06T10:05:00.000Z",
"data": {
"recordId": "list_abc123",
"organizationId": "org_123456",
"id": "list_abc123",
"externalId": "your_list_id",
"title": "Senior engineers",
"description": null,
"userId": "user_789",
"owner": "[email protected]",
"source": "API",
"createdAt": "2026-10-06T10:00:00.000Z",
"updatedAt": "2026-10-06T10:00:00.000Z",
"candidatesAdded": ["candidate_1", "candidate_2"],
"candidatesRemoved": []
}
}Additional Fields
| Field | Type | Description |
|---|---|---|
candidatesAdded | string[] | Popp ids of the candidates added by this change |
candidatesRemoved | string[] | Popp ids of the candidates removed by this change |
Only candidates that actually changed are listed. A candidate already on the list is not reported as added, and one that was not on it is not reported as removed.
This event does not carry candidateProfilesCount. Membership changes can happen at the same time, so a count here could already be out of date. Use candidatesAdded and candidatesRemoved, or read the list with GET /v1/candidates/lists/{id}.
Updated about 6 hours ago
