Turn webhooks into push notifications, fast.

Sometimes you just need a quick heads up.

It takes less than a minute to set up Tailhook notifications for

Every webhook...
{
  "type": "charge.capturerd",
  "object:" "event",
  "data": {
        "id:" "ch_00005",
        "amount:" "100",
    }
}
...can be a notification.
New Payment
ch_0005
100

How it works

Once you've enabled notifications from Tailhook in your browser, everything else goes through the API - no apps to download and no extensions to install.

You configure your endpoint

Send a POST to let Tailhook know what it should include in the notifcation payload. It can be static text, data from the webhook referenced using dot notation, or a combination of both.

The response will include a unique URL where you can send the webhook.

Tailhook parses incoming webhooks

When Tailhook receives a webhook, it uses the unique URL as a key to retrieve your settings. It parses the webhook,

When it's ready, the notification payload is added to the sending queue.

Notifications are delivered to your browser

The delivery method depends on the browser you use. Chrome and Firefox users get notfications via Web Push, while Safari uses APNS.

On a Mac, we recommend enabling Tailhook in Safari. You'll receive notifications even if Safari is closed.

About Tailhook

Tailhook was born as an internal tool at Quarva. We use it to receive actionable alerts about long-running processes, like Netlify builds, without piling even more email in our inboxes.

Before building Tailhook, we got this done using workflows on Zapier and ifttt. They can get expensive, though, and we really wanted something cli-based that would let us add new endpoints more easily. The version of Tailhook that you're looking at now was built in about a day to scratch that itch.

We hope other people find this as useful as we do. If you have any thoughts or questions, please let us know!

Privacy

We don't log the content of any requests to Tailhook endpoints. If a request is cached - so that we can retry a push after a connection error, for example - it will be cleared no more than 24 hours after it was made.

We use OneSignal to deliver notifications. They only receive the notification payload, and you can review their privacy policy here. Website analytics are handled by Fathom, whose privacy policy is available here.

Common Applications

New payment from Stripe

Receive a notification on every successful Stripe payment.

Stripe
charge.succeeded
100

Our Configuration

  • endpoint_title

    Value: Stripe

    Content: (string)

  • endpoint_body_header

    Value: type

    Content: (node reference)

  • endpoint_body

    Value: data.object.amount

    Content: (node reference)

  • endpoint_url

    Value: data.object.receipt_url

    Content: (node reference)

Sample webhook payload

{
  "created": 1326853478,
  "livemode": false,
  "id": "evt_00000000000000",
  "type": "charge.succeeded",
  "object": "event",
  "request": null,
  "pending_webhooks": 1,
  "api_version": "2020-08-27",
  "data": {
    "object": {
      "id": "ch_00000000000000",
      "object": "charge",
      "amount": 100,
      "amount_refunded": 0,
      "application": null,
      "application_fee": null,
      "application_fee_amount": null,
      "balance_transaction": "txn_00000000000000",
      "billing_details": {
        "address": {
          "city": null,
          "country": null,
          "line1": null,
          "line2": null,
          "postal_code": null,
          "state": null
        },
        "email": null,
        "name": null,
        "phone": null
      },
      "calculated_statement_descriptor": null,
      "captured": false,
      "created": 1600411308,
      "currency": "sgd",
      "customer": null,
      "description": "My First Test Charge (created for API docs)",
      "disputed": false,
      "failure_code": null,
      "failure_message": null,
      "fraud_details": {},
      "invoice": null,
      "livemode": false,
      "metadata": {},
      "on_behalf_of": null,
      "order": null,
      "outcome": null,
      "paid": true,
      "payment_intent": null,
      "payment_method": "card_00000000000000",
      "payment_method_details": {
        "card": {
          "brand": "visa",
          "checks": {
            "address_line1_check": null,
            "address_postal_code_check": null,
            "cvc_check": "pass"
          },
          "country": "US",
          "exp_month": 8,
          "exp_year": 2021,
          "fingerprint": "IMZEDxwtuFyFm1b3",
          "funding": "credit",
          "installments": null,
          "last4": "4242",
          "network": "visa",
          "three_d_secure": null,
          "wallet": null
        },
        "type": "card"
      },
      "receipt_email": null,
      "receipt_number": null,
      "receipt_url": "https://pay.stripe.com/receipts/acct_1HQ6Z3KRZIlSEKzY/ch_1HSdI0KRZIlSEKzYN6GeSSng/rcpt_I2ijOhMHqZrWyhZZKrj3fFAs84idGRo",
      "refunded": false,
      "refunds": {
        "object": "list",
        "data": [],
        "has_more": false,
        "url": "/v1/charges/ch_1HSdI0KRZIlSEKzYN6GeSSng/refunds"
      },
      "review": null,
      "shipping": null,
      "source_transfer": null,
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "succeeded",
      "transfer_data": null,
      "transfer_group": null
    }
  }
}

Endpoint Request


 curl -X POST "https://tailhook.dev/api/\
    ?user=your_user_id@users.tailhook.dev\
    &endpoint_name=Stripe Payment\
    &endpoint_title=Stripe\
    &endpoint_body_header=type\
    &endpoint_body=data.object.amount\
    &endpoint_url=data.object.receipt_url"
            

Roadmap

A few things we're planning to add in the near future

Webhook signature validation

Make sure that the webhook sender is who you think it is.

Distribution lists

Specify multiple users per webhook. Useful for sending build failures or downtime notifications to devops teams.

Multiple items in the notification body

Right now, you can have a maximum of two items in the body of a notification. We'll allow you to pass in an array of items that should be included instead.

Trigger nodes

Specify one node whose value can change the content of a notification. This is useful for services that send monolithic webhooks, like GitHub, so that you can include different fields based on the event.

Usage

Example

  • user - your user ID from above
  • endpoint_name - a display name for the endpoint, not used in notificaions
  • endpoint_body - the text to be displayed in the body of the notification. Can be a valid json node or a text string.
  • endpoint_title - the title of the notificattion. Can be a valid json node or a text string.
  • endpoint url - the URL that you will be sent to if you click on the notification. Can be a valid json node or a URL string, e.g. google.com


                    curl -X POST "https://tailhook.dev/api/\
                    ?user=your_user_id@users.tailhook.dev\
                    &endpoint_name=DisplayName\
                    &endpoint_body=data.body.node\
                    &endpoint_title=data.title.node\
                    &endpoint_url=data.url.node"
                 

If there's no error, you should receive a URL in the response:

{"success":"Endpoint created at tailhook.dev/hook/djsgbus83bs3ub"}%

Send your webhooks to that URL and you should get a notfication.

Troubleshooting

If you see the unprocessed json node in the notification, that means there was no matching node in the payload we received. Double check that you're addressing it correctly.