What are webhooks?
Webhooks are HTTP POST requests sent by the app to your endpoint when events occur (e.g., a new question or answer). Use them to integrate with external systems, automate workflows, or sync data.
Available webhook events
The app supports 8 webhook events:
- New Question (newQuestion) — When a customer submits a question
- Edit Question (editQuestion) — When a question is updated
- Delete Question (deleteQuestion) — When a question is deleted
- New Answer (newAnswer) — When an answer is added
- Edit Answer (editAnswer) — When an answer is updated
- Delete Answer (deleteAnswer) — When an answer is deleted
- Approve Question (approveQuestion) — When a question is approved/published
- New Vote (newVote) — When a customer votes on a question
How to configure webhooks
- Go to Settings in the app admin
- Find the Webhooks section
- Enter your webhook endpoint URL (must be HTTPS)
- Enable the events you want to receive
- Save your settings
The app will send webhooks only for enabled events.
Webhook request format
HTTP method
POST
Headers
- Content-Type: application/json
- X-Shopify-Shop-Domain: your-shop.myshopify.com
- X-Webhook-Topic: newQuestion (varies by event)
Request body structure
All webhooks follow this structure:
{
“action”: “create”,
“entity”: “question”,
“shop”: “your-shop.myshopify.com”,
“data”: {
// Complete question or answer object
}
}
Webhook event details
1. New Question (newQuestion)
When it fires: When a customer submits a new questionPayload:
{
“action”: “create”,
“entity”: “question”,
“shop”: “your-shop.myshopify.com”,
“data”: {
“id”: “clx123abc”,
“shop”: “your-shop.myshopify.com”,
“productId”: “123456789”,
“productType”: “T-Shirt”,
“productCategory”: “T-shirt”,
“productTags”: “summer, cotton”,
“customerName”: “John Doe”,
“customerEmail”: “john@example.com”,
“question”: “What size should I order?”,
“isPublished”: false,
“votes”: 0,
“createdAt”: “2024-01-15T10:30:00.000Z”,
“updatedAt”: “2024-01-15T10:30:00.000Z”,
“answers”: []
}
}
- id — Question ID
- shop — Store domain
- productId — Shopify product ID
- productType — Product type
- productCategory — Product category
- productTags — Comma-separated tags
- customerName — Customer name (optional)
- customerEmail — Customer email (optional)
- question — Question text
- isPublished — Published status
- votes — Vote count
- createdAt — Creation timestamp
- updatedAt — Last update timestamp
- answers — Array of answers (empty for new questions)
2. Edit Question (editQuestion)
When it fires: When a question is updatedPayload:
{
“action”: “update”,
“entity”: “question”,
“shop”: “your-shop.myshopify.com”,
“data”: {
“id”: “clx123abc”,
“shop”: “your-shop.myshopify.com”,
“productId”: “123456789”,
“productType”: “T-Shirt”,
“productCategory”: “T-shirt”,
“productTags”: “summer, cotton”,
“customerName”: “John Doe”,
“customerEmail”: “john@example.com”,
“question”: “What size should I order?”,
“isPublished”: true,
“votes”: 5,
“createdAt”: “2024-01-15T10:30:00.000Z”,
“updatedAt”: “2024-01-15T14:20:00.000Z”,
“answers”: []
}
}
3. Delete Question (deleteQuestion)
When it fires: When a question is deletedPayload:
{
“action”: “delete”,
“entity”: “question”,
“shop”: “your-shop.myshopify.com”,
“data”: {
“id”: “clx123abc”,
“shop”: “your-shop.myshopify.com”,
“productId”: “123456789”,
“productType”: “T-Shirt”,
“productCategory”: “T-shirt”,
“productTags”: “summer, cotton”,
“customerName”: “John Doe”,
“customerEmail”: “john@example.com”,
“question”: “What size should I order?”,
“isPublished”: true,
“votes”: 5,
“createdAt”: “2024-01-15T10:30:00.000Z”,
“updatedAt”: “2024-01-15T14:20:00.000Z”,
“answers”: [
{
“id”: “clx456def”,
“answer”: “I recommend size M”,
“authorName”: “Admin”,
“authorEmail”: “admin@store.com”,
“isPublished”: true,
“createdAt”: “2024-01-15T11:00:00.000Z”
}
]
}
}
4. New Answer (newAnswer)
When it fires: When an answer is added to a questionPayload:
{
“action”: “create”,
“entity”: “answer”,
“shop”: “your-shop.myshopify.com”,
“data”: {
“id”: “clx456def”,
“shop”: “your-shop.myshopify.com”,
“questionId”: “clx123abc”,
“authorName”: “Admin”,
“authorEmail”: “admin@store.com”,
“answer”: “I recommend size M for most customers.”,
“isPublished”: true,
“createdAt”: “2024-01-15T11:00:00.000Z”,
“updatedAt”: “2024-01-15T11:00:00.000Z”,
“question”: {
“id”: “clx123abc”,
“productId”: “123456789”,
“question”: “What size should I order?”,
“customerName”: “John Doe”,
“customerEmail”: “john@example.com”,
“votes”: 0
}
}
}
- id — Answer ID
- shop — Store domain
- questionId — Related question ID
- authorName — Answer author name
- authorEmail — Answer author email (optional)
- answer — Answer text
- isPublished — Published status
- createdAt — Creation timestamp
- updatedAt — Last update timestamp
- question — Related question object
5. Edit Answer (editAnswer)
When it fires: When an answer is updatedPayload:
{
“action”: “update”,
“entity”: “answer”,
“shop”: “your-shop.myshopify.com”,
“data”: {
“id”: “clx456def”,
“shop”: “your-shop.myshopify.com”,
“questionId”: “clx123abc”,
“authorName”: “Admin”,
“authorEmail”: “admin@store.com”,
“answer”: “Updated answer text”,
“isPublished”: true,
“createdAt”: “2024-01-15T11:00:00.000Z”,
“updatedAt”: “2024-01-15T15:30:00.000Z”,
“question”: {
“id”: “clx123abc”,
“productId”: “123456789”,
“question”: “What size should I order?”,
“customerName”: “John Doe”,
“customerEmail”: “john@example.com”,
“votes”: 5
}
}
}
6. Delete Answer (deleteAnswer)
When it fires: When an answer is deletedPayload:
{
“action”: “delete”,
“entity”: “answer”,
“shop”: “your-shop.myshopify.com”,
“data”: {
“id”: “clx456def”,
“shop”: “your-shop.myshopify.com”,
“questionId”: “clx123abc”,
“authorName”: “Admin”,
“authorEmail”: “admin@store.com”,
“answer”: “I recommend size M”,
“isPublished”: true,
“createdAt”: “2024-01-15T11:00:00.000Z”,
“updatedAt”: “2024-01-15T11:00:00.000Z”,
“question”: {
“id”: “clx123abc”,
“productId”: “123456789”,
“question”: “What size should I order?”,
“customerName”: “John Doe”,
“customerEmail”: “john@example.com”,
“votes”: 5
}
}
}
7. Approve Question (approveQuestion)
When it fires: When a question is approved/publishedPayload:
{
“action”: “approve”,
“entity”: “question”,
“shop”: “your-shop.myshopify.com”,
“data”: {
“id”: “clx123abc”,
“shop”: “your-shop.myshopify.com”,
“productId”: “123456789”,
“productType”: “T-Shirt”,
“productCategory”: “T-shirt”,
“productTags”: “summer, cotton”,
“customerName”: “John Doe”,
“customerEmail”: “john@example.com”,
“question”: “What size should I order?”,
“isPublished”: true,
“votes”: 0,
“createdAt”: “2024-01-15T10:30:00.000Z”,
“updatedAt”: “2024-01-15T12:00:00.000Z”,
“answers”: []
}
}
8. New Vote (newVote)
When it fires: When a customer votes on a questionPayload:
{
“action”: “vote”,
“entity”: “question”,
“shop”: “your-shop.myshopify.com”,
“data”: {
“questionId”: “clx123abc”,
“totalVotes”: 6,
“question”: {
“id”: “clx123abc”,
“productId”: “123456789”,
“question”: “What size should I order?”,
“customerName”: “John Doe”,
“customerEmail”: “john@example.com”,
“votes”: 6
},
“vote”: {
“identifier”: “hashed-identifier”,
“direction”: “up”,
“customerEmail”: “voter@example.com”,
“customerId”: “987654321”
}
}
}
- questionId — Question ID
- totalVotes — Updated vote count
- question — Question object with updated vote count
- vote.identifier — Hashed identifier (email, IP, or custom)
- vote.direction — “up” or “down”
- vote.customerEmail — Voter email (if available)
- vote.customerId — Voter Shopify customer ID (if available)
Best practices
1. Endpoint requirements
- Use HTTPS
- Return 200 OK within 5 seconds
- Handle duplicate events (idempotency)
2. Security
- Verify X-Shopify-Shop-Domain
- Validate payload structure
- Use authentication if needed
3. Error handling
- Log failures
- Return appropriate status codes
- Implement retries if needed
4. Testing
- Use a test endpoint during setup
- Verify payload structure
- Test all enabled events
Frequently asked questions
How quickly are webhooks sent?
Webhooks are sent immediately after the event occurs.
What if my endpoint is down?
The app sends the webhook once. If your endpoint fails, implement retries or use a webhook service.
Can I receive webhooks for multiple events?
Yes. Enable multiple events in Settings.
What HTTP status code should I return?
Return 200 OK to acknowledge receipt. Other codes may be treated as failures.
Are webhooks retried on failure?
No. The app sends once. Handle retries on your side if needed.
Can I filter which webhooks I receive?
Yes. Enable only the events you need in Settings.
What format are timestamps in?
ISO 8601 UTC (e.g., “2024-01-15T10:30:00.000Z”).
Do webhooks include product information?
No. They include productId. Fetch product details from Shopify if needed.
Can I change my webhook URL?
Yes. Update it in Settings. New events will use the new URL.
Are webhooks available on all plans?
Webhook features may vary by plan. Check your plan details in Settings.
Quick reference
| Event | Action | Entity | When it fires |
|---|---|---|---|
| newQuestion | create | question | New question submitted |
| editQuestion | update | question | Question updated |
| deleteQuestion | delete | question | Question deleted |
| newAnswer | create | answer | New answer added |
| editAnswer | update | answer | Answer updated |
| deleteAnswer | delete | answer | Answer deleted |
| approveQuestion | approve | question | Question approved |
| newVote | vote | question | Vote cast |