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

# Get Webhooks

> Retrieve all registered webhook endpoints for your merchant account

## Overview

The Get Webhooks endpoint returns a list of all webhook endpoints you've registered. Use this to view your webhook configurations, check their status, and retrieve webhook IDs for updates or deletions.

## Endpoint

```
GET https://webhooks.sbx.moduluslabs.io/v1/webhooks
```

## Authentication

This endpoint requires [HTTP Basic Authentication](/docs/qr/authentication) using your Secret Key.

```
Authorization: Basic {base64(secret_key:)}
```

## Request

### Headers

| Header          | Value                         | Required |
| --------------- | ----------------------------- | -------- |
| `Authorization` | `Basic {base64(secret_key:)}` | Yes      |
| `accept`        | `application/json`            | No       |

### Parameters

This endpoint does not accept any query parameters or request body.

## Response

### Success Response

**Status Code:** `200 OK`

Returns an array of webhook objects.

<ResponseField name="webhooks" type="array" required>
  Array of all registered webhooks for your merchant account. Returns an empty array `[]` if no webhooks are registered.

  Each webhook object contains:

  <Expandable title="Webhook Object Properties">
    <ResponseField name="id" type="integer" required>
      Unique identifier for the webhook.

      **Example:** `123`
    </ResponseField>

    <ResponseField name="webhookUrl" type="string" required>
      The HTTPS URL where webhook notifications are sent.

      **Example:** `"https://api.yourcompany.com/webhooks/modulus"`
    </ResponseField>

    <ResponseField name="actions" type="array" required>
      Array of webhook actions this endpoint receives.

      **Possible values:** `["QRPH_SUCCESS"]`, `["QRPH_DECLINED"]`, or `["QRPH_SUCCESS", "QRPH_DECLINED"]`

      **Example:** `["QRPH_SUCCESS", "QRPH_DECLINED"]`
    </ResponseField>

    <ResponseField name="status" type="string" required>
      Current webhook status.

      **Possible values:**

      * `ENABLED` - Webhook is active and receiving notifications
      * `DISABLED` - Webhook is registered but not receiving notifications

      **Example:** `"ENABLED"`
    </ResponseField>

    <ResponseField name="createdAt" type="string" required>
      ISO 8601 timestamp of when the webhook was created.

      **Example:** `"2024-01-15T10:30:00Z"`
    </ResponseField>

    <ResponseField name="updatedAt" type="string" required>
      ISO 8601 timestamp of when the webhook was last updated.

      **Example:** `"2024-01-15T14:20:00Z"`
    </ResponseField>
  </Expandable>
</ResponseField>

### Response Examples

<CodeGroup>
  ```json Multiple Webhooks theme={null}
  {
    "webhooks": [
      {
        "id": 123,
        "webhookUrl": "https://api.yourcompany.com/webhooks/modulus",
        "actions": ["QRPH_SUCCESS", "QRPH_DECLINED"],
        "status": "ENABLED",
        "createdAt": "2024-01-15T10:30:00Z",
        "updatedAt": "2024-01-15T10:30:00Z"
      },
      {
        "id": 124,
        "webhookUrl": "https://backup.yourcompany.com/webhooks/modulus",
        "actions": ["QRPH_SUCCESS"],
        "status": "DISABLED",
        "createdAt": "2024-01-14T08:15:00Z",
        "updatedAt": "2024-01-15T12:00:00Z"
      }
    ]
  }
  ```

  ```json Single Webhook theme={null}
  {
    "webhooks": [
      {
        "id": 123,
        "webhookUrl": "https://api.yourcompany.com/webhooks/modulus",
        "actions": ["QRPH_SUCCESS", "QRPH_DECLINED"],
        "status": "ENABLED",
        "createdAt": "2024-01-15T10:30:00Z",
        "updatedAt": "2024-01-15T10:30:00Z"
      }
    ]
  }
  ```

  ```json No Webhooks theme={null}
  {
    "webhooks": []
  }
  ```
</CodeGroup>

<ResponseExample>
  ```json 200 Success theme={null}
  {
    "webhooks": [
      {
        "id": 123,
        "webhookUrl": "https://api.yourcompany.com/webhooks/modulus",
        "actions": ["QRPH_SUCCESS", "QRPH_DECLINED"],
        "status": "ENABLED",
        "createdAt": "2024-01-15T10:30:00Z",
        "updatedAt": "2024-01-15T10:30:00Z"
      }
    ]
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "code": "10000013",
    "error": "Invalid API Key",
    "referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
  }
  ```

  ```json 403 Forbidden theme={null}
  {
    "code": "10000015",
    "error": "Insufficient permissions",
    "referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
  }
  ```

  ```json 500 Internal Server Error theme={null}
  {
    "code": "10000001",
    "error": "An unexpected error occurred. Please try again later.",
    "referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
  }
  ```
</ResponseExample>

### Error Responses

<AccordionGroup>
  <Accordion title="401 Unauthorized" icon="key">
    **Status Code:** `401`

    **Cause:** Invalid or missing authentication credentials

    **Response Example:**

    ```json theme={null}
    {
      "code": "20000001",
      "error": "Invalid or missing secret key",
      "referenceNumber": "abc123-def456-ghi789"
    }
    ```

    **Solution:**

    * Verify your secret key is correct
    * Ensure Authorization header format: `Basic {base64(secret_key:)}`
    * Check you're using the right environment (sandbox vs production)
  </Accordion>

  <Accordion title="403 Forbidden" icon="ban">
    **Status Code:** `403`

    **Cause:** Account disabled or API access revoked

    **Solution:**

    * Contact Modulus Labs support
    * Verify your account status
  </Accordion>

  <Accordion title="500 Internal Server Error" icon="server">
    **Status Code:** `500`

    **Cause:** Unexpected server error

    **Solution:**

    * Retry the request
    * If the issue persists, contact Modulus Labs support
  </Accordion>
</AccordionGroup>

<RequestExample>
  ```bash cURL theme={null}
  curl https://webhooks.sbx.moduluslabs.io/v1/webhooks \
    -u sk_your_secret_key:
  ```

  ```javascript Node.js theme={null}
  const axios = require('axios');
  const jose = require('jose');

  const SECRET_KEY = process.env.MODULUS_SECRET_KEY;
  const ENCRYPTION_KEY = process.env.MODULUS_ENCRYPTION_KEY;

  async function getWebhooks() {
    try {
      // Decode encryption key from base64
      const key = Buffer.from(ENCRYPTION_KEY, 'base64');

      const response = await axios.get(
        'https://webhooks.sbx.moduluslabs.io/v1/webhooks',
        {
          auth: {
            username: SECRET_KEY,
            password: ''
          }
        }
      );

      // Decrypt the response token
      const { plaintext } = await jose.compactDecrypt(
        response.data.response.Token,
        key
      );
      const webhooks = JSON.parse(new TextDecoder().decode(plaintext));

      console.log(`Found ${webhooks.length} webhook(s)`);

      webhooks.forEach(webhook => {
        console.log('\nWebhook ID:', webhook.id);
        console.log('URL:', webhook.callbackUrl);
        console.log('Action:', webhook.webhookAction);
        console.log('Status:', webhook.webhookStatus);
      });

      return webhooks;
    } catch (error) {
      if (error.response) {
        console.error('Error:', error.response.status);
        console.error('Details:', error.response.data);
      } else {
        console.error('Request failed:', error.message);
      }
      throw error;
    }
  }

  getWebhooks();
  ```

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

  SECRET_KEY = os.getenv('MODULUS_SECRET_KEY')

  def get_webhooks():
      try:
          response = requests.get(
              'https://webhooks.sbx.moduluslabs.io/v1/webhooks',
              auth=(SECRET_KEY, '')
          )

          response.raise_for_status()

          data = response.json()
          webhooks = data['webhooks']

          print(f"Found {len(webhooks)} webhook(s)")

          for webhook in webhooks:
              print(f"\nWebhook ID: {webhook['id']}")
              print(f"URL: {webhook['webhookUrl']}")
              print(f"Actions: {', '.join(webhook['actions'])}")
              print(f"Status: {webhook['status']}")
              print(f"Created: {webhook['createdAt']}")

          return webhooks

      except requests.exceptions.HTTPError as e:
          print(f' Error: {e.response.status_code}')
          print('Details:', e.response.json())
          raise
      except requests.exceptions.RequestException as e:
          print(f' Request failed: {str(e)}')
          raise

  if __name__ == '__main__':
      get_webhooks()
  ```

  ```php PHP theme={null}
  <?php

  $secretKey = getenv('MODULUS_SECRET_KEY');

  $ch = curl_init('https://webhooks.sbx.moduluslabs.io/v1/webhooks');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_USERPWD, $secretKey . ':');

  $response = curl_exec($ch);
  $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  if ($httpCode === 200) {
      $data = json_decode($response, true);
      $webhooks = $data['webhooks'];

      echo "Found " . count($webhooks) . " webhook(s)\n";

      foreach ($webhooks as $webhook) {
          echo "\nWebhook ID: {$webhook['id']}\n";
          echo "URL: {$webhook['webhookUrl']}\n";
          echo "Actions: " . implode(', ', $webhook['actions']) . "\n";
          echo "Status: {$webhook['status']}\n";
          echo "Created: {$webhook['createdAt']}\n";
      }
  } else {
      echo " Error: HTTP $httpCode\n";
      echo "Details: $response\n";
  }
  ```

  ```java Java theme={null}
  import java.net.http.*;
  import java.net.URI;
  import java.util.Base64;
  import com.google.gson.Gson;
  import com.google.gson.JsonObject;
  import com.google.gson.JsonArray;

  public class GetWebhooksExample {
      public static void main(String[] args) throws Exception {
          String secretKey = System.getenv("MODULUS_SECRET_KEY");

          // Create HTTP client
          HttpClient client = HttpClient.newHttpClient();

          // Encode credentials
          String auth = secretKey + ":";
          String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());

          // Build request
          HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("https://webhooks.sbx.moduluslabs.io/v1/webhooks"))
              .header("Authorization", "Basic " + encodedAuth)
              .GET()
              .build();

          // Send request
          HttpResponse<String> response = client.send(
              request,
              HttpResponse.BodyHandlers.ofString()
          );

          if (response.statusCode() == 200) {
              Gson gson = new Gson();
              JsonObject data = gson.fromJson(response.body(), JsonObject.class);
              JsonArray webhooks = data.getAsJsonArray("webhooks");

              System.out.println("Found " + webhooks.size() + " webhook(s)");

              for (int i = 0; i < webhooks.size(); i++) {
                  JsonObject webhook = webhooks.get(i).getAsJsonObject();
                  System.out.println("\nWebhook ID: " + webhook.get("id").getAsInt());
                  System.out.println("URL: " + webhook.get("webhookUrl").getAsString());
                  System.out.println("Status: " + webhook.get("status").getAsString());
              }
          } else {
              System.out.println(" Error: HTTP " + response.statusCode());
              System.out.println("Details: " + response.body());
          }
      }
  }
  ```

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

  import (
      "encoding/json"
      "fmt"
      "io"
      "net/http"
      "os"
  )

  type Webhook struct {
      ID         int      `json:"id"`
      WebhookURL string   `json:"webhookUrl"`
      Actions    []string `json:"actions"`
      Status     string   `json:"status"`
      CreatedAt  string   `json:"createdAt"`
      UpdatedAt  string   `json:"updatedAt"`
  }

  type WebhooksResponse struct {
      Webhooks []Webhook `json:"webhooks"`
  }

  func getWebhooks() ([]Webhook, error) {
      secretKey := os.Getenv("MODULUS_SECRET_KEY")

      // Create request
      req, err := http.NewRequest(
          "GET",
          "https://webhooks.sbx.moduluslabs.io/v1/webhooks",
          nil,
      )
      if err != nil {
          return nil, err
      }

      // Set basic auth
      req.SetBasicAuth(secretKey, "")

      // Send request
      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          return nil, err
      }
      defer resp.Body.Close()

      body, _ := io.ReadAll(resp.Body)

      if resp.StatusCode == 200 {
          var webhooksResp WebhooksResponse
          json.Unmarshal(body, &webhooksResp)

          fmt.Printf("Found %d webhook(s)\n", len(webhooksResp.Webhooks))

          for _, webhook := range webhooksResp.Webhooks {
              fmt.Printf("\nWebhook ID: %d\n", webhook.ID)
              fmt.Printf("URL: %s\n", webhook.WebhookURL)
              fmt.Printf("Actions: %v\n", webhook.Actions)
              fmt.Printf("Status: %s\n", webhook.Status)
              fmt.Printf("Created: %s\n", webhook.CreatedAt)
          }

          return webhooksResp.Webhooks, nil
      }

      fmt.Printf(" Error: HTTP %d\n", resp.StatusCode)
      fmt.Printf("Details: %s\n", string(body))
      return nil, fmt.Errorf("HTTP %d", resp.StatusCode)
  }

  func main() {
      webhooks, err := getWebhooks()
      if err != nil {
          fmt.Printf("Failed to get webhooks: %v\n", err)
      }
  }
  ```

  ```csharp C# / .NET theme={null}
  // Required NuGet package: jose-jwt
  using System;
  using System.Net.Http;
  using System.Net.Http.Headers;
  using System.Text;
  using System.Text.Json;
  using System.Threading.Tasks;
  using Jose;

  class Program
  {
      static async Task Main(string[] args)
      {
          await GetWebhooks();
      }

      static async Task GetWebhooks()
      {
          // Get credentials from environment variables
          var secretKey = Environment.GetEnvironmentVariable("MODULUS_SECRET_KEY");
          var encryptionKey = Environment.GetEnvironmentVariable("MODULUS_ENCRYPTION_KEY");

          if (string.IsNullOrEmpty(secretKey) || string.IsNullOrEmpty(encryptionKey))
          {
              Console.WriteLine("Error: MODULUS_SECRET_KEY and MODULUS_ENCRYPTION_KEY must be set");
              return;
          }

          try
          {
              // Decode the Base64URL encryption key
              var keyBytes = Base64UrlDecode(encryptionKey);

              // Create HTTP client with Basic Authentication
              using var client = new HttpClient();
              var credentials = Convert.ToBase64String(
                  Encoding.ASCII.GetBytes($"{secretKey}:")
              );
              client.DefaultRequestHeaders.Authorization =
                  new AuthenticationHeaderValue("Basic", credentials);

              // Send GET request
              var response = await client.GetAsync(
                  "https://webhooks.sbx.moduluslabs.io/v1/webhooks"
              );

              var responseBody = await response.Content.ReadAsStringAsync();

              if (response.IsSuccessStatusCode)
              {
                  // Decrypt the response token
                  var encryptedResponse = JsonSerializer.Deserialize<JsonElement>(responseBody);
                  var responseToken = encryptedResponse
                      .GetProperty("response")
                      .GetProperty("Token")
                      .GetString();

                  var decryptedJson = JWT.Decode(responseToken, keyBytes);

                  // Response is a direct array of webhooks
                  var webhooks = JsonSerializer.Deserialize<Webhook[]>(
                      decryptedJson,
                      new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
                  );

                  Console.WriteLine($"Found {webhooks.Length} webhook(s)");

                  foreach (var webhook in webhooks)
                  {
                      Console.WriteLine($"\nWebhook ID: {webhook.Id}");
                      Console.WriteLine($"URL: {webhook.CallbackUrl}");
                      Console.WriteLine($"Action: {webhook.WebhookAction}");
                      Console.WriteLine($"Status: {webhook.WebhookStatus}");
                  }
              }
              else
              {
                  Console.WriteLine($"Error: HTTP {(int)response.StatusCode}");
                  Console.WriteLine($"Details: {responseBody}");
              }
          }
          catch (Exception e)
          {
              Console.WriteLine($"Error: {e.Message}");
          }
      }

      // Base64URL decoding helper
      static byte[] Base64UrlDecode(string input)
      {
          var base64 = input.Replace('-', '+').Replace('_', '/');
          switch (base64.Length % 4)
          {
              case 2: base64 += "=="; break;
              case 3: base64 += "="; break;
          }
          return Convert.FromBase64String(base64);
      }
  }

  // Response model
  public class Webhook
  {
      public string Id { get; set; }
      public string CallbackUrl { get; set; }
      public string WebhookAction { get; set; }
      public string WebhookStatus { get; set; }
  }
  ```
</RequestExample>

## Use Cases

<AccordionGroup>
  <Accordion title="Audit Webhook Configuration" icon="clipboard-check">
    Verify which webhooks are active and what events they receive:

    ```javascript theme={null}
    const webhooks = await getWebhooks();

    const enabledWebhooks = webhooks.filter(w => w.status === 'ENABLED');
    console.log(`${enabledWebhooks.length} active webhook(s)`);

    enabledWebhooks.forEach(webhook => {
      console.log(`- ${webhook.webhookUrl} receives ${webhook.actions.join(', ')}`);
    });
    ```
  </Accordion>

  <Accordion title="Find Webhook ID for Update" icon="magnifying-glass">
    Retrieve the webhook ID before updating or deleting:

    ```javascript theme={null}
    const webhooks = await getWebhooks();

    const webhook = webhooks.find(
      w => w.webhookUrl === 'https://api.yourcompany.com/webhooks/modulus'
    );

    if (webhook) {
      console.log('Webhook ID:', webhook.id);
      // Use this ID to update or delete
      await updateWebhook(webhook.id, { status: 'DISABLED' });
    }
    ```
  </Accordion>

  <Accordion title="Monitor Webhook Status" icon="heartbeat">
    Check if your webhooks are enabled in health checks:

    ```javascript theme={null}
    async function checkWebhookHealth() {
      const webhooks = await getWebhooks();

      const disabledWebhooks = webhooks.filter(w => w.status === 'DISABLED');

      if (disabledWebhooks.length > 0) {
        console.warn(`  ${disabledWebhooks.length} webhook(s) are disabled`);
        // Alert team
        await alertOncall('Disabled webhooks detected', {
          webhooks: disabledWebhooks.map(w => w.webhookUrl)
        });
      }
    }
    ```
  </Accordion>

  <Accordion title="Prevent Duplicate Webhooks" icon="clone">
    Check if a webhook URL is already registered before creating:

    ```javascript theme={null}
    async function ensureWebhook(url, actions) {
      const webhooks = await getWebhooks();

      const existing = webhooks.find(w => w.webhookUrl === url);

      if (existing) {
        console.log('Webhook already exists:', existing.id);
        return existing;
      }

      // Create new webhook
      return await createWebhook(url, actions, 'ENABLED');
    }
    ```
  </Accordion>

  <Accordion title="Sync Webhook Configuration" icon="arrows-rotate">
    Compare current webhooks with expected configuration:

    ```javascript theme={null}
    const expectedWebhooks = [
      { url: 'https://api.example.com/webhooks', actions: ['QRPH_SUCCESS'] },
      { url: 'https://backup.example.com/webhooks', actions: ['QRPH_SUCCESS'] }
    ];

    const currentWebhooks = await getWebhooks();

    // Find missing webhooks
    const missing = expectedWebhooks.filter(expected =>
      !currentWebhooks.some(current => current.webhookUrl === expected.url)
    );

    // Create missing webhooks
    for (const webhook of missing) {
      await createWebhook(webhook.url, webhook.actions, 'ENABLED');
    }
    ```
  </Accordion>
</AccordionGroup>

## Best Practices

<CardGroup cols={2}>
  <Card title="Cache Webhook Configuration" icon="database">
    Cache webhook IDs in your application to avoid repeated API calls:

    ```javascript theme={null}
    // Cache webhook IDs on startup
    const webhooks = await getWebhooks();
    const webhookMap = new Map(
      webhooks.map(w => [w.webhookUrl, w.id])
    );

    // Use cached ID for updates
    const webhookId = webhookMap.get(url);
    await updateWebhook(webhookId, { status: 'DISABLED' });
    ```
  </Card>

  <Card title="Regular Health Checks" icon="heart-pulse">
    Periodically verify webhooks are enabled and configured correctly:

    ```javascript theme={null}
    setInterval(async () => {
      const webhooks = await getWebhooks();
      const enabled = webhooks.filter(w => w.status === 'ENABLED');

      if (enabled.length === 0) {
        alertOncall('No enabled webhooks!');
      }
    }, 3600000); // Every hour
    ```
  </Card>

  <Card title="Log Webhook Changes" icon="file-lines">
    Track webhook configuration changes for audit purposes:

    ```javascript theme={null}
    const webhooks = await getWebhooks();

    await db.webhookAudit.insert({
      timestamp: new Date(),
      webhookCount: webhooks.length,
      webhooks: webhooks
    });
    ```
  </Card>

  <Card title="Validate Expected Configuration" icon="circle-check">
    Ensure critical webhooks are present and enabled:

    ```javascript theme={null}
    const webhooks = await getWebhooks();

    const productionWebhook = webhooks.find(
      w => w.webhookUrl === 'https://api.prod.com/webhooks'
    );

    if (!productionWebhook || productionWebhook.status !== 'ENABLED') {
      throw new Error('Production webhook not configured');
    }
    ```
  </Card>
</CardGroup>

## Filtering and Processing Webhooks

```javascript theme={null}
const webhooks = await getWebhooks();

// Filter enabled webhooks
const enabledWebhooks = webhooks.filter(w => w.status === 'ENABLED');

// Filter by action type
const successOnlyWebhooks = webhooks.filter(w =>
  w.actions.includes('QRPH_SUCCESS') && !w.actions.includes('QRPH_DECLINED')
);

// Sort by creation date (newest first)
const sortedWebhooks = webhooks.sort((a, b) =>
  new Date(b.createdAt) - new Date(a.createdAt)
);

// Group by status
const groupedByStatus = webhooks.reduce((acc, webhook) => {
  acc[webhook.status] = acc[webhook.status] || [];
  acc[webhook.status].push(webhook);
  return acc;
}, {});

console.log('Enabled:', groupedByStatus.ENABLED?.length || 0);
console.log('Disabled:', groupedByStatus.DISABLED?.length || 0);
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Empty Webhooks Array" icon="circle-question">
    **Symptom:** Response returns `{"webhooks": []}`

    **Possible Causes:**

    * No webhooks have been created yet
    * Using wrong secret key (different merchant account)
    * Webhooks were deleted

    **Solutions:**

    * Verify you're using the correct secret key
    * Create a webhook using the [Create Webhook API](/api-reference/webhooks/create)
    * Check if you're in the right environment (sandbox vs production)
  </Accordion>

  <Accordion title="Missing Expected Webhook" icon="magnifying-glass">
    **Symptom:** Webhook you created is not in the list

    **Possible Causes:**

    * Wrong secret key (different merchant account)
    * Webhook was deleted
    * API cache delay (rare)

    **Solutions:**

    * Verify secret key matches the one used to create the webhook
    * Check if webhook was accidentally deleted
    * Retry the request after a few seconds
  </Accordion>

  <Accordion title="Outdated Webhook Information" icon="clock">
    **Symptom:** Webhook status or URL doesn't match recent updates

    **Possible Causes:**

    * Application caching old data
    * Race condition with concurrent updates

    **Solutions:**

    * Clear application cache
    * Call Get Webhooks API again to refresh data
    * Implement cache invalidation after updates
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Create Webhook" icon="plus" href="/api-reference/webhooks/create">
    Register a new webhook endpoint
  </Card>

  <Card title="Update Webhook" icon="pen" href="/api-reference/webhooks/update">
    Modify existing webhook configuration
  </Card>

  <Card title="Delete Webhook" icon="trash" href="/api-reference/webhooks/delete">
    Remove a webhook endpoint
  </Card>

  <Card title="Webhooks Overview" icon="book" href="/docs/webhooks/overview">
    Learn about the Webhook API
  </Card>
</CardGroup>


## OpenAPI

````yaml GET /v1/webhooks
openapi: 3.1.0
info:
  title: Modulus Labs Webhooks API
  description: >-
    API for managing webhook endpoints to receive QR Ph transaction
    notifications
  version: 1.0.0
servers:
  - url: https://webhooks.sbx.moduluslabs.io
    description: Sandbox
security: []
paths:
  /v1/webhooks:
    get:
      tags:
        - Webhooks
      summary: Get Webhooks
      description: Retrieve all registered webhook endpoints for your merchant account.
      operationId: listWebhooks
      responses:
        '200':
          description: List of webhooks retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Webhook'
              example:
                - id: 123
                  webhookUrl: https://api.yourcompany.com/webhooks/modulus
                  webhookAction:
                    - QRPH_SUCCESS
                    - QRPH_DECLINED
                  webhookStatus: ENABLED
        '401':
          description: Unauthorized - Invalid or missing credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - basicAuth: []
components:
  schemas:
    Webhook:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the webhook
        webhookAction:
          type: array
          items:
            type: string
            enum:
              - QRPH_SUCCESS
              - QRPH_DECLINED
          description: List of transaction events this webhook receives
        webhookStatus:
          type: string
          enum:
            - ENABLED
            - DISABLED
          description: Current status of the webhook
        webhookUrl:
          type: string
          format: uri
          description: The HTTPS URL where notifications are sent
    ErrorResponse:
      type: object
      properties:
        statusCode:
          type: integer
          description: HTTP status code
        message:
          type: string
          description: Error message
        error:
          type: string
          description: Error type
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: >-
        HTTP Basic Authentication using your Secret Key as the username and an
        empty password

````