Collect in-app feedback, bug reports, and feature requests from your mobile and web apps — with device context and log traces included automatically.
The feedback endpoint creates a support ticket enriched with device information. Your agents see the device model, OS version, app version, and any log traces right in the ticket sidebar — no back-and-forth asking users for details.
/api/v1/feedback/Server or Client keySubmit feedback or a bug report with device context. Creates a ticket with channel set to "mobile" and device info in metadata.
| Name | Type | Description |
|---|---|---|
subject* | string | Short summary of the feedback or bug (max 500 chars) |
user_email | string | Email of the end user. If omitted, an anonymous user is created. |
description | string | Detailed description or reproduction steps |
user_first_name | string | First name (used if user is created) |
user_last_name | string | Last name (used if user is created) |
type | string | bug, feedback (default), or question — auto-tags the ticket |
priority | string | low, normal (default), high, or urgent |
device | object | Device context — see fields below |
logs | string | Plain-text log trace (max 500 KB). Stored as an attached .log file. |
metadata | object | Any extra data (screen name, session ID, feature flags, etc.) |
| Name | Type | Description |
|---|---|---|
os | string | Operating system (e.g. iOS, Android) |
os_version | string | OS version (e.g. 17.4, 14) |
app_version | string | Your app version (e.g. 2.1.0) |
app_build | string | Build number (e.g. 145) |
device_model | string | Device model (e.g. iPhone 15 Pro, Pixel 8) |
locale | string | User locale (e.g. en_US) |
timezone | string | Timezone (e.g. America/New_York) |
screen_resolution | string | Screen size (e.g. 1179x2556) |
curl -X POST https://api.bancrofthq.com/api/v1/feedback/ \ -H "X-API-Key: bnc_cl_your_client_key" \ -H "Content-Type: application/json" \ -d '{ "subject": "App crashes when opening settings", "description": "Tapping the gear icon causes a freeze then crash", "user_email": "jane@example.com", "user_first_name": "Jane", "type": "bug", "priority": "high", "device": { "os": "iOS", "os_version": "17.4", "app_version": "2.1.0", "app_build": "145", "device_model": "iPhone 15 Pro", "locale": "en_US", "timezone": "America/New_York" }, "logs": "2024-03-01 12:00:01 [INFO] SettingsVC viewDidLoad\n2024-03-01 12:00:02 [ERROR] CoreData fetch failed", "metadata": { "screen": "settings", "session_id": "abc-123" } }'
// Response 201 { "id": "a1b2c3d4-...", "number": 47, "subject": "App crashes when opening settings", "status": "open", "priority": "high", "channel": "mobile", "metadata": { "device": { "os": "iOS", "os_version": "17.4", "app_version": "2.1.0", "device_model": "iPhone 15 Pro" }, "feedback_type": "bug", "screen": "settings", "session_id": "abc-123" }, "requester": { "email": "jane@example.com", "first_name": "Jane", "last_name": "" }, "created_at": "2026-03-02T10:00:00Z", "updated_at": "2026-03-02T10:00:00Z" }
/api/v1/feedback/{id}/attachments/Server or Client keyUpload a screenshot or file to a feedback report. Accepts multipart form data.
| Name | Type | Description |
|---|---|---|
file* | file | The file to upload. Accepted types: images (PNG, JPG, GIF, WebP), PDF, text, CSV, ZIP. |
curl -X POST https://api.bancrofthq.com/api/v1/feedback/a1b2c3d4-.../attachments/ \ -H "X-API-Key: bnc_cl_your_client_key" \ -F "file=@screenshot.png"
// Response 201 { "id": "att-uuid-...", "filename": "screenshot.png", "content_type": "image/png", "size": 245760, "file": "https://storage.example.com/attachments/.../screenshot.png", "created_at": "2026-03-02T10:01:00Z" }
Here's how a typical mobile integration looks. Your app collects device info automatically and sends it along with the user's report.
import UIKit
func reportBug(subject: String, description: String, logs: String?) async throws {
let device: [String: String] = [
"os": "iOS",
"os_version": UIDevice.current.systemVersion,
"app_version": Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "",
"app_build": Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "",
"device_model": UIDevice.current.model,
"locale": Locale.current.identifier,
"timezone": TimeZone.current.identifier,
]
var body: [String: Any] = [
"subject": subject,
"description": description,
"user_email": currentUser.email,
"type": "bug",
"device": device,
]
if let logs = logs { body["logs"] = logs }
var request = URLRequest(url: URL(string: "https://api.bancrofthq.com/api/v1/feedback/")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(apiKey, forHTTPHeaderField: "X-API-Key")
request.httpBody = try JSONSerialization.data(withJSONObject: body)
let (_, response) = try await URLSession.shared.data(for: request)
guard (response as? HTTPURLResponse)?.statusCode == 201 else { throw ReportError.failed }
}suspend fun reportBug(subject: String, description: String, logs: String? = null) {
val device = mapOf(
"os" to "Android",
"os_version" to Build.VERSION.RELEASE,
"app_version" to BuildConfig.VERSION_NAME,
"app_build" to BuildConfig.VERSION_CODE.toString(),
"device_model" to Build.MANUFACTURER + " " + Build.MODEL,
"locale" to Locale.getDefault().toString(),
"timezone" to TimeZone.getDefault().id,
)
val body = buildJsonObject {
put("subject", subject)
put("description", description)
put("user_email", currentUser.email)
put("type", "bug")
put("device", Json.encodeToJsonElement(device))
logs?.let { put("logs", it) }
}
httpClient.post("https://api.bancrofthq.com/api/v1/feedback/") {
header("X-API-Key", apiKey)
contentType(ContentType.Application.Json)
setBody(body)
}
}When a feedback report comes in, your agents see:
bug, feedback, or question)