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

# Poll Events

> Retrieve stored webhook events by polling — the catch-up path for hosted and custom webhooks

Fetch the stored events of the webhook's account, oldest first, filtered exactly like the webhook itself (`events` subscription and `message_type` for custom webhooks, `message_type` only for hosted ones). Served from our store: **no LinkedIn traffic** on the account.

Use it as a polling alternative to the SSE stream (hosted mode), or to **catch up after an outage on your side** (custom mode) instead of re-syncing the inbox.

<Note>
  Available for **hosted and custom** webhooks. Events are stored for **30 days** then automatically deleted. To re-push missed events to your URL instead, see [Delivery & retries](/api-reference/v2/webhooks/introduction#delivery-retries-custom-mode).
</Note>

### Header Parameters

<ParamField header="x-api-key" type="string" required>
  Your API key
</ParamField>

### Path Parameters

<ParamField path="webhook_id" type="string" required>
  The unique identifier of the webhook
</ParamField>

### Query Parameters

<ParamField query="since" type="string">
  ISO 8601 datetime to fetch events after. Only events created **after** this timestamp are returned.

  Example: `2025-01-15T10:30:00Z`
</ParamField>

<ParamField query="until" type="string">
  ISO 8601 datetime. Only events created **at or before** this timestamp are returned.
</ParamField>

<ParamField query="after" type="string">
  Cursor: the `event_id` of the last event you processed. Returns the events stored after it. Prefer this over `since` for paging — it is stable even when several events share a timestamp.
</ParamField>

<ParamField query="count" type="integer" default="50">
  Maximum number of events to return. Between 1 and 200.
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  Whether the request was successful
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="Properties">
    <ResponseField name="items" type="array">
      List of events, sorted by `created_at` ascending

      <Expandable title="Event Object">
        <ResponseField name="event_id" type="string">
          Unique event identifier
        </ResponseField>

        <ResponseField name="event" type="object">
          The full event payload (see [Event Types](/api-reference/v2/webhooks/introduction#event-types))
        </ResponseField>

        <ResponseField name="created_at" type="string">
          ISO 8601 timestamp of when the event was stored
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="next_cursor" type="string">
      `event_id` of the last item when the page is full — pass it as `after` to get the next page. `null` when there is nothing more.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseExample>
  ```json Success Response theme={null}
  {
    "success": true,
    "data": {
      "items": [
        {
          "event_id": "6789abcdef0123456789ab01",
          "event": {
            "account_id": "69c127c37cae0494dd827286",
            "account_name": "My Account",
            "platform": "linkedin",
            "event": {
              "type": "message",
              "sender_name": "John Doe",
              "message_text": "Hello!",
              "sender_profile": "https://www.linkedin.com/in/johndoe"
            },
            "timestamp": "2025-01-15T10:31:00Z"
          },
          "created_at": "2025-01-15T10:31:00.123Z"
        }
      ]
    },
    "metadata": {
      "action": "poll_webhook_events",
      "credits_consumed": 0,
      "timestamp": "2025-01-15T10:35:00.000000"
    }
  }
  ```

  ```json No Events theme={null}
  {
    "success": true,
    "data": {
      "items": []
    },
    "metadata": {
      "action": "poll_webhook_events",
      "credits_consumed": 0,
      "timestamp": "2025-01-15T10:35:00.000000"
    }
  }
  ```
</ResponseExample>

### Polling Pattern

```javascript theme={null}
let lastPollTime = new Date().toISOString();

setInterval(async () => {
  const res = await fetch(
    `https://api.linkupapi.com/v2/webhooks/${webhookId}/events?since=${lastPollTime}&limit=100`,
    { headers: { 'x-api-key': 'YOUR_API_KEY' } }
  );
  const { data } = await res.json();

  for (const item of data.items) {
    console.log('Event:', item.event);
    lastPollTime = item.created_at; // move cursor forward
  }
}, 10000); // poll every 10 seconds
```

### Notes

* Events are stored for **30 days** (TTL) then automatically deleted
* Polling does **not** consume additional credits beyond the monitoring cost
* Use the `since` parameter to avoid re-processing events
* For real-time delivery, prefer the [SSE Stream](/api-reference/v2/webhooks/stream) endpoint
