For AI agents: markdown of this page — /docs-content-en/performan/self-reviews.md documentation index — /llms.txt
Self-review cards
GET /v1/performan/review/self-reviews
Returns the self-review cards of a campaign that are available to the key owner. The campaign id parameter is required, and the listing is cursor based.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaignId (query) |
number | yes | — | Campaign id. The campaign list — GET /v1/performan/review/campaigns |
limit (query) |
number | no | 50 | Records per page, 200 at most |
afterCursorId (query) |
number | no | — | The next-page cursor. The value comes from meta.nextCursor.id of the previous response. The first request omits it |
Examples
curl — personal key
curl "https://vibecode.bitrix24.com/v1/performan/review/self-reviews?campaignId=1&limit=20" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl "https://vibecode.bitrix24.com/v1/performan/review/self-reviews?campaignId=1&limit=20" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/performan/review/self-reviews?campaignId=1&limit=20', {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const body = await res.json()
if (!body.success) {
throw new Error(`${body.error.code}: ${body.error.message}`)
}
for (const card of body.data) {
// An unfilled card has an empty answers array and a rate of zero
console.log(card.id, card.status, card.rate, card.answers.length)
}
console.log(body.meta.nextCursor)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/performan/review/self-reviews?campaignId=1&limit=20', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const body = await res.json()
if (!body.success) {
throw new Error(`${body.error.code}: ${body.error.message}`)
}
console.log(body.data, body.meta.nextCursor)
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data |
array | The self-review card array |
data[].id |
number | Card id |
data[].campaignId |
number | The card's campaign. The list — GET /v1/performan/review/campaigns |
data[].campaignStageId |
number | The campaign stage the card belongs to |
data[].stageType |
string | Stage type. For this method — selfReview |
data[].revieweeUserId |
number | The employee being reviewed. Employee card — GET /v1/users/:id |
data[].revieweeUserName |
string | Name of the employee being reviewed |
data[].managerUserId |
number | The reviewee's manager. Employee card — GET /v1/users/:id |
data[].managerUserName |
string | Manager name |
data[].status |
string | Card state: new — not filled, completed — finished, rejected — rejected, published — published |
data[].rate |
number | The final rate from the rating question. 0 — no rate set |
data[].comment |
string | Card comment |
data[].answers |
array | Answers to the stage questions. On an unfilled card the array is empty |
data[].answers[].questionId |
number | Question id |
data[].answers[].questionTitle |
string | Question wording |
data[].answers[].questionDescription |
string | Question note |
data[].answers[].questionType |
string | Question type as a string: 1 — single choice, 2 — multiple choice, 3 — text answer |
data[].answers[].questionTypeLabel |
string | Question type name in the portal language |
data[].answers[].isRating |
boolean | Whether the answer forms the card's final rate |
data[].answers[].answerText |
string | Answer text. Empty for a choice question |
data[].answers[].selectedOptions |
array | The chosen options. Empty for a text question |
data[].answers[].selectedOptions[].id |
number | Option id |
data[].answers[].selectedOptions[].text |
string | Option text |
data[].answers[].selectedOptions[].value |
number | Numeric option value, rate is computed from it |
data[].ratingScale |
array | The rating scale of the stage |
data[].ratingScale[].value |
number | Scale value |
data[].ratingScale[].label |
string | Value caption |
meta.nextCursor |
object | null | The next-page cursor. null — no more records |
meta.nextCursor.id |
number | The value for the afterCursorId parameter of the next request |
Response example
{
"success": true,
"data": [
{
"id": 1,
"campaignId": 1,
"campaignStageId": 3,
"stageType": "selfReview",
"revieweeUserId": 42,
"revieweeUserName": "Mary Jones",
"managerUserId": 7,
"managerUserName": "John Smith",
"status": "new",
"rate": 0,
"comment": "",
"answers": [],
"ratingScale": [
{ "value": 1, "label": "Well below expectations" },
{ "value": 2, "label": "Below expectations" },
{ "value": 3, "label": "Meets expectations" },
{ "value": 4, "label": "Above expectations" },
{ "value": 5, "label": "Well above expectations" }
]
}
],
"meta": { "nextCursor": null }
}
Error response example
400 — a required parameter was not sent:
{
"success": false,
"error": {
"code": "INVALID_PARAMS",
"message": "campaignId is required and must be a positive integer"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_PARAMS |
campaignId was not sent, or the value of campaignId or afterCursorId is not a positive integer, or limit is outside the 1–200 range |
| 401 | MISSING_API_KEY |
The X-Api-Key header was not sent |
| 401 | TOKEN_MISSING |
The key has no portal tokens. An OAuth application key requires the Authorization: Bearer header |
| 403 | SCOPE_DENIED |
The key has no performan scope |
| 404 | ROUTE_NOT_FOUND |
The Performance Review section is not enabled for the account. The answer is indistinguishable from the answer to any address that does not exist |
| 404 | ENTITY_NOT_FOUND |
The section is enabled, but the account has no Performance Review module: Bitrix24 answers that the performan.review.* method was not found |
| 409 | PERFORMAN_SCOPE_JUST_GRANTED |
A Cowork key was granted the performan scope by this very request. Repeat it and it goes through |
| 403 | BITRIX_ACCESS_DENIED |
Bitrix24 denied access. The permissions the key uses to reach the portal do not include performan |
| 422 | BITRIX_ERROR |
Bitrix24 rejected the request. The cause is in error.message, the machine code from Bitrix24 in error.b24Code |
| 429 | RATE_LIMITED |
The request rate on the Bitrix24 side was exceeded |
| 429 | QUEUE_OVERFLOW, QUEUE_TIMEOUT |
The portal request queue is full or the request did not get through the queue in time. The Retry-After header suggests the delay |
| 503 | BITRIX_TIMEOUT |
Bitrix24 accepted the request but did not answer in time. A read is safe to retry |
| 502 | BITRIX_UNAVAILABLE |
Bitrix24 is unavailable |
The full list of common API errors — Errors.
Known specifics
The listing is limited to the key owner. The method returns this employee's self-review cards, not those of every campaign member. An empty data array means the employee has no self-review card in this campaign. An account administrator gets the same slice.
A campaign that does not exist answers with an empty page. A campaign id unavailable to the key owner gives 200 with an empty data, not a refusal. To tell one from the other, check against the campaign list.
A limit outside the 1–200 range is refused. The answer is 400 INVALID_PARAMS and the request never reaches Bitrix24; ask for a page of 200 records with an explicit limit=200.