Manage employees (the target colleagues of your simulations) from your own systems: payroll, HRIS, sync scripts, etc.
Create, update, query, and delete employees without going through the Whalemate interface.
Query the campaign event history of an employee (opens, clicks, reports, compromised credentials, etc.).
Base URL:
All endpoints are under the prefix {{base_url}}/api/companies/v1.
To get the production host (
base_url), contact your Whalemate representative or write to us through the support chat.
Authentication:
The API uses API Key authentication through the X-API-KEY header.
X-API-KEY: tu_api_key_de_empresa
You can generate or check your key from Configuración → Integraciones → card Claves API → Claves Activas. The details are in API Keys: how to generate, use, and revoke them.
The company is resolved automatically from the API Key: you don't send company_id in the body or the URL, and each request operates only on your company's victims.
Required headers:
Header | Value | Required |
|---|---|---|
| Your company API Key | ✅ Yes |
|
| ✅ Yes (on |
|
| ✅ Yes |
GET {{base_url}}/api/companies/v1/victims
Param | Type | Default | Description |
|---|---|---|---|
| integer |
| Number of results per page |
| string | - | Filters by first name (partial match) |
| string | - | Filters by last name (partial) |
| string | - | Filters by email (partial) |
| string | - | Filters by department (partial) |
| string | - | Filters by country (partial) |
| string | - | Filters by position (partial) |
| string |
|
|
Example:
GET {{base_url}}/api/companies/v1/victims?filter[country]=Brazil
{
"data": [
{
"id": 12,
"email": "[email protected]",
"first_name": "Juan",
"last_name": "Pérez",
"department": "Finanzas",
"position": "Analista",
"country": "Argentina",
"personal_id": "30123456",
"active": true,
"booster": "normal",
"groups": [
{ "id": 4, "name": "Finanzas", "type": "custom" }
]
}
],
"links": { "first": "...", "last": "...", "prev": null, "next": "..." },
"meta": { "current_page": 1, "per_page": 20, "total": 134, "last_page": 7 }
}GET {{base_url}}/api/companies/v1/victims/{id}
Same object as in the list, without the data wrapper. Returns 404 if the id does not exist or does not belong to your company.
POST {{base_url}}/api/companies/v1/victims
Field | Type | Required | Description |
|---|---|---|---|
| string | ✅ | Unique email of the employee |
| string | ✅ | First name |
| string | ✅ | Last name |
| string | ✅ | Country |
| string | ✅ | One of |
| string | ✅ | Position |
| string | ✅ | Department |
| string | ✅ | One of |
| string | ❌ | Phone number with country code, with |
| string | ❌ | Personal identifier (DNI, employee ID, etc.) |
Contract change (1-oct-2026): until that date
phone_numberaccepted any text. From today, if you send it without a country code, the API responds422. Check your integrations that load local phone numbers (for example, 10 digits) and add the country code before sending them.
POST {{base_url}}/api/companies/v1/victims
X-API-KEY: tu_api_key_de_empresa
{
"email": "[email protected]",
"first_name": "Ana",
"last_name": "Gómez",
"country": "Argentina",
"language": "es",
"position": "Contadora",
"department": "Finanzas",
"phone_number": "+5491122334455",
"personal_id": "28999111",
"booster": "high"
}Successful response (201 Created): the object of the created victim, with the same shape as in View a victim.
PUT {{base_url}}/api/companies/v1/victims/{id}
Accepts the same fields as Create an employee. email, first_name, last_name, country, language, position, department and booster are required; phone_number and personal_id are optional. The email must remain unique, ignoring the employee itself.
Contract change (1-oct-2026): until that date
phone_numberaccepted any text. From today, if you send it without a country code, the API responds422. Check your integrations that load local phone numbers (for example, 10 digits) and add the country code before sending them.
Response (200 OK): the updated object.
DELETE {{base_url}}/api/companies/v1/victims/{id}
Response (204 No Content): no body. The employee is left as inactive (soft delete) and no longer appears in the default list (filter[status]=active).
GET {{base_url}}/api/companies/v1/victims/{id}/events
Returns the campaign event history of the employee, sorted by date descending.
Flat array (no pagination):
[
{
"id": 501,
"date_time": "2026-05-12 09:31:00",
"type": "Clicked Link",
"campaign_name": "Campaña Q2 - Phishing bancario",
"campaign_id": 33
}
]Possible event types: Email Sent, Failed, Clicked Link, Email Reported, Email Opened, Credential Harvesting, File Open, Download, Reported, Impersonated.
404 Not Found if the victim does not exist or does not belong to your company.
Code | Cause | Body |
|---|---|---|
| Missing |
|
| API Key does not exist or was revoked |
|
| The resource does not exist or belongs to another company | - |
| Validation error (duplicate email, missing field, value outside enum, invalid phone number…) |
|
|
| same format; the message says the country code is missing and gives the example |
|
| same format; the message says the number is not valid for the country it declares |
| License quota exhausted (Create only) |
|
curl -X POST https://api.whalemate.io/api/companies/v1/victims \
-H "X-API-KEY: tu_api_key_aqui" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"email": "[email protected]",
"first_name": "Ana",
"last_name": "Gómez",
"country": "Argentina",
"language": "es",
"position": "Contadora",
"department": "Finanzas",
"booster": "high"
}'Where do I get my API Key?
In Configuración → Integraciones → card Claves API → Claves Activas. There they are generated, listed, and revoked.
What happens if I delete a victim by mistake?
The deletion is logical (soft delete): the victim becomes inactive but is not lost. You can list it again with filter[status]=inactive or all, and create or activate it again depending on your flow.
Can I create victims in bulk (batch)?
The current endpoint processes one victim per request. If bulk registration is a priority for your organization, you can request it at roadmap.whalemate.com/roadmap.
How do I assign a victim to a group from the API?
This endpoint does not manage groups directly; the groups field in the response is read-only. Group assignment is done from the platform or through the sync integrations (Google/Microsoft/Okta).
What does the field booster mean?
It is the level of exposure and attention the victim receives in simulations (low, normal, high, critical). It affects the frequency and difficulty of the campaigns that reach them.
I get a 422 when creating an employee with a phone number, and it used to work.
Check that phone_number starts with + or 00 and has the country code. Since 1-oct-2026 a local number without a country code is rejected.
Can I send the phone number with spaces or hyphens?
Yes, they are removed and the number is saved without those symbols.
Do you have feedback or want to request improvements? Let us know at roadmap.whalemate.com/roadmap