Pull phishing campaign user behaviors
As a Company Admin you can list your organization’s phishing, smishing, or quishing campaigns and pull per-user behaviors for a campaign job: who opened, clicked, or submitted data, with timestamps. Use a credential with Client Role = Company Admin. Company context is automatic. Do not send X-KEEPNET-Company-Id. The same pattern applies to phishing, smishing, and quishing simulators — only the base path changes.
Request a Bearer token before any call: Quickstart → Request an access token.
POST /api/phishing-simulator/phishing-campaign/search
Returns a paginated list of phishing campaigns for your company.
Returns a list of the phishing campaigns. Test it: Authorize with Client ID/Secret, then Send — request body is pre-filled.
- : API
Client ID and Client Secret from Company → Company Settings → REST API. Enter credentials to auto-fetch token.
120CreateTimefalseOK
POST /api/phishing-simulator/phishing-campaign/search HTTP/1.1
Host: api.keepnetlabs.com
Authorization: Bearer YOUR_OAUTH2_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 126
{
"pageNumber": 1,
"pageSize": 20,
"orderBy": "CreateTime",
"ascending": false,
"filter": {
"Condition": "AND",
"SearchInputTextValue": ""
}
}OK
{
"data": {
"pageNumber": 1,
"pageSize": 1,
"totalNumberOfPages": 1,
"totalNumberOfRecords": 1,
"results": [
{
"resourceId": "text",
"name": "text",
"method": "text",
"methodDetail": "text",
"scenarioCount": "text",
"instanceCount": "text",
"targetUsers": "text",
"status": "text",
"instanceGroup": 1,
"hasTraining": true,
"jobResultMessage": "text",
"createdBy": "text",
"createTime": "2026-01-01T00:00:00.000Z",
"lastLaunch": "2026-01-01T00:00:00.000Z",
"emailDelivery": "text",
"frequency": 1,
"categoryDistributionType": "text"
}
]
},
"status": "text",
"message": "text",
"validationMessages": [
"text"
]
}Campaigns with Mark as Test (excludeFromReports: true) are excluded from dashboard and report statistics in the UI; they may still appear in API list responses. When aggregating metrics, filter or ignore items where excludeFromReports is true.
Smishing and quishing
Same flow with a different base path:
Smishing:
POST /api/smishing-simulator/smishing-campaign/searchQuishing:
POST /api/quishing-simulator/quishing-campaign/search
POST /api/phishing-simulator/phishing-campaign-job-report/search
Campaign jobs are run instances of a campaign. This endpoint returns jobs for reporting. From each result row, note phishingCampaignResourceId and instanceGroup for the summary and per-user searches below. For this endpoint, use orderBy: "Name" in the request body ("CreateTime" can return 400 Invalid request).
Retrieves campaign job's list. Test it: Authorize with Client ID/Secret, then Send — request body is pre-filled.
- : API
Client ID and Client Secret from Company → Company Settings → REST API. Enter credentials to auto-fetch token.
120NamefalseOK
POST /api/phishing-simulator/phishing-campaign-job-report/search HTTP/1.1
Host: api.keepnetlabs.com
Authorization: Bearer YOUR_OAUTH2_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 120
{
"pageNumber": 1,
"pageSize": 20,
"orderBy": "Name",
"ascending": false,
"filter": {
"Condition": "AND",
"SearchInputTextValue": ""
}
}OK
{
"data": {
"pageNumber": 1,
"pageSize": 1,
"totalNumberOfPages": 1,
"totalNumberOfRecords": 1,
"results": [
{
"phishingCampaignResourceId": "text",
"instanceGroup": 1,
"name": "text",
"startDate": "2026-01-01T00:00:00.000Z",
"totalOpenedCount": 1,
"totalClickedCount": 1,
"totalSubmittedCount": 1,
"totalAttachmentOpenedCount": 1,
"totalNoResponseCount": 1,
"totalTargetUserCount": 1,
"emailDeliveredUserCount": 1,
"method": "text",
"methodDetail": "text",
"status": "text",
"jobResultMessage": "text",
"createdBy": "text",
"createdDate": "2026-01-01T00:00:00.000Z",
"emailDelivery": "text",
"totalSubmittedMFACount": 1
}
]
},
"status": "text",
"message": "text",
"validationMessages": [
"text"
]
}From the response, pick a job and note phishingCampaignResourceId and instanceGroup. Example: "phishingCampaignResourceId": "xHJe83nmj0W7", "instanceGroup": 1 (use values from your response; dummy IDs in examples — H8d).
GET /api/phishing-simulator/phishing-campaign-job-report/summary/{resourceId}/{instanceGroup}
Returns aggregate metrics for one campaign job (sent, opened, clicked, submitted counts, and related summary fields). Path resourceId is the job row’s phishingCampaignResourceId (not a target-user ID).
Returns campaign job summary. Test it: Set path
resourceIdandinstanceGroupfrom the job search response.
- : API
Client ID and Client Secret from Company → Company Settings → REST API. Enter credentials to auto-fetch token.
OK
GET /api/phishing-simulator/phishing-campaign-job-report/summary/{resourceId}/{instanceGroup} HTTP/1.1
Host: api.keepnetlabs.com
Authorization: Bearer YOUR_OAUTH2_TOKEN
Accept: */*
OK
{
"data": {
"phishingCampaignResourceId": "text",
"phishingCampaignName": "text",
"campaignInfo": {
"startDate": "2026-01-01T00:00:00.000Z",
"endDate": "2026-01-01T00:00:00.000Z",
"scheduledDate": "2026-01-01T00:00:00.000Z",
"totalTargetUserCount": 1,
"emailDeliveredUserCount": 1,
"emailNotDeliveredUserCount": 1,
"emailDeliveryStartDate": "2026-01-01T00:00:00.000Z",
"emailDeliveryEndDate": "2026-01-01T00:00:00.000Z",
"frequency": 1,
"emailDeliveryDuration": "text",
"scheduleTypeId": 1,
"categoryDistributionType": "text",
"trackingReplyInfo": "text",
"sendUserPreferredLanguage": 1
},
"settings": {
"excludeFromReports": true,
"duration": 1,
"smtpName": "text",
"directEmailSettingName": "text"
},
"targetUsers": {
"randomlyUsersCount": 1,
"targetGroupsCount": 1,
"sendRandomlyUsers": true,
"sendOnlyActiveUsers": true
},
"scenarioStats": {
"openedEmail": 1,
"clickedEmail": 1,
"submittedEmail": 1,
"attachmentOpenedEmail": 1,
"reportedEmail": 1,
"noResponseEmail": 1,
"notDelivered": 1,
"failedToSend": 1,
"mfa": 1
},
"scenarios": [
{
"scenarioInfo": {
"name": "text",
"category": "text",
"methodTypeId": 1,
"difficultyTypeId": 1,
"languageShortCode": "text"
},
"trainingInfo": {
"trainingId": "text",
"trainingDescription": "text",
"name": "text",
"categoryName": "text",
"companyName": "text",
"languageList": [
{
"languageId": "text",
"languageShortCode": "text"
}
]
},
"enrollmentInfo": {
"enrollmentId": "text"
},
"emailTemplateInfo": {
"resourceId": "text",
"name": "text",
"categoryResourceId": "text",
"difficultyResourceId": "text",
"fromName": "text",
"fromAddress": "text",
"languageShortCode": "text",
"phishingFileName": "text",
"phishingFileType": "text",
"phishingFileUrl": "text",
"subject": "text",
"template": "text"
},
"emailTemplateInfos": [
{
"resourceId": "text",
"name": "text",
"categoryResourceId": "text",
"difficultyResourceId": "text",
"fromName": "text",
"fromAddress": "text",
"languageShortCode": "text",
"phishingFileName": "text",
"phishingFileType": "text",
"phishingFileUrl": "text",
"subject": "text",
"template": "text"
}
],
"landingPageTemplateInfo": {
"resourceId": "text",
"name": "text",
"methodTypeId": 1,
"difficultyTypeId": 1,
"urlTemplate": "text",
"languageShortCode": "text"
}
}
],
"scenariosGeneralInfo": {
"categories": [
"text"
],
"methodTypeId": 1,
"difficultyTypeIds": [
1
],
"languageShortCodes": [
"text"
]
},
"landingPageTemplateInfo": {
"resourceId": "text",
"name": "text",
"methodTypeId": 1,
"difficultyTypeId": 1,
"urlTemplate": "text",
"languageShortCode": "text"
},
"trainingInfoForCategory": {
"trainingId": "text",
"trainingDescription": "text",
"name": "text",
"categoryName": "text",
"companyName": "text",
"languageList": [
{
"languageId": "text",
"languageShortCode": "text"
}
]
},
"enrollmentInfoForCategory": {
"enrollmentId": "text"
},
"smartGroupInfo": {
"resourceId": "text",
"name": "text"
},
"campaignDurationExpired": true
},
"status": "text",
"message": "text",
"validationMessages": [
"text"
]
}Example: GET /api/phishing-simulator/phishing-campaign-job-report/summary/xHJe83nmj0W7/1
POST /api/phishing-simulator/phishing-campaign-job-report/{searchType}/search/{resourceId}/{instanceGroup}
Returns a paginated list of target users for the campaign job filtered by behavior. Path resourceId = phishingCampaignResourceId from the job search row; instanceGroup = instanceGroup from the same row.
Common searchType values: Opened, Clicked, All, NoResponse, Reported, AttachmentOpened, Replied. For submitted users, use All and read submittedCount / lastSubmittedTime; Submitted is not valid as searchType (400). Per-user field names are in Endpoints → PhishingCampaignJobReport.
Search Phishing Campaign Users. Test it: Set path parameters from the job search response; request body is pre-filled.
- : API
Client ID and Client Secret from Company → Company Settings → REST API. Enter credentials to auto-fetch token.
1100EmailfalseOK
POST /api/phishing-simulator/phishing-campaign-job-report/{searchType}/search/{resourceId}/{instanceGroup} HTTP/1.1
Host: api.keepnetlabs.com
Authorization: Bearer YOUR_OAUTH2_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 122
{
"pageNumber": 1,
"pageSize": 100,
"orderBy": "Email",
"ascending": false,
"filter": {
"Condition": "AND",
"SearchInputTextValue": ""
}
}OK
{
"data": {
"totalSandBoxActivityCount": 1,
"pageNumber": 1,
"pageSize": 1,
"totalNumberOfPages": 1,
"totalNumberOfRecords": 1,
"results": [
{
"resourceId": "text",
"firstName": "text",
"lastName": "text",
"email": "text",
"department": "text",
"phishingScenarioName": "text",
"phishingScenarioLanguage": "text",
"emailTemplateLanguage": "text",
"lastOpenedTime": "2026-01-01T00:00:00.000Z",
"lastOpenedTimeToLocalUser": "text",
"openedCount": 1,
"lastClickedTime": "2026-01-01T00:00:00.000Z",
"lastClickedTimeToLocalUser": "text",
"clickedCount": 1,
"lastSubmittedTime": "2026-01-01T00:00:00.000Z",
"lastSubmittedTimeToLocalUser": "text",
"submittedCount": 1,
"lastAttachmentOpenedTime": "2026-01-01T00:00:00.000Z",
"lastAttachmentOpenedTimeToLocalUser": "text",
"attachmentOpenedCount": 1,
"minPasswordComplexity": "text",
"status": "text",
"jobResultMessage": "text",
"lastSendingTime": "2026-01-01T00:00:00.000Z",
"lastSendingTimeToLocalUser": "text",
"reportedCount": 1,
"lastReportedTime": "2026-01-01T00:00:00.000Z",
"lastReportedTimeToLocalUser": "text",
"emailDelivery": "text",
"mfaSubmittedCount": 1,
"activityType": "text",
"systemActivityType": "text",
"mfaLastSubmittedTime": "2026-01-01T00:00:00.000Z",
"mfaLastSubmittedTimeToLocalUser": "text",
"replyType": "text",
"replySent": "2026-01-01T00:00:00.000Z",
"replySentToLocalUser": "text",
"isTrackingReplyContentEnabled": true,
"isTrackingReplyOutOfOfficeEnabled": true,
"preferredLanguage": "text",
"targetGroups": "text",
"targetUserId": 1,
"customFieldValues": [
{
"resourceId": "text",
"name": "text",
"dataType": "text",
"value": "text",
"timestampValue": "2026-01-01T00:00:00.000Z"
}
]
}
]
},
"status": "text",
"message": "text",
"validationMessages": [
"text"
]
}Example: POST /api/phishing-simulator/phishing-campaign-job-report/Opened/search/xHJe83nmj0W7/1. Paginate until pageNumber reaches totalNumberOfPages or results is empty. From a user row, note resourceId for the email detail endpoints below.
POST /api/phishing-simulator/phishing-campaign-job-report/search-email-opened/{resourceId}
Event-level opened detail for one target user. Path resourceId is the user’s resourceId from a user list row (Opened / Clicked / All search), not phishingCampaignResourceId.
Search Phishing Campaign User Email Opened. Test it: Set path
resourceIdfrom the user list; request body is pre-filled.
- : API
Client ID and Client Secret from Company → Company Settings → REST API. Enter credentials to auto-fetch token.
1100EmailfalseOK
POST /api/phishing-simulator/phishing-campaign-job-report/search-email-opened/{resourceId} HTTP/1.1
Host: api.keepnetlabs.com
Authorization: Bearer YOUR_OAUTH2_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 122
{
"pageNumber": 1,
"pageSize": 100,
"orderBy": "Email",
"ascending": false,
"filter": {
"Condition": "AND",
"SearchInputTextValue": ""
}
}OK
{
"data": {
"resourceId": "text",
"openedTime": "2026-01-01T00:00:00.000Z",
"sandBoxType": 1,
"systemSandBoxType": 1,
"activityType": "text",
"systemActivityType": "text",
"isChangedActivity": true,
"openedTimeToLocalUser": "text",
"browserName": "text",
"userAgent": "text",
"userGeolocation": "text",
"userIpAddressList": "text",
"isExcluded": true
},
"status": "text",
"message": "text",
"validationMessages": [
"text"
]
}POST /api/phishing-simulator/phishing-campaign-job-report/search-email-clicked/{resourceId}
Event-level clicked detail for the same user. Same path resourceId as the opened endpoint.
Search Phishing Campaign User Email Clicked. Test it: Set path
resourceIdfrom the user list; request body is pre-filled.
- : API
Client ID and Client Secret from Company → Company Settings → REST API. Enter credentials to auto-fetch token.
1100EmailfalseOK
POST /api/phishing-simulator/phishing-campaign-job-report/search-email-clicked/{resourceId} HTTP/1.1
Host: api.keepnetlabs.com
Authorization: Bearer YOUR_OAUTH2_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 122
{
"pageNumber": 1,
"pageSize": 100,
"orderBy": "Email",
"ascending": false,
"filter": {
"Condition": "AND",
"SearchInputTextValue": ""
}
}OK
{
"data": {
"resourceId": "text",
"clickedTime": "2026-01-01T00:00:00.000Z",
"sandBoxType": 1,
"systemSandBoxType": 1,
"activityType": "text",
"systemActivityType": "text",
"isChangedActivity": true,
"clickedTimeToLocalUser": "text",
"browserName": "text",
"userAgent": "text",
"userGeolocation": "text",
"userIpAddressList": "text",
"isExcluded": true
},
"status": "text",
"message": "text",
"validationMessages": [
"text"
]
}POST /api/phishing-simulator/phishing-campaign-job-report/search-email-submitted/{resourceId}
Event-level submitted detail for the same user. Same path resourceId as above. Using the campaign job ID here returns 404 (Phishing campaign instance user not found).
Search Phishing Campaign User Email Submitted. Test it: Set path
resourceIdfrom the user list; request body is pre-filled.
- : API
Client ID and Client Secret from Company → Company Settings → REST API. Enter credentials to auto-fetch token.
1100EmailfalseOK
POST /api/phishing-simulator/phishing-campaign-job-report/search-email-submitted/{resourceId} HTTP/1.1
Host: api.keepnetlabs.com
Authorization: Bearer YOUR_OAUTH2_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 122
{
"pageNumber": 1,
"pageSize": 100,
"orderBy": "Email",
"ascending": false,
"filter": {
"Condition": "AND",
"SearchInputTextValue": ""
}
}OK
{
"data": {
"submittedTime": "2026-01-01T00:00:00.000Z",
"submittedData": "text",
"submittedTimeToLocalUser": "text",
"browserName": "text",
"userAgent": "text",
"userGeolocation": "text",
"userIpAddressList": "text",
"isExcluded": true
},
"status": "text",
"message": "text",
"validationMessages": [
"text"
]
}Export
Export job report list:
POST /api/phishing-simulator/phishing-campaign-job-report/search/export— same body shape as job search (see Endpoints → PhishingCampaignJobReport). Response is CSV (binary), not JSON.Export per behavior list:
POST /api/phishing-simulator/phishing-campaign-job-report/{searchType}/search/export/{resourceId}/{instanceGroup}(for exampleOpenedwith the samephishingCampaignResourceIdandinstanceGroup).
Smishing and quishing have equivalent paths under smishing-simulator and quishing-simulator.
Common errors
403 Forbidden — Wrong Client Role or missing permission. Set Client Role = Company Admin in Company → Company Settings → REST API. Roles and permissions →
401 Unauthorized — Missing or invalid token. Request a new token via
POST /connect/token.400 Bad Request — Invalid search body. For
phishing-campaign-job-report/search, useorderBy:"Name"and a non-null filter (Condition,SearchInputTextValue:""). Do not sendfilter: null. Do not usesearchType=Submittedfor user behavior search.404 Not Found — Wrong path ID. Use
phishingCampaignResourceId+instanceGroupfor summary and{searchType}/search; use the user’sresourceIdforsearch-email-*endpoints.
Related: Quickstart →. Reseller: View customer's campaign list and report →. Endpoint details: Endpoints → PhishingCampaign, PhishingCampaignJobReport.
Last updated