> ## Documentation Index
> Fetch the complete documentation index at: https://developer.payrollintegrations.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Subscriptions

Webhooks allow users to receive automatic notifications when events occur in the Payroll Integrations system.

<Note>
  Need webhook access? Contact [partnerships@payrollintegrations.com](mailto:partnerships@payrollintegrations.com) to have
  the `api-user-webhook-subscription` role assigned to your API user.
</Note>

## Event Types

| Event                        | Description                                                     |
| :--------------------------- | :-------------------------------------------------------------- |
| `PAYROLL_PROCESSED`          | A payroll job has finished processing                           |
| `UPDATE_GROUP_PROCESSED`     | A bulk deduction/loan update group has been processed           |
| `EMPLOYEE_CENSUS_HIRED`      | A new employee has been added to the census                     |
| `EMPLOYEE_CENSUS_UPDATED`    | Employee census data has been updated                           |
| `EMPLOYEE_CENSUS_TERMINATED` | An employee has been marked as terminated, deceased, or retired |

***

## Create a Subscription

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "event_types": ["PAYROLL_PROCESSED", "UPDATE_GROUP_PROCESSED"],
      "path": "https://your-domain.com/webhooks"
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions",
      headers={
          "Authorization": "Bearer YOUR_ACCESS_TOKEN",
          "Content-Type": "application/json",
      },
      json={
          "event_types": ["PAYROLL_PROCESSED", "UPDATE_GROUP_PROCESSED"],
          "path": "https://your-domain.com/webhooks",
      },
  )
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
      "https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions",
      {
          method: "POST",
          headers: {
              Authorization: "Bearer YOUR_ACCESS_TOKEN",
              "Content-Type": "application/json",
          },
          body: JSON.stringify({
              event_types: ["PAYROLL_PROCESSED", "UPDATE_GROUP_PROCESSED"],
              path: "https://your-domain.com/webhooks",
          }),
      },
  );
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();

  curl_setopt($ch, CURLOPT_URL, "https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions");
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Authorization: Bearer YOUR_ACCESS_TOKEN",
      "Content-Type: application/json"
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
      "event_types" => ["PAYROLL_PROCESSED", "UPDATE_GROUP_PROCESSED"],
      "path" => "https://your-domain.com/webhooks"
  ]));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  curl_close($ch);
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "net/http"
  )

  func main() {
      body := []byte(`{
          "event_types": ["PAYROLL_PROCESSED", "UPDATE_GROUP_PROCESSED"],
          "path": "https://your-domain.com/webhooks"
      }`)

      req, _ := http.NewRequest("POST",
          "https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions",
          bytes.NewBuffer(body))
      req.Header.Set("Authorization", "Bearer YOUR_ACCESS_TOKEN")
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, _ := client.Do(req)
      defer resp.Body.Close()
  }
  ```

  ```java Java theme={null}
  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions"))
      .header("Authorization", "Bearer YOUR_ACCESS_TOKEN")
      .header("Content-Type", "application/json")
      .POST(HttpRequest.BodyPublishers.ofString("""
          {
            "event_types": ["PAYROLL_PROCESSED", "UPDATE_GROUP_PROCESSED"],
            "path": "https://your-domain.com/webhooks"
          }
          """))
      .build();

  HttpResponse<String> response = HttpClient.newHttpClient()
      .send(request, HttpResponse.BodyHandlers.ofString());
  ```

  ```ruby Ruby theme={null}
  require "net/http"
  require "json"

  uri = URI("https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Post.new(uri)
  request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"
  request["Content-Type"] = "application/json"
  request.body = {
    event_types: ["PAYROLL_PROCESSED", "UPDATE_GROUP_PROCESSED"],
    path: "https://your-domain.com/webhooks"
  }.to_json

  response = http.request(request)
  ```
</CodeGroup>

| Field         | Description                                                                                                                                                               |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event_types` | Array of events to subscribe to. Options: `PAYROLL_PROCESSED`, `UPDATE_GROUP_PROCESSED`, `EMPLOYEE_CENSUS_HIRED`, `EMPLOYEE_CENSUS_UPDATED`, `EMPLOYEE_CENSUS_TERMINATED` |
| `path`        | The HTTPS endpoint that will receive webhook notifications                                                                                                                |

**Response:** `201 Created`

***

## Modify a Subscription

Direct modification isn't supported. To change event types or the destination URL:

1. **Create** a new subscription with the desired list of events
2. **Delete** the existing subscription

<Warning>
  If the existing subscription is deleted before creating the new
  subscription, event notifications may be missed during the brief gap between
  deletion and creation.
</Warning>

***

## Delete a Subscription

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions/{subscription_id} \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  response = requests.delete(
      "https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions/{subscription_id}",
      headers={
          "Authorization": "Bearer YOUR_ACCESS_TOKEN",
      },
  )
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
      "https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions/{subscription_id}",
      {
          method: "DELETE",
          headers: {
              Authorization: "Bearer YOUR_ACCESS_TOKEN",
          },
      },
  );
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();

  curl_setopt($ch, CURLOPT_URL, "https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions/{subscription_id}");
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ]);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  curl_close($ch);
  ```

  ```go Go theme={null}
  package main

  import "net/http"

  func main() {
      req, _ := http.NewRequest("DELETE",
          "https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions/{subscription_id}",
          nil)
      req.Header.Set("Authorization", "Bearer YOUR_ACCESS_TOKEN")

      client := &http.Client{}
      resp, _ := client.Do(req)
      defer resp.Body.Close()
  }
  ```

  ```java Java theme={null}
  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions/{subscription_id}"))
      .header("Authorization", "Bearer YOUR_ACCESS_TOKEN")
      .DELETE()
      .build();

  HttpResponse<String> response = HttpClient.newHttpClient()
      .send(request, HttpResponse.BodyHandlers.ofString());
  ```

  ```ruby Ruby theme={null}
  require "net/http"

  uri = URI("https://api.payrollintegrationsapp.com/v1/webhooks/subscriptions/{subscription_id}")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Delete.new(uri)
  request["Authorization"] = "Bearer YOUR_ACCESS_TOKEN"

  response = http.request(request)
  ```
</CodeGroup>

**Response:** `204 No Content`
