Feedback requests¶
A feedback request is one request for a grade sent to one contact through a campaign. The API calls them appeals in its paths. These endpoints export the feedback requests of a campaign, create new ones from your systems, record grades and comments your own channel collected, and cancel requests that have not been sent yet.
Every feedback request has a type and a status:
| Type | Meaning |
|---|---|
sms |
Sent as an SMS message to phone. |
email |
Sent as an email to email. |
widget |
Collected by the feedback widget on your website. |
external |
Collected by your own channel and reported through this API, identified by identifier. |
| Status | Meaning |
|---|---|
Scheduled |
Waiting to be sent. The only status in which a request can be cancelled. |
Request |
Sent, waiting for a grade. |
Retry |
The request was repeated after no usable answer. |
Invalid |
The answer could not be read as a grade. |
Graded |
A grade was received. |
Comment request |
The customer was asked for a comment after grading. |
Commented |
A comment was received. |
Error |
Sending failed. |
Canceled |
Cancelled before sending. |
Survey request, Survey started, Survey completed |
The customer was asked to complete, started, or completed the follow-up survey. |
List feedback requests¶
GET /appeals/ exports the feedback requests of one campaign. Note the trailing slash.
GET https://app.instantfeedback.si/api/appeals/?campaign=17&date_from=2026-01-01&date_to=2026-01-31
| Parameter | Required | Format | Meaning |
|---|---|---|---|
campaign |
Yes | integer | Campaign ID. |
date_from |
No | YYYY-MM-DD |
Only feedback requests scheduled on or after this date. |
date_to |
No | YYYY-MM-DD |
Only feedback requests scheduled up to and including this date. |
changed_since |
No | YYYY-MM-DD |
Only feedback requests whose grade changed on or after this date. Use it to pick up grades that arrived since your last export. |
page |
No | integer | Page of results; see Responses and paging. |
Feedback requests deleted in the web app are not returned.
Example response:
{
"count": 65,
"next": null,
"previous": null,
"results": [{
"id": 1637,
"type": "sms",
"status": "Graded",
"phone": "+38641279757",
"text": "Thank you for your purchase! Rate your experience from 1 to 5.",
"date_created": "2026-01-03T15:34:10.442726+01:00",
"date_scheduled": "2026-01-03T16:12:10.442726+01:00",
"date_graded": "2026-01-04T16:39:10.442726+01:00",
"date_commented": null,
"grade": 4,
"comment": "",
"custom_fields": [{
"name": "Service type",
"value": "Development"
}]
}]
}
| Field | Meaning |
|---|---|
id |
Feedback request ID. |
type |
sms, email, widget, or external. |
status |
One of the statuses in the table above. |
phone |
Mobile number of the recipient. Only for type sms. |
email |
Email address of the recipient. Only for type email. |
identifier |
The identifier your system supplied. Only for type external. |
subject |
Email subject. Only for type email, and only when the request has its own subject. |
text |
Text of the feedback request that was sent. |
date_created |
When the feedback request was entered into the system. |
date_scheduled |
When the feedback request is, or was, sent. |
date_graded |
When the grade was received, or null. |
date_commented |
When the comment was received, or null. |
grade |
The grade received, or null. |
comment |
The comment received, or an empty string. |
custom_fields |
Values of the campaign's custom fields, one object per field with name and value. |
phone, email, identifier, and subject are left out of a record when they have no
value.
Get a feedback request¶
GET /appeals/:id returns one feedback request. It has the same fields as an entry of the
list, plus the campaign it belongs to.
GET https://app.instantfeedback.si/api/appeals/1637
{
"id": 1637,
"campaign": {
"id": 17,
"name": "Webshop – after order pickup"
},
"type": "sms",
"status": "Graded",
"phone": "+38641279757",
"text": "Thank you for your purchase! Rate your experience from 1 to 5.",
"date_created": "2026-01-03T15:34:10.442726+01:00",
"date_scheduled": "2026-01-03T16:12:10.442726+01:00",
"date_graded": "2026-01-04T16:39:10.442726+01:00",
"date_commented": null,
"grade": 4,
"comment": "",
"custom_fields": []
}
Create a feedback request¶
POST /appeals/create creates a feedback request in a campaign. Send the data as JSON in
the request body.
POST https://app.instantfeedback.si/api/appeals/create
{
"campaign": 17,
"phone": "+38641279757",
"date_scheduled": "2026-03-21T12:35:00+01:00",
"custom_fields": [{
"name": "Service type",
"value": "Development"
}]
}
| Parameter | Required | Format | Meaning |
|---|---|---|---|
campaign |
Yes | integer | Campaign ID. The campaign must be active. |
phone |
For SMS | string | Mobile number the request is sent to, in international format such as +38641279757. |
email |
For email | string | Email address the request is sent to. |
identifier |
For external | string | Your own identifier of the customer or transaction, up to 128 characters. |
text |
No | string | Text of the request. Defaults to the text defined on the campaign. |
subject |
No | string | Email subject. Defaults to the subject defined on the campaign. Email only. |
date_scheduled |
No | ISO 8601 | When to send the request, for example 2026-03-21T12:35:00+01:00 or 2026-03-21 12:35. Defaults to now. Without a UTC offset, the time is read in the account's time zone. |
grade |
No | integer | A grade your channel already collected. External campaigns only; must be a grade of the campaign's scale. |
comment |
No | string | A comment your channel already collected. External campaigns only, and only together with grade. |
custom_fields |
When the campaign has a required custom field | list | One object per custom field, with the field's name as defined on the campaign and its value. |
The type of the new feedback request follows the campaign's channel:
- SMS campaigns need
phone, email campaigns needemail. - SMS and email campaigns take either: the request is sent as an SMS when you send
phone, and as an email when you sendemail. - Web campaigns need no contact. The response contains the iframe code of the feedback widget for this request, so a grade given in that widget lands on this request.
- External campaigns need
identifier. The response contains the campaign's texts, so your channel can show them to the customer; report the answer with Record a grade and Record a comment.
Custom field values are checked against the field type: a Choice field accepts one of its
choices, a Text field a string, other types a value in the field's format. Fields marked
as required on the campaign must be present and not empty.
On success the response is HTTP 201 with the feedback request, in the same shape as
Get a feedback request. Two campaign channels add a field:
"widget": {
"iframe": "<iframe id=\"pskwidget-24\" class=\"pskwidgetframe\" width=\"100%\" height=\"400\" src=\"https://app.instantfeedback.si/widgets/feedback/...\" frameBorder=\"0\" scrolling=\"no\"></iframe>"
}
"texts": {
"initial": "How satisfied were you with our service? Rate it from 1 to 5.",
"replies": {
"1": "We are sorry to hear that. What went wrong?",
"5": "Thank you! What did you like most?"
},
"final": "Thank you for your feedback.",
"instructions": null,
"disclaimer": null
}
| Field | Meaning |
|---|---|
widget.iframe |
Web campaigns: the HTML of an iframe that shows the feedback widget for this request. |
texts.initial |
External campaigns: the text of the feedback request to show the customer. |
texts.replies |
The reply to show after each grade, keyed by grade. |
texts.final |
The text to show after the comment, or null. |
texts.instructions, texts.disclaimer |
The campaign's instructions and disclaimer texts, or null. |
A request that InstantFeedback refuses to create returns HTTP 400 with the reason in
detail:
detail |
Meaning |
|---|---|
| Recipient is blacklisted. | The number or address is on the blacklist. |
| Recipient is graylisted. | The campaign uses the graylist and the contact is on it. |
| Scheduled time is outside the allowed interval (08:00 - 20:00). | date_scheduled falls outside the campaign's sending hours. |
| A message to ... has already been sent or is pending for ..., so no further messages can be sent on that date. | The contact already has an SMS on that date, or an email in a campaign that does not allow several emails per day. |
| A grace period applies because ... | The campaign's grace period blocks another request to this contact within the configured number of days. |
| Monthly response cap exceeded for account. and similar | The account's or campaign's daily or monthly cap on feedback requests is reached. |
| Rejected by inbound rules: ... | The campaign has Enable inbound rules for REST API switched on, and a custom field value did not pass the rules. |
| Either 'phone' or 'email' is required for SMS + Email campaigns. | A request for an SMS and email campaign has neither. |
Errors in custom field values come back under custom_fields, one object per field with
name and detail, for example Field does not exist., Field is required., Value can
not be empty., or 'X' is not a valid value. Choices are: Development, Support..
Record a grade¶
POST /appeals/:id/grade records a grade on a feedback request that is waiting for one,
that is in the Request status. Use it when your own channel collected the grade, typically
in an external campaign.
POST https://app.instantfeedback.si/api/appeals/1802/grade
{
"grade": 4,
"date_graded": "2026-03-21T13:02:00+01:00"
}
| Parameter | Required | Format | Meaning |
|---|---|---|---|
grade |
Yes | integer | A grade of the campaign's scale. |
date_graded |
No | ISO 8601 | When the grade was given. Defaults to now and cannot be in the future. |
InstantFeedback processes the grade like one received through its own channels, so
notifications and integrations fire as usual. The response is HTTP 200:
{
"id": 1802,
"status": "Graded",
"grade": 4,
"date_graded": "2026-03-21T13:02:00+01:00",
"texts": {
"reply": "Thank you! What did you like most?",
"final": "Thank you for your feedback."
}
}
texts.reply is the campaign's reply for this grade, with variables filled in, and
texts.final the final text or null. Show them to the customer when your channel
handles the conversation.
| Error | Meaning |
|---|---|
{"detail": "This operation is only allowed for feedback requests with status 'Request'."} |
The request has not been sent yet, or already has a grade. |
{"grade": ["Grade '99' is outside the range defined by campaign scale 'CSAT'."]} |
The grade is not on the campaign's scale. |
{"date_graded": ["Date cannot be later than the current date."]} |
date_graded is in the future. |
Record a comment¶
POST /appeals/:id/comment records a comment on a graded feedback request. It is allowed in
the Comment request and Commented statuses; for external feedback requests also in the
Graded status. A second comment is appended to the first on a new line.
POST https://app.instantfeedback.si/api/appeals/1802/comment
{
"comment": "Fast delivery, friendly courier."
}
| Parameter | Required | Format | Meaning |
|---|---|---|---|
comment |
Yes | string | The comment. Must not be empty. |
date_commented |
No | ISO 8601 | When the comment was given. Defaults to now and cannot be in the future. |
The response is HTTP 200:
{
"id": 1802,
"status": "Commented",
"comment": "Fast delivery, friendly courier.",
"date_commented": "2026-03-21T13:04:12.310021+01:00",
"texts": {
"final": "Thank you for your feedback."
}
}
Cancel a feedback request¶
POST /appeals/:id/cancel cancels the sending of one feedback request. This is only
possible while the status is Scheduled.
POST https://app.instantfeedback.si/api/appeals/1802/cancel
The response is HTTP 200 with the new status:
{
"id": 1802,
"status": "Canceled"
}
A request that is no longer scheduled returns HTTP 400:
{"detail": "This operation is only allowed for feedback requests with status 'Scheduled'."}
Troubleshooting¶
| Message or symptom | What to do |
|---|---|
| Parameter "campaign" is required. | GET /appeals/ needs ?campaign=<id> in the URL. |
HTTP 301 from GET /appeals |
Add the trailing slash: /appeals/. |
HTTP 403 You do not have permission to perform this action. |
The campaign or feedback request belongs to another account, or the campaign is not active. Check the ID and the campaign's status in the web app. |
HTTP 415 Unsupported media type |
Send the body as JSON with the Content-Type: application/json header. |
This field is required. for phone or email |
The campaign's channel needs that contact field. For SMS and email campaigns send one of the two. |
| An export returns fewer records than expected. | A page holds at most 1000 records. Follow the next URL until it is null. Deleted feedback requests are never returned. |
| A grade recorded through the API does not appear. | Grades can only be recorded in the Request status. Check the current status with GET /appeals/:id. |