> This is Payabli documentation. For a complete page index, fetch https://docs.payabli.com/llms.txt — append .md to any page URL for lightweight markdown. For section-level indexes, query parameters, and other AI-optimized access methods, see https://docs.payabli.com/ai-agents.md

# Review notification logs with the API

> Learn how to use the Payabli API to search notification deliveries, read why one failed, and retry it

Payabli records a log entry for every notification it sends, whether that's a webhook delivery, an email, an SMS, or a generated report. Use the notification logs API to confirm a notification reached its destination, find out why one didn't, and send it again from your own tooling.

To work through logs in the Payabli Portal instead, see [Review notification logs (Portal)](/guides/pay-ops-portal-notification-logs-review). For how Payabli delivers and retries notifications, see [Notifications overview](/guides/pay-ops-notifications-webhooks-overview).

## Considerations

Keep these considerations in mind when working with the notification logs API:

* The endpoints require the `notifications_read` or `notifications_create` permission. Retrying a notification requires `notifications_create`.
* Each search must scope to an organization or a paypoint, so pass either `orgId` or `paypointId`.
* A search window can't span more than 30 days between `startDate` and `endDate`.
* Payabli can't retry some notifications at all, such as password-reset emails.

## Search notification logs

Send a POST request to `/v2/notificationlogs` to search for notifications within a date range. Filter by event, delivery outcome, and owning entity, and page through the results. See the [API reference](/developers/api-reference/notification-logs/search-notification-logs-with-filtering-and-pagination) for full documentation.

This example returns the first 20 successful `approvedpayment` notifications for an organization in January 2024:

### Request

POST [https://api-sandbox.payabli.com/api/v2/notificationlogs](https://api-sandbox.payabli.com/api/v2/notificationlogs)

```curl
curl -X POST "https://api-sandbox.payabli.com/api/v2/notificationlogs?PageSize=20" \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{
  "startDate": "2024-01-01T00:00:00Z",
  "endDate": "2024-01-31T23:59:59Z",
  "notificationEvent": "approvedpayment",
  "succeeded": true,
  "orgId": 123
}'
```

```typescript
import { PayabliClient } from "@payabli/sdk-node";

async function main() {
    const client = new PayabliClient({
        bearerAuth: {
            clientId: "YOUR_CLIENT_ID",
            clientSecret: "YOUR_CLIENT_SECRET",
        },
    });
    await client.notificationlogs.searchNotificationLogs({
        PageSize: 20,
        startDate: "2024-01-01T00:00:00Z",
        endDate: "2024-01-31T23:59:59Z",
        notificationEvent: "approvedpayment",
        succeeded: true,
        orgId: 123,
    });
}
main();

```

```python
from payabli import payabli
import datetime

client = payabli(
    client_id="YOUR_CLIENT_ID",
    client_secret="YOUR_CLIENT_SECRET",
)

client.notificationlogs.search_notification_logs(
    page_size=20,
    start_date=datetime.datetime.fromisoformat("2024-01-01T00:00:00+00:00"),
    end_date=datetime.datetime.fromisoformat("2024-01-31T23:59:59+00:00"),
    notification_event="approvedpayment",
    succeeded=True,
    org_id=123,
)

```

```java
package com.example.usage;

import io.github.payabli.api.PayabliApiClient;
import io.github.payabli.api.resources.notificationlogs.requests.SearchNotificationLogsRequest;
import java.time.OffsetDateTime;

public class Example {
    public static void main(String[] args) {
        PayabliApiClient client = PayabliApiClient.withCredentials("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")
            .build()
        ;

        client.notificationlogs().searchNotificationLogs(
            SearchNotificationLogsRequest
                .builder()
                .startDate(OffsetDateTime.parse("2024-01-01T00:00:00Z"))
                .endDate(OffsetDateTime.parse("2024-01-31T23:59:59Z"))
                .pageSize(20)
                .notificationEvent("approvedpayment")
                .succeeded(true)
                .orgId(123L)
                .build()
        );
    }
}
```

```ruby
require "payabli"

client = Payabli::Client.new(api_key: "YOUR_API_KEY_HERE")

client.notificationlogs.search_notification_logs(
  page_size: 20,
  start_date: "2024-01-01T00:00:00Z",
  end_date: "2024-01-31T23:59:59Z",
  notification_event: "approvedpayment",
  succeeded: true,
  org_id: 123
)

```

```csharp
using PayabliApi;
using System.Threading.Tasks;
using System;
using System.Globalization;

public partial class Examples
{
    public async Task Example() {
        var client = new PayabliApiClient(
            clientId: "YOUR_CLIENT_ID",
            clientSecret: "YOUR_CLIENT_SECRET"
        );

        await client.Notificationlogs.SearchNotificationLogsAsync(
            new SearchNotificationLogsRequest {
                PageSize = 20,
                StartDate = DateTime.Parse("2024-01-01T00:00:00Z", null, DateTimeStyles.AdjustToUniversal),
                EndDate = DateTime.Parse("2024-01-31T23:59:59Z", null, DateTimeStyles.AdjustToUniversal),
                NotificationEvent = "approvedpayment",
                Succeeded = true,
                OrgId = 123L
            }
        );
    }

}

```

```go
package example

import (
    context "context"

    payabli "github.com/payabli/sdk-go"
    client "github.com/payabli/sdk-go/client"
    option "github.com/payabli/sdk-go/option"
)

func do() {
    client := client.NewClient(
        option.WithClientCredentials(
            "YOUR_CLIENT_ID",
            "YOUR_CLIENT_SECRET",
        ),
    )
    request := &payabli.SearchNotificationLogsRequest{
        PageSize: payabli.Int(
            20,
        ),
        StartDate: payabli.MustParseDateTime(
            "2024-01-01T00:00:00Z",
        ),
        EndDate: payabli.MustParseDateTime(
            "2024-01-31T23:59:59Z",
        ),
        NotificationEvent: payabli.String(
            "approvedpayment",
        ),
        Succeeded: payabli.Bool(
            true,
        ),
        OrgId: payabli.Int64(
            int64(123),
        ),
    }
    client.Notificationlogs.SearchNotificationLogs(
        context.TODO(),
        request,
    )
}

```

```php
<?php

namespace Example;

use Payabli\PayabliClient;
use Payabli\Notificationlogs\Requests\SearchNotificationLogsRequest;
use DateTime;

$client = new PayabliClient(
    clientId: 'YOUR_CLIENT_ID',
    clientSecret: 'YOUR_CLIENT_SECRET',
);
$client->notificationlogs->searchNotificationLogs(
    new SearchNotificationLogsRequest([
        'pageSize' => 20,
        'startDate' => new DateTime('2024-01-01T00:00:00Z'),
        'endDate' => new DateTime('2024-01-31T23:59:59Z'),
        'notificationEvent' => 'approvedpayment',
        'succeeded' => true,
        'orgId' => 123,
    ]),
);

```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "startDate": "2024-01-01T00:00:00Z",
  "endDate": "2024-01-31T23:59:59Z",
  "notificationEvent": "approvedpayment",
  "succeeded": true,
  "orgId": 123
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api-sandbox.payabli.com/api/v2/notificationlogs?PageSize=20")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

A successful response returns an array of matching log entries, newest first:

### Response (200)

```json
[
  {
    "organizationLogo": "https://example.com/org-logo.png",
    "organizationFavIcon": "https://example.com/org-favicon.png",
    "paypointLogo": "https://example.com/paypoint-logo.png",
    "notificationType": 1,
    "organizationName": "The Pilgrim Planner",
    "paypointName": "Pilgrim Planner",
    "requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "orgId": 123,
    "paypointId": 3040,
    "notificationEvent": "approvedpayment",
    "target": "https://webhook.example.com/payments",
    "responseStatusCode": 200,
    "responseStatus": "OK",
    "success": true,
    "jobData": "{\"transactionId\":\"txn_123\"}",
    "createdDate": "2024-01-15T10:30:00Z",
    "successDate": "2024-01-15T10:30:05Z",
    "lastFailedDate": null,
    "isInProgress": false
  }
]
```

Each entry's `notificationType` identifies the delivery method: `1` (Email), `2` (SMS), or `3` (Webhook).

### Filter the search

Pass any of these fields in the request body to narrow the results:

| Field               | Type    | Description                                                                   |
| ------------------- | ------- | ----------------------------------------------------------------------------- |
| `startDate`         | string  | The start of the search window. Required.                                     |
| `endDate`           | string  | The end of the search window, no more than 30 days after the start. Required. |
| `orgId`             | integer | The organization to search. Pass this or `paypointId`.                        |
| `paypointId`        | integer | The paypoint to search. Pass this or `orgId`.                                 |
| `notificationEvent` | string  | The event to match, such as `approvedpayment`. Case-insensitive.              |
| `succeeded`         | boolean | The delivery outcome. Set to `false` to return only failed deliveries.        |

Set the page size and page with the `PageSize` and `Page` query parameters. To triage failures, filter with `succeeded: false` and read the delivery fields on each entry.

### Read the delivery outcome

Three fields tell you what happened to a delivery:

* `success` is `true` when the target accepted the delivery and `false` when it didn't.
* `responseStatusCode` is the HTTP status code the target returned, such as `200` or `500`. It's `0` when the target sent no response.
* `responseStatus` is the status message, such as `OK`, `Dropped`, or `No response received from server.`

Read `successDate` and `lastFailedDate` together to see the delivery's history. A `lastFailedDate` with no `successDate` means the delivery has failed and hasn't succeeded since. Automatic retries may still be running, so check `isInProgress` before you step in.

## Get notification details

Send a GET request to `/v2/notificationlogs/{uuid}` to retrieve one entry with the full request and response Payabli captured. See the [API reference](/developers/api-reference/notification-logs/get-notification-log) for full documentation.

### Request

GET [https://api-sandbox.payabli.com/api/v2/notificationlogs/\{uuid}](https://api-sandbox.payabli.com/api/v2/notificationlogs/\{uuid})

```curl
curl https://api-sandbox.payabli.com/api/v2/notificationlogs/550e8400-e29b-41d4-a716-446655440000 \
     -H "Authorization: Bearer <token>"
```

```typescript
import { PayabliClient } from "@payabli/sdk-node";

async function main() {
    const client = new PayabliClient({
        bearerAuth: {
            clientId: "YOUR_CLIENT_ID",
            clientSecret: "YOUR_CLIENT_SECRET",
        },
    });
    await client.notificationlogs.getNotificationLog("550e8400-e29b-41d4-a716-446655440000");
}
main();

```

```python
from payabli import payabli

client = payabli(
    client_id="YOUR_CLIENT_ID",
    client_secret="YOUR_CLIENT_SECRET",
)

client.notificationlogs.get_notification_log(
    uuid_="550e8400-e29b-41d4-a716-446655440000",
)

```

```java
package com.example.usage;

import io.github.payabli.api.PayabliApiClient;

public class Example {
    public static void main(String[] args) {
        PayabliApiClient client = PayabliApiClient.withCredentials("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")
            .build()
        ;

        client.notificationlogs().getNotificationLog("550e8400-e29b-41d4-a716-446655440000");
    }
}
```

```ruby
require "payabli"

client = Payabli::Client.new(api_key: "YOUR_API_KEY_HERE")

client.notificationlogs.get_notification_log(uuid: "550e8400-e29b-41d4-a716-446655440000")

```

```csharp
using PayabliApi;
using System.Threading.Tasks;

public partial class Examples
{
    public async Task Example() {
        var client = new PayabliApiClient(
            clientId: "YOUR_CLIENT_ID",
            clientSecret: "YOUR_CLIENT_SECRET"
        );

        await client.Notificationlogs.GetNotificationLogAsync(
            "550e8400-e29b-41d4-a716-446655440000"
        );
    }

}

```

```go
package example

import (
    context "context"

    client "github.com/payabli/sdk-go/client"
    option "github.com/payabli/sdk-go/option"
)

func do() {
    client := client.NewClient(
        option.WithClientCredentials(
            "YOUR_CLIENT_ID",
            "YOUR_CLIENT_SECRET",
        ),
    )
    client.Notificationlogs.GetNotificationLog(
        context.TODO(),
        "550e8400-e29b-41d4-a716-446655440000",
    )
}

```

```php
<?php

namespace Example;

use Payabli\PayabliClient;

$client = new PayabliClient(
    clientId: 'YOUR_CLIENT_ID',
    clientSecret: 'YOUR_CLIENT_SECRET',
);
$client->notificationlogs->getNotificationLog(
    '550e8400-e29b-41d4-a716-446655440000',
);

```

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api-sandbox.payabli.com/api/v2/notificationlogs/550e8400-e29b-41d4-a716-446655440000")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

Alongside the core notification fields, the detail response adds what left Payabli and what came back:

* `webHeaders` are the custom headers Payabli sent with the notification, if any.
* `responseHeaders` are the headers the target returned, or null when the target sent no response.
* `responseContent` is the body the target returned, or empty when the target sent no response.

### Response (200)

```json
{
  "webHeaders": [
    {
      "key": "Content-Type",
      "value": "application/json"
    },
    {
      "key": "User-Agent",
      "value": "PaymentSystem/1.0"
    }
  ],
  "responseHeaders": [
    {
      "key": "Content-Type",
      "value": [
        "application/json"
      ]
    },
    {
      "key": "X-Request-ID",
      "value": [
        "req_abc123"
      ]
    }
  ],
  "responseContent": "{\"status\":\"received\",\"id\":\"wh_123\"}",
  "organizationName": "The Pilgrim Planner",
  "paypointName": "Pilgrim Planner",
  "requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "orgId": 123,
  "paypointId": 3040,
  "notificationEvent": "approvedpayment",
  "target": "https://webhook.example.com/payments",
  "responseStatusCode": 200,
  "responseStatus": "OK",
  "success": true,
  "jobData": "{\"transactionId\":\"txn_123\"}",
  "createdDate": "2024-01-15T10:30:00Z",
  "successDate": "2024-01-15T10:30:05Z",
  "lastFailedDate": null,
  "isInProgress": false
}
```

The `webHeaders` array shows those custom headers exactly as Payabli sent them.

`webHeaders` includes any custom headers configured on the webhook, with their values in plain text. Redact them before sharing a response in a ticket or a screenshot.

### Tell a rejected delivery from an unreachable one

The `responseStatusCode` separates the two failures that look alike in a search:

* A status code, such as `401` or `500`, means your endpoint received the request and rejected it. Read `responseContent` for what your server returned, then fix the endpoint before you retry.
* A `responseStatusCode` of `0`, with `responseStatus` reading `No response received from server.`, means Payabli couldn't reach the endpoint. Confirm the URL is right and publicly reachable before you retry.

## Retry a failed notification

Payabli retries a failed webhook twice on its own, waiting 5 minutes between tries. After the second failed retry, it marks the delivery failed and leaves it for you to retry. Fix whatever caused the failure first, because a retry to an endpoint that's still broken fails the same way.

Send a GET request to `/v2/notificationlogs/{uuid}/retry` to retry a single notification. See the [API reference](/developers/api-reference/notification-logs/retry-notification-log) for full documentation.

### Request

GET [https://api-sandbox.payabli.com/api/v2/notificationlogs/\{uuid}/retry](https://api-sandbox.payabli.com/api/v2/notificationlogs/\{uuid}/retry)

```curl
curl https://api-sandbox.payabli.com/api/v2/notificationlogs/550e8400-e29b-41d4-a716-446655440000/retry \
     -H "Authorization: Bearer <token>"
```

```typescript
import { PayabliClient } from "@payabli/sdk-node";

async function main() {
    const client = new PayabliClient({
        bearerAuth: {
            clientId: "YOUR_CLIENT_ID",
            clientSecret: "YOUR_CLIENT_SECRET",
        },
    });
    await client.notificationlogs.retryNotificationLog("550e8400-e29b-41d4-a716-446655440000");
}
main();

```

```python
from payabli import payabli

client = payabli(
    client_id="YOUR_CLIENT_ID",
    client_secret="YOUR_CLIENT_SECRET",
)

client.notificationlogs.retry_notification_log(
    uuid_="550e8400-e29b-41d4-a716-446655440000",
)

```

```java
package com.example.usage;

import io.github.payabli.api.PayabliApiClient;

public class Example {
    public static void main(String[] args) {
        PayabliApiClient client = PayabliApiClient.withCredentials("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")
            .build()
        ;

        client.notificationlogs().retryNotificationLog("550e8400-e29b-41d4-a716-446655440000");
    }
}
```

```ruby
require "payabli"

client = Payabli::Client.new(api_key: "YOUR_API_KEY_HERE")

client.notificationlogs.retry_notification_log(uuid: "550e8400-e29b-41d4-a716-446655440000")

```

```csharp
using PayabliApi;
using System.Threading.Tasks;

public partial class Examples
{
    public async Task Example() {
        var client = new PayabliApiClient(
            clientId: "YOUR_CLIENT_ID",
            clientSecret: "YOUR_CLIENT_SECRET"
        );

        await client.Notificationlogs.RetryNotificationLogAsync(
            "550e8400-e29b-41d4-a716-446655440000"
        );
    }

}

```

```go
package example

import (
    context "context"

    client "github.com/payabli/sdk-go/client"
    option "github.com/payabli/sdk-go/option"
)

func do() {
    client := client.NewClient(
        option.WithClientCredentials(
            "YOUR_CLIENT_ID",
            "YOUR_CLIENT_SECRET",
        ),
    )
    client.Notificationlogs.RetryNotificationLog(
        context.TODO(),
        "550e8400-e29b-41d4-a716-446655440000",
    )
}

```

```php
<?php

namespace Example;

use Payabli\PayabliClient;

$client = new PayabliClient(
    clientId: 'YOUR_CLIENT_ID',
    clientSecret: 'YOUR_CLIENT_SECRET',
);
$client->notificationlogs->retryNotificationLog(
    '550e8400-e29b-41d4-a716-446655440000',
);

```

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api-sandbox.payabli.com/api/v2/notificationlogs/550e8400-e29b-41d4-a716-446655440000/retry")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

Payabli resends the notification to its target and returns a confirmation message, not the updated log entry. Search for the notification again to confirm whether `successDate` fills in.

### Response (200)

```json
{
  "message": "Notification retry succeeded."
}
```

## Retry several notifications

Send a POST request to `/v2/notificationlogs/retry` with an array of up to 50 notification IDs to retry them together. See the [API reference](/developers/api-reference/notification-logs/bulk-retry-notification-logs) for full documentation.

### Request

POST [https://api-sandbox.payabli.com/api/v2/notificationlogs/retry](https://api-sandbox.payabli.com/api/v2/notificationlogs/retry)

```curl
curl -X POST https://api-sandbox.payabli.com/api/v2/notificationlogs/retry \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '[
  "550e8400-e29b-41d4-a716-446655440000",
  "550e8400-e29b-41d4-a716-446655440001",
  "550e8400-e29b-41d4-a716-446655440002"
]'
```

```typescript
import { PayabliClient } from "@payabli/sdk-node";

async function main() {
    const client = new PayabliClient({
        bearerAuth: {
            clientId: "YOUR_CLIENT_ID",
            clientSecret: "YOUR_CLIENT_SECRET",
        },
    });
    await client.notificationlogs.bulkRetryNotificationLogs([
        "550e8400-e29b-41d4-a716-446655440000",
        "550e8400-e29b-41d4-a716-446655440001",
        "550e8400-e29b-41d4-a716-446655440002",
    ]);
}
main();

```

```python
from payabli import payabli

client = payabli(
    client_id="YOUR_CLIENT_ID",
    client_secret="YOUR_CLIENT_SECRET",
)

client.notificationlogs.bulk_retry_notification_logs(
    request=[
        "550e8400-e29b-41d4-a716-446655440000",
        "550e8400-e29b-41d4-a716-446655440001",
        "550e8400-e29b-41d4-a716-446655440002"
    ],
)

```

```java
package com.example.usage;

import io.github.payabli.api.PayabliApiClient;
import java.util.Arrays;

public class Example {
    public static void main(String[] args) {
        PayabliApiClient client = PayabliApiClient.withCredentials("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")
            .build()
        ;

        client.notificationlogs().bulkRetryNotificationLogs(
            Arrays.asList("550e8400-e29b-41d4-a716-446655440000", "550e8400-e29b-41d4-a716-446655440001", "550e8400-e29b-41d4-a716-446655440002")
        );
    }
}
```

```ruby
require "payabli"

client = Payabli::Client.new(api_key: "YOUR_API_KEY_HERE")

client.notificationlogs.bulk_retry_notification_logs(request: %w[550e8400-e29b-41d4-a716-446655440000 550e8400-e29b-41d4-a716-446655440001 550e8400-e29b-41d4-a716-446655440002])

```

```csharp
using PayabliApi;
using System.Threading.Tasks;
using System.Collections.Generic;

public partial class Examples
{
    public async Task Example() {
        var client = new PayabliApiClient(
            clientId: "YOUR_CLIENT_ID",
            clientSecret: "YOUR_CLIENT_SECRET"
        );

        await client.Notificationlogs.BulkRetryNotificationLogsAsync(
            new List<string>(){
                "550e8400-e29b-41d4-a716-446655440000",
                "550e8400-e29b-41d4-a716-446655440001",
                "550e8400-e29b-41d4-a716-446655440002",
            }
        );
    }

}

```

```go
package example

import (
    context "context"

    client "github.com/payabli/sdk-go/client"
    option "github.com/payabli/sdk-go/option"
)

func do() {
    client := client.NewClient(
        option.WithClientCredentials(
            "YOUR_CLIENT_ID",
            "YOUR_CLIENT_SECRET",
        ),
    )
    request := []string{
        "550e8400-e29b-41d4-a716-446655440000",
        "550e8400-e29b-41d4-a716-446655440001",
        "550e8400-e29b-41d4-a716-446655440002",
    }
    client.Notificationlogs.BulkRetryNotificationLogs(
        context.TODO(),
        request,
    )
}

```

```php
<?php

namespace Example;

use Payabli\PayabliClient;

$client = new PayabliClient(
    clientId: 'YOUR_CLIENT_ID',
    clientSecret: 'YOUR_CLIENT_SECRET',
);
$client->notificationlogs->bulkRetryNotificationLogs(
    [
        '550e8400-e29b-41d4-a716-446655440000',
        '550e8400-e29b-41d4-a716-446655440001',
        '550e8400-e29b-41d4-a716-446655440002',
    ],
);

```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["550e8400-e29b-41d4-a716-446655440000", "550e8400-e29b-41d4-a716-446655440001", "550e8400-e29b-41d4-a716-446655440002"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api-sandbox.payabli.com/api/v2/notificationlogs/retry")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

A bulk retry covers only failed webhooks and excludes emails. It runs asynchronously, so the response confirms only that Payabli accepted the request. Search the logs again after 2 to 5 minutes and check whether `successDate` fills in to confirm each delivery landed.

## Related resources

See these related resources to help you get the most out of Payabli.

#### Prerequisites

* **[Notifications and reports overview](/guides/pay-ops-notifications-webhooks-overview)** - Get automated reports and notifications for key events

#### References

* **[Search notification logs](/developers/api-reference/notification-logs/search-notification-logs-with-filtering-and-pagination)** - Search notification deliveries through the API

#### Related topics

* **[Review notification logs (Portal)](/guides/pay-ops-portal-notification-logs-review)** - Find a notification Payabli sent, see why a delivery failed, and retry it
* **[Manage notifications](/guides/pay-ops-developer-notifications-manage)** - Learn how to use the Payabli API to add notifications and automated reports for important events
* **[Webhook quickstart](/guides/pay-ops-developer-webhooks-quickstart)** - Learn to use example code to set up webhooks for payment notifications