Solo
For one app and one person answering.
Free
- 1 space
- Just you
- 20 support requests a month
Merchants write in from any app. You answer from one place.
What changes when every app's support runs through WishSupport instead of a helpdesk per app.
With a helpdesk per app: A separate helpdesk or mailbox per app, each with its own login to check.
With WishSupport: Every app in one portal. The dashboard shows who is waiting for a reply across all of them.
With a helpdesk per app: Every app's helpdesk needs its own invites and its own seats.
With WishSupport: Invite a teammate once and add them to any of your apps. A seat is per person, not per app.
With a helpdesk per app: Agents ask for the store URL and which app it is before they can help.
With WishSupport: The shop, the app and the merchant's plan arrive with the first message.
With a helpdesk per app: Edited or deleted replies disappear, so nobody can say who told the merchant what.
With WishSupport: Every ticket logs who replied, closed or deleted what. A deleted message stays, naming who deleted it.
With a helpdesk per app: A merchant can wait for hours before anyone notices the message.
With WishSupport: Your team is emailed the moment a ticket opens. A message left unread for 5 minutes emails whoever has not seen it, your team or the merchant.
Plain HTTPS and JSON. Works from any backend: Remix, Node.js, Laravel or Rails.
One per app. Your first is free.
Getting startedOne API call from your server.
QuickstartAnswers reach merchants in under a second.
ConversationsWrap your Shopify app with the React SDK, or call the API from your backend. Your team answers from the inbox.
// app.tsx: the server route keeps your key, the provider adds the widget.
<WishSupportProvider navigate={useNavigate()}>
<Outlet />
</WishSupportProvider>
// app.support._index.tsx
<SupportList />
// app.support.$ticketId.tsx
<SupportTicket ticketId={useParams().ticketId!} />// On your app's server: the API key never reaches a browser.
const response = await fetch('https://api.wishsupport.app/v1/client/tickets', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WISHSUPPORT_API_KEY}`,
'X-Shop-Domain': session.shop, // from your authenticated Shopify session
'Content-Type': 'application/json',
},
body: JSON.stringify({
shopName: shop.name,
requesterName: staff.name,
requesterEmail: staff.email,
subject: 'COD form not showing at checkout',
message: 'The form disappeared after the last update.',
plan: shop.planName,
}),
});
const { ticket } = await response.json(); // keep ticket.code for repliescurl -X POST https://api.wishsupport.app/v1/client/tickets \
-H "Authorization: Bearer $WISHSUPPORT_API_KEY" \
-H "X-Shop-Domain: acme.myshopify.com" \
-H "Content-Type: application/json" \
-d '{
"shopName": "Acme Supplies",
"requesterName": "Nadia Rahman",
"requesterEmail": "nadia@acme.example",
"subject": "COD form not showing at checkout",
"message": "The form disappeared after the last update.",
"plan": "growth"
}'{
"ticket": { "code": "TCK-A7K2P9X", "status": "open" },
"message": {
"id": 1,
"senderType": "shop",
"body": "The form disappeared after the last update."
}
}Many apps, many shops, one team.
Own keys, team and files
Shop, plan and requester attached
Real-time over WebSocket
Nothing is hard-deleted
Everyone sees what's handled
After 1 to 365 days, per app
4 files per message, 10 MB each
By ticket code, subject or text
Every plan has every feature. Plans differ only in how many apps, teammates and support requests they cover.
For one app and one person answering.
Free
For a couple of apps and a small support team.
$15/month
For Shopify partner teams running several apps.
$39/month
For companies handling large merchant volume.
$79/month
Included in every plan
Over the monthly request limit, new requests are held rather than refused, so merchants can always write in.
Running several apps, moving off a shared inbox or wiring up the client API? Tell us about your setup.