Everything you need to know about Signalshoot.
This guide walks you through the entire process of adding Signalshoot to your app, from creating your account to seeing the first feedback in your dashboard. No prior experience with APIs is assumed.
Signalshoot works in three simple steps: (1) Your app sends an HTTP request to our server when a user submits feedback. (2) Our server stores the feedback in your dashboard. (3) You open the dashboard to read, organize, and respond. There is no SDK to install. Your app just needs to be able to send an HTTP POST request — which every programming language and framework can do.
After signing in to Signalshoot, go to the Settings page. You will find three important values there:
Endpoint: https://api.signalshoot.com/v1/ingest/YOUR_APP_ID Header: X-API-Key: fb_live_YOUR_KEY
In all code examples below, replace YOUR_APP_ID with your actual App ID, and fb_live_YOUR_KEY (or fb_test_YOUR_KEY) with your actual key. You can copy these directly from Settings.
When your app sends feedback to Signalshoot, it sends a JSON object. Here is what each field does:
Choose your platform below and copy the code. The integration is a single HTTP POST request — no library or SDK to install. Paste the code into your app wherever you want users to be able to send feedback (a contact form, a bug report button, a feedback modal, etc.).
React Native / Expo
const sendFeedback = async (type, message, channel = 'contact') => {
await fetch('https://api.signalshoot.com/v1/ingest/YOUR_APP_ID', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'fb_live_YOUR_KEY',
},
body: JSON.stringify({
type, message, channel,
metadata: { app_version: Constants.expoConfig?.version, os: Platform.OS },
}),
});
};Flutter (Dart)
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<void> sendFeedback(String type, String message) async {
await http.post(
Uri.parse('https://api.signalshoot.com/v1/ingest/YOUR_APP_ID'),
headers: {'Content-Type': 'application/json', 'X-API-Key': 'fb_live_YOUR_KEY'},
body: jsonEncode({'type': type, 'message': message, 'channel': 'contact'}),
);
}Swift (iOS)
func sendFeedback(type: String, message: String) async throws {
var req = URLRequest(url: URL(string: "https://api.signalshoot.com/v1/ingest/YOUR_APP_ID")!)
req.httpMethod = "POST"
req.setValue("application/json", forHTTPHeaderField: "Content-Type")
req.setValue("fb_live_YOUR_KEY", forHTTPHeaderField: "X-API-Key")
req.httpBody = try JSONSerialization.data(withJSONObject: [
"type": type, "message": message, "channel": "contact"
])
let (_, _) = try await URLSession.shared.data(for: req)
}Kotlin (Android)
val body = JSONObject().apply {
put("type", "bug"); put("message", msg); put("channel", "contact")
}.toString().toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("https://api.signalshoot.com/v1/ingest/YOUR_APP_ID")
.addHeader("X-API-Key", "fb_live_YOUR_KEY")
.post(body).build()
OkHttpClient().newCall(request).execute()Web (JavaScript)
await fetch('https://api.signalshoot.com/v1/ingest/YOUR_APP_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'fb_live_YOUR_KEY' },
body: JSON.stringify({ type: 'bug', message: msg, channel: 'contact' }),
});Important for web apps: Your API key will be visible in browser source code if you include it in client-side JavaScript. For web applications, we strongly recommend sending the API request from your backend server instead. This keeps your key hidden from users.
If you use an AI coding assistant like Claude, Cursor, or GitHub Copilot, you don't need to write the integration code yourself. Copy the prompt below and paste it into your AI assistant. It contains all the information the AI needs to generate the correct code for your specific app and platform.
Add a feedback button to my app that sends user feedback to Signalshoot.
API endpoint: https://api.signalshoot.com/v1/ingest/MY_APP_ID
API key: fb_live_MY_KEY (send as X-API-Key header)
Request body (JSON):
- type: "bug" | "feedback" | "inquiry" (required)
- message: string (required, max 5000 chars)
- channel: string (optional, e.g. "contact", "report")
- user_id: string (optional, enables replies)
- metadata: object (optional, e.g. { app_version, os, device, screen })By default, feedback is one-way: users send, you read. But if you include a user_id when sending feedback, you unlock two-way communication. Here's how it works: (1) User sends feedback with user_id included. (2) You see it in the dashboard and write a reply. (3) Your app calls the replies endpoint to check if there's a response. (4) Your app displays the reply to the user. For threaded follow-ups, the user sends a new request with parent_id set to the original feedback ID.
// Include user_id when sending:
{ type: 'bug', message: '...', user_id: 'user_123' }
// Fetch replies:
GET https://api.signalshoot.com/v1/feedback/YOUR_APP_ID/replies?user_id=user_123
X-API-Key: fb_live_YOUR_KEYBefore releasing your app with Signalshoot integrated, test the entire flow: (1) Send a test feedback using your test API key (fb_test_...). (2) Open the Signalshoot dashboard and verify it appears. (3) Try changing the status, adding tags, and writing a reply. (4) If you implemented replies, verify your app can fetch them. (5) Once everything works, switch to the live API key in your production build.
curl -X POST https://api.signalshoot.com/v1/ingest/YOUR_APP_ID \
-H "Content-Type: application/json" \
-H "X-API-Key: fb_live_YOUR_KEY" \
-d '{"type":"bug","channel":"contact","message":"Test from cURL"}'Your test key (fb_test_...) works exactly like the live key, but feedback sent with it is marked as test data and stored separately. This means you can test freely without cluttering your production inbox. You can also use the "Send test feedback" button in Settings to quickly verify your dashboard is working.