Moneyline

Webhooks

Receive real-time notifications when events occur in Moneyline.

Setup

Create a Webhook Endpoint

curl -X POST https://api.moneyline.dev/v1/webhooks \
  -H "Authorization: Bearer ml_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/moneyline",
    "events": ["submission.processed", "document.parsed", "policy.evaluated"]
  }'

Dashboard

Navigate to Webhooks in the dashboard to create, edit, and monitor webhook endpoints.

Events

EventDescription
submission.createdNew submission created
submission.processingProcessing workflow started
submission.processedAll documents processed, analytics ready
submission.failedProcessing failed
document.uploadedDocument uploaded
document.classifiedDocument auto-classified
document.parsedDocument parsing complete
document.failedDocument processing failed
transactions.enrichedTransaction enrichment complete
policy.evaluatedPolicy evaluation complete

Payload Format

{
  "id": "evt_abc123",
  "type": "submission.processed",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "id": "sub_xyz789",
    "external_id": "deal-001",
    "status": "processed",
    "documents_count": 3,
    "transactions_count": 245
  }
}

Verification

All webhook requests include an HMAC-SHA256 signature in the X-Moneyline-Signature header.

Verify in Node.js

import crypto from 'crypto';

function verifyWebhook(payload: string, signature: string, secret: string): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(`sha256=${expected}`)
  );
}

Verify in Python

import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, f"sha256={expected}")

Retry Logic

Failed deliveries are retried with exponential backoff:

AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours
612 hours

After 6 failed attempts, the webhook is disabled and an email notification is sent.

Best Practices

  • Return 2xx quickly — Process webhook payloads asynchronously
  • Use idempotency — Events may be delivered more than once; use event.id to deduplicate
  • Verify signatures — Always validate the X-Moneyline-Signature header
  • Monitor delivery logs — Check the dashboard for failed deliveries

On this page