Webhook target returning 500 - how to handle dead letter queue in Python?

Problem
I’m trying to set up a webhook endpoint to catch Genesys Cloud WFM adherence events. The goal is to log these into a local SQLite database for our Chicago team to review later. The webhook works fine when the server is up, but if my script crashes or the DB is locked, Genesys keeps retrying aggressively. I want to implement a dead letter queue so failed payloads don’t get lost, but I’m not sure how to structure the Python code to handle the HTTP 200 ACK while queuing the error separately.

Here is the basic Flask route I have right now:

@app.route('/webhook/wfm-adherence', methods=['POST'])
def wfm_webhook():
 data = request.json
 try:
 db.execute('INSERT INTO adherence_logs VALUES (?)', (json.dumps(data),))
 db.commit()
 return '', 200
 except Exception as e:
 # What do I return here? 500 triggers retries.
 # I want to acknowledge Genesys but save the data for later.
 return '', 500

The issue is that returning 500 causes Genesys to retry immediately, which floods my server. If I return 200, Genesys stops retrying, but I haven’t actually saved the data yet if the DB write failed.

Environment specs:

  • Python 3.9 with Flask
  • Genesys Cloud API v2 Webhooks
  • SQLite3 local database
  • US/Central timezone server

I’ve read about using a message queue like RabbitMQ, but that feels like overkill for a small team. Is there a way to return 200 to Genesys to stop the retries, while still capturing the failed payload in a local file or queue for manual reprocessing? I don’t want to lose any adherence data.

I’ve tried using threading to write to the DB in the background, but I’m worried about race conditions if multiple webhooks hit at once. Can I just write the payload to a JSON file and process it later with a cron job? How do I ensure the file isn’t corrupted if two requests come in simultaneously?

I’m stuck on the best way to acknowledge the webhook without losing data when the backend fails.

Studio handles retries natively. Don’t build custom DLQ logic in Python if you can avoid it. Use the retryPolicy in the webhook definition. Set maxRetries to 3 and retryIntervalMs to 5000. If it fails after that, it drops. Simpler than managing a queue.

"retryPolicy": {
 "maxRetries": 3,
 "retryIntervalMs": 5000
}