Events and webhooks

When something interesting happens on your Increase account, such as a new Transaction being created, Increase can reach out to your application so that you can take action (such as sending an email alert about the transaction to your user) automatically.

The first step is to create an Event Subscription in the dashboard or via the API. As part of this, you specify a URL on your own servers. Increase will then send HTTPS requests to that URL to notify you of activity.

When something noteworthy happens, Increase first generates an Event object. Next, we’ll send a POST request to your endpoint. The body of the POST request will be the same as the API representation of the Event, such as:

{ "id": "event_123abc", "created_at": "2020-01-31T23:59:59Z", "category": "transaction.created", "associated_object_type": "transaction", "associated_object_id": "transaction_abc123", "type": "event" }

Note that you can make Event Subscriptions in the live API or in the sandbox. Sandbox Event Subscriptions will receive webhooks for Sandbox Events and vice versa.

Consuming Events

Individual Events don’t contain very much information on their own. This is by design, as the API structure can remain extremely stable and avoid difficult webhook migrations in the future as the Increase API changes. If you need additional metadata, such as the amount of the Transaction in the above example, make a GET request to the API for that information. You can use the associated_object_type or category fields to determine what resource to fetch from the API.

If you don’t want to use webhooks, or need to do some batch processing, you can also request Events from the Increase API using the List Events API. Events will remain in our systems for up to 30 days.

Failures and retries

In production, if your application returns anything other than a 20x HTTP status code, we’ll retry it up to 10 times with exponentially increasing backoffs. In your webhook endpoint implementation, we recommend you place inbound Events into your application’s own queuing system (such as Kafka, Resque, etc) for asynchronous event processing, and returning a 200 response from your endpoint as quickly as possible. Because we can't guarantee we'll receive your 200, your webhook implementation should gracefully handle receiving the same webhook multiple times.

To avoid queueing issues, we will not retry failed webhooks in the sandbox.

Event types

For a list of all of the possible actions that will result in an Event/webhook being generated, see our API reference.

Securing your webhook endpoint (recommended)

Increase will include an Increase-Webhook-Signature header in each webhook request. This header will contain a timestamp and one or more signatures. The timestamp is prefixed by t=, and each signature is prefixed by a scheme. Schemes start with v, followed by an integer. Currently, the only valid live signature scheme is v1.

Increase-Webhook-Signature: t=2022-01-31T23:59:59Z,v1=7ebfbadaa1856b9f1374f3e08453de3d760838344862344a103c28129d9173d1

Increase generates signatures using a hash-based message authentication code (HMAC) with SHA-256. To prevent downgrade attacks, you should ignore all schemes that are not v1. It is possible to have multiple signatures with the same scheme-secret pair. This can happen when you roll an endpoint’s secret from the Dashboard, and choose to keep the previous secret active for up to 24 hours. During this time, your endpoint has multiple active secrets and Increase generates one signature for each secret.

Step 1: Extract the timestamp and signatures from the header

Split the header, using the , character as the separator, to get a list of elements. Then split each element, using the = character as the separator, to get a prefix and value pair. The value for the prefix t corresponds to the timestamp, and v1 corresponds to the signature (or signatures). You can discard all other elements.

Step 2: Prepare the signed_payload string

The signed_payload string is created by concatenating:

  • The timestamp (as a string)
  • The character .
  • The actual JSON payload (that is, the request body)

Step 3: Determine the expected signature

Compute an HMAC with the SHA256 hash function. Use the endpoint’s signing secret as the key, and use the signed_payload string as the message.

Step 4: Compare the signatures

Compare the signature (or signatures) in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance.

To protect against timing attacks, use a constant-time string comparison to compare the expected signature to each of the received signatures.