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

# Pull webhooks

> Poll your creditor’s pending webhook items and acknowledge processing

Pull webhooks let your integration fetch events on a schedule without hosting a
webhook receiver. Debbie stores each matching event as a `PENDING` webhook item.
Your job fetches the items, processes them, and marks each completed item as
`SUCCESS` so it is no longer returned by the pending filter.

## Before you start

Create an [API key](https://creditor-documentation.debbiecollect.com/api-reference/authentication.md) in the creditor portal under
**Developers → API** with `read:webhooks` to fetch items and `write:webhooks` to
create the subscription and acknowledge items. The same page shows your
`tenantId` and `creditorId`.

Replace `{tenantId}`, `{creditorId}` and `{token}` in the examples with those
values. Include `creditorId` as a query parameter on **every request**. Your
subscription and its items are restricted to your creditor.

## 1. Create a pull webhook

Use [Create webhook](https://creditor-documentation.debbiecollect.com/api-reference/endpoints/webhooks/create.md) with `pull: true`.
Include your creditor id both in the query string and in the body. No delivery
URL is needed:

```bash theme={null}
curl --request POST \
  "https://api.debbiecollect.com/v1/{tenantId}/webhooks?creditorId={creditorId}" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  --data '{
    "name": "ERP case sync",
    "creditorId": "{creditorId}",
    "events": ["cases.create"],
    "pull": true
  }'
```

Save the returned `id` as `{webhookId}`. A creditor webhook can subscribe to
`cases.create`, `cases.update`, `cases.delete` and `billings.create`. See the
[event reference](https://creditor-documentation.debbiecollect.com/api-reference/webhooks/introduction.md#events) for their payloads.

The **Pull webhooks** switch is available in the caseworker
platform under **Advanced settings → Other settings**, but is not shown in the
creditor portal. Use the API call above to create your pull subscription.

A pull webhook does not POST events to a URL. It collects new matching events
after creation; creating one does not export existing cases.

## 2. Fetch pending items

Set up a scheduled job that calls
[Get webhook items](https://creditor-documentation.debbiecollect.com/api-reference/endpoints/webhooks/get-items.md) with
`state=PENDING`. Filter by `webhookId` to fetch only this subscription's items:

```bash theme={null}
curl --get "https://api.debbiecollect.com/v1/{tenantId}/webhooks/items" \
  -H "Authorization: Bearer {token}" \
  --data-urlencode "creditorId={creditorId}" \
  --data-urlencode "state=PENDING" \
  --data-urlencode "webhookId={webhookId}" \
  --data-urlencode "page=0" \
  --data-urlencode "pageSize=20"
```

The response contains `items` and pagination `meta`. For example, with other
item fields omitted:

```json theme={null}
{
  "items": [
    {
      "id": "867ddc9d-ee15-4493-b7fe-f6fbd6bbe71b",
      "hookId": "b963f219-255e-47b7-a3f2-0fe6180514a1",
      "event": "cases.create",
      "state": "PENDING",
      "data": {
        "caseId": "3f1c2d4e-5a6b-4c8d-9e0f-1a2b3c4d5e6f",
        "id": 1042,
        "referenceId": "INV-2026-0042",
        "customerId": "9b8a7c6d-5e4f-4a2b-9c0d-9e8f7a6b5c4d",
        "creditorId": "0f6c7a3e-6e4e-4f0c-9a2a-2f6cba3f9a11"
      }
    }
  ],
  "meta": { "currentPage": 0, "pageSize": 20 }
}
```

Use `item.event` to choose how to process `item.data`. In this example,
`item.id` is the webhook item to acknowledge; `item.hookId` identifies the
subscription, and `item.data.id` is the case number. See
[cases.create](https://creditor-documentation.debbiecollect.com/api-reference/webhooks/cases.create.md) for this event's payload.
Fetching an item does not change its state or reserve it for your worker.

## 3. Acknowledge each processed item

After successfully processing and saving an item's result in your system, call
[Patch webhook item](https://creditor-documentation.debbiecollect.com/api-reference/endpoints/webhooks/patch-item.md) with that
item's `id` and `{"state":"SUCCESS"}`:

```bash theme={null}
curl --request PATCH \
  "https://api.debbiecollect.com/v1/{tenantId}/webhooks/items/{itemId}?creditorId={creditorId}" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  --data '{"state":"SUCCESS"}'
```

The endpoint returns `200` with `{}`. The item remains stored but no longer
appears in requests filtered by `state=PENDING`.

## 4. Fetch the next batch

After acknowledging a batch, repeat the GET request with **`page=0`**. Continue
until `items` is empty, then wait until the next scheduled poll.

> [!WARNING]
>
> Do not increment the page number while acknowledging items. Successful items
> leave the pending results, so the next batch moves to page 0. Requesting page
> 1 would skip pending items.

## Retries and duplicate processing

* If processing fails, leave the item `PENDING`. Record the failure and retry
  later. If a batch has failures, wait before fetching it again and alert on
  repeated failures rather than repeatedly polling the same items without a delay.
* If processing succeeds but the PATCH fails or times out, the item may appear
  again. Persist the processed `item.id` with your result so a retry can
  acknowledge it without repeating the work.
* Run one polling job per subscription at a time, or coordinate workers in your
  own system. Two workers can fetch the same pending item.
* Items are returned newest first. Do not assume that events for a case arrive
  in the order in which they occurred.

For an initial check, create a case after subscribing to `cases.create`, fetch
its pending item, and acknowledge it. Repeat the same pending request and
confirm that the item's `id` is no longer returned.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.