Skip to main content
GET
/
v1
/
webhooks
Get Webhooks
curl --request GET \
  --url https://webhooks.sbx.moduluslabs.io/v1/webhooks \
  --header 'Authorization: Basic <encoded-value>'
{
  "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"
    }
  ]
}

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 using your Secret Key.
Authorization: Basic {base64(secret_key:)}

Request

Headers

HeaderValueRequired
AuthorizationBasic {base64(secret_key:)}Yes
acceptapplication/jsonNo

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.
webhooks
array
required
Array of all registered webhooks for your merchant account. Returns an empty array [] if no webhooks are registered.Each webhook object contains:

Response Examples

{
  "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"
    }
  ]
}
{
  "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"
    }
  ]
}

Error Responses

Status Code: 401Cause: Invalid or missing authentication credentialsResponse Example:
{
  "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)
Status Code: 403Cause: Account disabled or API access revokedSolution:
  • Contact Modulus Labs support
  • Verify your account status
Status Code: 500Cause: Unexpected server errorSolution:
  • Retry the request
  • If the issue persists, contact Modulus Labs support

Code Examples

curl https://webhooks.sbx.moduluslabs.io/v1/webhooks \
  -u sk_your_secret_key:

Use Cases

Verify which webhooks are active and what events they receive:
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(', ')}`);
});
Retrieve the webhook ID before updating or deleting:
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' });
}
Check if your webhooks are enabled in health checks:
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)
    });
  }
}
Check if a webhook URL is already registered before creating:
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');
}
Compare current webhooks with expected configuration:
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');
}

Best Practices

Cache Webhook Configuration

Cache webhook IDs in your application to avoid repeated API calls:
// 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' });

Regular Health Checks

Periodically verify webhooks are enabled and configured correctly:
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

Log Webhook Changes

Track webhook configuration changes for audit purposes:
const webhooks = await getWebhooks();

await db.webhookAudit.insert({
  timestamp: new Date(),
  webhookCount: webhooks.length,
  webhooks: webhooks
});

Validate Expected Configuration

Ensure critical webhooks are present and enabled:
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');
}

Filtering and Processing Webhooks

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

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
  • Check if you’re in the right environment (sandbox vs production)
Symptom: Webhook you created is not in the listPossible 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
Symptom: Webhook status or URL doesn’t match recent updatesPossible 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

Next Steps

Authorizations

Authorization
string
header
required

HTTP Basic Authentication using your Secret Key as the username and an empty password

Response

List of webhooks retrieved successfully

id
string

Unique identifier for the webhook

webhookAction
enum<string>[]

List of transaction events this webhook receives

Available options:
QRPH_SUCCESS,
QRPH_DECLINED
webhookStatus
enum<string>

Current status of the webhook

Available options:
ENABLED,
DISABLED
webhookUrl
string<uri>

The HTTPS URL where notifications are sent