Notifications
New-sale notifications by email, Slack or Discord, and weekly or monthly email reports.
PilotFox can tell you about each new sale as it comes in, by email, in a Slack channel or in a Discord channel, and send you a summary of a site every week or every month.
Slack and Discord webhooks
Post new-sale messages to a channel through an incoming webhook.
Email reports
A weekly or monthly email of a site's traffic and revenue.
New-sale notifications
When PilotFox stores a payment it has never seen before, the site's channels get a message like:
New sale: $49.00 · from Hacker News (news.ycombinator.com) · Germany
When a sale is announced
A payment is a new sale when all of these hold:
- PilotFox had not stored it yet, and it was paid in the last 24 hours (or up to 5 minutes ahead of the server's clock);
- its amount is above zero and it is not refunded in full;
- the site has a channel at that moment (an enabled Slack or Discord webhook, or at least one email recipient).
So payments imported when a provider is first connected (or its key replaced), payments read again later and refunds never send a message, and each payment sends at most one. Payments recorded with the payments API count the same way: the first time a payment id is recorded, never on an update.
Sales are sent once a minute, one message per site and channel, so several sales in a minute arrive as one message ("3 new sales: $147.00", one line per sale, up to ten, then "…and N more"). Totals in several currencies are listed side by side ("$98.00 + €49.00").
What a message says
| Part | What it is |
|---|---|
| Amount | What the customer paid, in the payment's currency. |
from … | Where the buyer came from: the visit the payment is credited to under the site's credit model. Its referrer domain (without www.), named for well-known sites ("Hacker News (news.ycombinator.com)", "Google (google.com)"); else its campaign source with the channel ("newsletter (Email)"); else its channel ("Direct"). |
| Country | That visit's country. |
test mode | Added for a payment made with a provider's test key. |
| Link | The site's Revenue page. |
Whatever is unknown is left out, so a payment linked to no visit shows only its amount. Text that comes from a visitor (a referrer, a campaign source) is made one line, stripped of invisible characters, cut to 80 characters and escaped for the channel, so it can never add a line, a link or a mention of its own.
Channels and who can set them
Open Site settings → Notifications. The settings need site:update (the editor role and above).
| Channel | How |
|---|---|
| Tick the organization members who should get an email. Only members who can see the site's revenue are listed, and each send checks again: a member who later loses that access (or is banned) gets nothing. | |
| Slack | Paste an incoming webhook URL (https://hooks.slack.com/services/…). See Slack and Discord webhooks. |
| Discord | Paste a channel webhook URL (https://discord.com/api/webhooks/…). |
A webhook receives every new sale's amount, source and country, so pointing one somewhere or switching it on also needs
revenue:read on the site: every organization role has it, but an API key may not (403). Switching a webhook off,
deleting it and sending a test need site:update only. Like an email recipient, the member or API key that set a
webhook's URL is checked again at each send: once it can no longer see the site's revenue (or is deleted), the webhook
gets nothing until someone pastes the URL again (see who connected it).
Messages are sent at most once. If Slack or Discord refuses a message (for example because the webhook was deleted), the webhook's settings show why and the message is not sent again later.
Send a test
Send test posts a made-up sale (4 900 in the smallest unit of the site's currency, so $49.00 for US dollars, from Hacker News, Germany) to one channel at once, marked as a test:
email: to you only, the signed-in person, and only if your role on the site includes its revenue;slackordiscord: to that webhook, even while it is switched off.
curl -X POST "https://pilotfox.app/api/v1/sites/SITE_ID/notifications/test" \
-H "Authorization: Bearer $PILOTFOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"channel": "slack"}'The answer is 200 either way: {"data": {"ok": true, "message": null}}, or ok: false with the reason, such as
"Slack no longer accepts this webhook (it was removed or disabled). Paste a new one." A channel that is not set up is
400 ("Paste a Slack webhook URL first"). A test email needs a signed-in person, so an API key gets 400 for
email.
API endpoints
All under /api/v1/sites/{siteId}, with site:update:
| Endpoint | What it does | Reference |
|---|---|---|
GET /notifications | The recipients, the members who can be chosen, and the Slack and Discord webhooks | settings |
PUT /notifications/email with {"userIds": [...]} | Replaces the email recipients (up to 200) | recipients |
PUT /notifications/slack, PUT /notifications/discord | Connects a webhook (url) or switches it on or off (enabled) | Slack, Discord |
DELETE /notifications/slack, DELETE /notifications/discord | Removes the webhook | Slack, Discord |
POST /notifications/test with {"channel": "slack"} (or "discord", "email") | Sends a test | test |
Each of these answers with the site's notification settings, except the test. A recipient who cannot see the site's
revenue is refused (400, with the refused userIds in error.details).
Email reports have their own endpoints: see Email reports.
Self-hosted instances
Emails need the server's mail settings (Cloudflare Email Sending or SMTP_URL, see
Mail); without them, nothing is emailed and the server logs that a mail was
not sent.
Slack and Discord messages are sent from the server to hooks.slack.com and discord.com, so the server needs
outbound HTTPS to them.