Integrations

This page covers programmatic integrations that sit between PatchKit and systems you control: Webhooks (PatchKit notifies your server when something happens) and Secure Running (your shipped game verifies a license key against PatchKit’s Keys service at runtime).

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:

  1. Go to the Applications page.
  2. Select one of your applications.
  3. Click on the Webhooks tab.
  4. 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 as application/json) or form (sent as application/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 — the product_key value from app_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.