Integrations
This page covers programmatic integrations that sit between PatchKit and systems you control: Webhooks (PatchKit notifies your server when something happens), Secure Running (your shipped game verifies a license key against PatchKit’s Keys service at runtime) and License Dispatcher (your shop gets a free license key for each buyer).
For general API and CLI usage see API and Command-Line Tools.
Webhooks
The Webhooks feature lets you receive notifications about events in your PatchKit Panel. A common use case is posting a message to Slack/Discord when a new version is published, or triggering a downstream CI step after a version finishes processing.
Webhook Events
The following events are available:
- Version Published (
version_published) — triggered when a new version of an application is published. - Version Processed (
version_processed) — triggered when a version of an application is processed. - Version Process Failed (
version_process_failed) — triggered when a version of an application fails to process.
How to Set Up Webhooks
To set up Webhooks:
- Go to the Applications page.
- Select one of your applications.
- Click on the Webhooks tab.
- Click on the New Webhook button.
On the next page, you will be asked to provide:
- Event — the event type that will trigger the webhook.
- Request Method — the HTTP method (
GET,POST,PUT, etc.). - URL — the URL that will receive the webhook.
- Headers — the headers that will be sent with the request, in JSON format.
- Request Format — the format of the request body:
json(sent asapplication/json) orform(sent asapplication/x-www-form-urlencoded). - Payload — the payload that will be sent, in JSON format. Template variables are interpolated before sending (see below).
Finally, click Create.
Headers Example
Headers must be provided in JSON format:
{
"Authorization": "Bearer <your_shared_secret>"
}
Payload Example
The payload must be provided in JSON format:
{
"msg": "Application published!"
}
Using Variables
You can use variables in the payload, headers, and URL. The following variables are available:
{{event.name}}— the event that fired (version_published,version_processed,version_process_failed).{{app.name}}— the internal name of the application.{{app.display_name}}— the display name of the application.{{app.group_name}}— the name of the application group (when using channels).{{app.download_url}}— the share URL of the application launcher.{{app.direct_download_url}}— direct download URL of the application launcher.{{version.id}}— the ID of the version (vid).{{version.label}}— the label of the version.{{version.published_at}}— the date and time when the version was published.{{version.humanized_content_size}}— the size of the version content file, human-readable.{{version.humanized_diff_size}}— the size of the version diff file, human-readable.{{version.changes}}— the changelog of the version.{{version.known_issues}}— the known-issues text of the version.{{version.processing_error}}— the processing errors (if any), joined by semicolons.{{version.processing_started_at}}— when processing started.{{version.processing_finished_at}}— when processing finished.{{version.humanized_processing_duration}}— processing duration, human-readable.
Example:
{
"msg": "Application {{app.display_name}} version {{version.label}} has been published!"
}
How to Test Webhooks
Click the Test button on the webhooks page to send a test request to the webhook’s URL. The test request uses a fixed set of sample values (e.g. app.name = Test App, version.label = Test Version) rather than data from any real version, so you can wire up the receiver before you actually publish anything.
The Test button’s sample values do not currently populate version.known_issues — references to that variable render empty on test requests, but the variable is set correctly on real events.
Delivery semantics
The points below describe how PatchKit currently delivers webhooks. This section exists so you can build a safe receiver; if any of these change, the docs here should be updated.
Signing
Outgoing webhook requests are not cryptographically signed. PatchKit does not include an HMAC signature header.
To authenticate that a webhook actually came from PatchKit, configure a shared-secret header on the webhook (for example Authorization: Bearer <your_shared_secret>) and verify it on the receiver. Treat the webhook URL itself as sensitive.
Retries
If the receiver does not return a 2xx response, the delivery job raises an error and is retried by the background queue with the default exponential-backoff policy. You should therefore design your receiver to be idempotent — the same event.name + version.id pair can arrive multiple times.
Timeout
Outgoing requests use the HTTP client’s default timeout (60 seconds). Receivers that take longer than this will be treated as failures and retried.
Rate limits
There is no explicit per-app or per-account rate limit on outgoing webhooks. Every webhook matching a triggering event fires once per event.
Delivery history
There is currently no UI to browse past webhook deliveries or retry a specific delivery manually. If you need an audit trail, log the incoming requests on your receiver side.
User-Agent
Outgoing webhooks use Ruby’s Net::HTTP default User-Agent. Do not rely on a specific User-Agent string for authentication.
Secure Running
Secure Running lets a shipped game verify — at runtime, not just at download time — that the player holds a valid License Key. This is the right integration when you’re distributing a paid or gated game and want to prevent the binary from being run outside of the intended license holder.
License Keys themselves are documented in Applications → License Keys. This section is about verifying them from inside your running game.
How it works
When the launcher runs your game, it passes a +patcher-data-location command-line argument. The value is a relative path to an app_data.json file the launcher has placed next to your executable. That file contains the player’s license key:
{
"file_id": "patcher_data",
"version": "1.0",
"product_key": "ABCD-EFGH-IJKL",
"product_key_encryption": "none"
}
Your game’s startup code should parse this argument, read app_data.json, and verify the product_key against the PatchKit Keys service.
Verifying a License Key
Send a request to the following endpoint:
https://keys2.patchkit.net/v2/keys/LICENSE_KEY?app_secret=APP_SECRET
LICENSE_KEY— theproduct_keyvalue fromapp_data.json.APP_SECRET— your application’s secret (visible on the Application’s Overview page in the Panel).
If the response is 200 OK, the license key is valid. Any other response may mean the key is invalid. We recommend treating 5xx responses as valid for reliability — a transient outage of the Keys service should not lock legitimate players out of their game.
APP_SECRET is embedded in the shipped binary when you make requests from the game process. Treat it as a deterrent rather than a hard secret — anyone with access to the binary can extract it. Combine Secure Running with other anti-tamper measures if you need stronger guarantees.
If your game is built on Unity, you can use this extension to secure your game.
License Dispatcher
A License Dispatcher hands out your License Keys automatically. After a purchase, your shop, server or payment provider calls the dispatcher’s endpoint and gets the next free key for the buyer. PatchKit marks the key as Distributed and saves the buyer’s e-mail address in the key’s notes, so the same key is never handed out twice.
Use it when you sell your game outside PatchKit (your own web shop, Patreon, PayPal, MyCommerce) and want each buyer to receive a key without manual work.
Setting Up a Dispatcher
- Open your application in the Panel and go to the Keys tab.
-
Scroll down to the License Dispatchers section and click New License Dispatcher. Existing dispatchers are listed in the same section, with their key collections, the number of free keys left and whether e-mail delivery is on.

-
Fill in the form and click Create Dispatcher.

The form has three parts:
- Key Collections - every key collection of this application, plus collections shared with it through links (marked shared from). Free Keys shows how many keys each collection can still hand out. Type an Order for the collections to use: the dispatcher takes keys from the collection with the lowest number until it runs out, then moves on to the next one. Leave the field empty to skip a collection. At least one collection is required.
- E-mail Delivery (optional) - your SendGrid settings, needed only for Patreon and PayPal. See E-mail Delivery. The saved API key is never shown again: leave the field empty to keep it. To turn e-mail delivery off, clear all three fields.
- Patreon Webhook Secret (optional) - needed only for Patreon. See Webhook Endpoint.
A key is free when it is not distributed, not blocked and not yet activated. If you also hand out keys manually, mark those keys as Distributed so the dispatcher skips them.
The Dispatcher Page
After you create a dispatcher, the Panel opens its page. You can always get back to it from the License Dispatchers section of the Keys tab.

The top of the page shows:
- Free keys left - the total for the whole dispatcher, followed by its collections in the order they are used, each with its own number of free keys. When it drops to zero, a warning appears and both endpoints stop handing out keys until you add a collection with free keys.
- E-mail delivery - whether keys are e-mailed for Patreon and PayPal, and from which address and SendGrid template.
- Edit and Delete buttons. Deleting a dispatcher stops its endpoints; the keys themselves stay untouched.
Below are the two endpoints, ready to copy:

- Acquire Endpoint - the URL to call from your server, a
curlexample and the possible responses. See Acquire Endpoint. - Webhook Endpoint - the URL to paste into Patreon, PayPal or MyCommerce. See Webhook Endpoint.
At the bottom, Regenerate Secret replaces the secret contained in both URLs.
Both endpoint URLs contain the dispatcher’s secret. Anyone who knows a URL can take your keys, so call it only from your server, never from a game or a web page. If a URL leaks, click Regenerate Secret: the old URLs stop working immediately and you will need to update your integrations.
Acquire Endpoint
Call it from your server once per purchase:
POST https://api2.patchkit.net/1/license_dispatchers/DISPATCHER_SECRET/acquire
| Parameter | Required | Description |
|---|---|---|
email |
yes | Buyer’s e-mail address. Saved in the key’s notes. |
Example:
curl -X POST "https://api2.patchkit.net/1/license_dispatchers/DISPATCHER_SECRET/acquire" \
-d "email=buyer@example.com"
Responses:
| Status | Body | Meaning |
|---|---|---|
200 |
{"license_key": "ABCD-EFGH-IJKL-MNOP"} |
The key for this buyer. |
400 |
{"message": "missing 'email' parameter"} |
The email parameter is missing. |
404 |
{"message": "Not Found"} |
Wrong URL, or the secret was regenerated. |
409 |
{"message": "no license key available"} |
No free keys left. Add a key collection to the dispatcher. |
The Acquire endpoint does not send e-mails. Deliver the key to the buyer yourself, for example on your order confirmation page.
Every successful call takes a new key, even for the same e-mail address. Store the returned key with the order on your side, and do not retry a call that already returned 200.
Parallel calls are safe: each call gets a different key.
Webhook Endpoint
Paste this URL into your payment provider’s webhook settings:
https://api2.patchkit.net/1/license_dispatchers/DISPATCHER_SECRET/webhook
The dispatcher recognizes the provider by the request and handles:
| Provider | Event | How the buyer gets the key |
|---|---|---|
| Patreon | members:create for a member who pledges more than 0. Followers are ignored. |
E-mail through your SendGrid account. |
| PayPal | CHECKOUT.ORDER.APPROVED. Other events are rejected with 404. |
E-mail through your SendGrid account. |
| MyCommerce | Remote key generator call. Test calls (IS_TEST=true) return TEST-KEY and do not use a key. |
Returned in the response; MyCommerce delivers it. |
Patreon requests must be signed. Copy the webhook secret from Patreon into the dispatcher’s Patreon Webhook Secret field. Requests with a wrong signature are rejected with 404.
PayPal requests are not signature-verified. Treat the webhook URL as a secret.
E-mail Delivery
Patreon and PayPal need e-mail delivery, configured on the dispatcher with your own SendGrid account:
- SendGrid API Key - with permission to send mail.
- SendGrid Dynamic Template ID - the template of the e-mail, for example
d-1234.... - Sender E-mail - a sender address verified in SendGrid.
The template receives these variables:
{
"license_key": "ABCD-EFGH-IJKL-MNOP",
"recipient": {
"full_name": "Jane Doe",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com"
},
"payload": { }
}
payload is the full Patreon webhook body; it is null for PayPal. In the template, use for example {{license_key}} and {{recipient.first_name}}.
If e-mail delivery is not configured, Patreon and PayPal calls fail with 422 and no key is used. If no free keys are left, they fail with 409.