Skip to content

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 need email.
  • SMS and email campaigns take either: the request is sent as an SMS when you send phone, and as an email when you send email.
  • 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.