Hi everyone,
I've been integrating Resemble AI's voice generation into a dashboard project for automated client status updates, and one of the most critical pieces was getting reliable, real-time notifications when a voice file is ready. Polling their API constantly wasn't efficient for our use case, so I dove deep into their webhook setup. I wanted to share a structured, step-by-step walkthrough of the process, including the pitfalls I hit and how to validate everything is working. This is especially useful if you're building any kind of automated pipeline or dashboard where you need to trigger the next step the moment a job completes.
Here's the end-to-end process I followed, broken down into phases:
**Phase 1: Preparing Your Endpoint**
* You **must** have a publicly accessible HTTPS endpoint ready to receive POST requests. For initial testing, I used a tool like [ngrok]( https://ngrok.com/) to tunnel from a local server. This is a non-negotiable first step.
* Your endpoint should be configured to:
* Accept a POST request.
* Parse the JSON payload (the structure is in their docs, but I'll summarize key fields).
* Return a `2xx` status code (like `200 OK`) quickly. If you don't, Resemble's system may retry or eventually mark the webhook as failed.
**Phase 2: Configuring in the Resemble AI Console**
1. Navigate to your **Project** inside the Resemble AI console.
2. Go to **Settings > Webhooks**.
3. Click **"Add New Webhook."**
4. In the form:
* **URL:** Enter your full public HTTPS endpoint URL.
* **Events:** For completed generation jobs, you want to select **`voice_generation_completed`**. You can also select `voice_generation_failed` for error handling—I highly recommend setting up both.
* **Status:** Toggle to **Active**.
**Phase 3: Understanding the Payload & Validating**
Once configured, any completed job will trigger a POST request to your URL. The JSON body contains everything you need. Here are the most important fields from a logging and dashboard perspective:
* `event_type`: Should be `voice_generation_completed` or `voice_generation_failed`.
* `data.id`: The unique ID of the generation job.
* `data.status`: The final status (e.g., `success`).
* `data.voice`: The name of the voice model used.
* `data.output_url`: **The most important field.** This is the direct URL to the generated WAV file. It's what you'll use to fetch the audio.
* `data.project_name`: Helpful if you're managing multiple projects.
**Phase 4: Testing and Common Pitfalls**
* **Silent Failures:** My biggest issue was my endpoint initially returning a `500` error because of a parsing mistake. Resemble's UI doesn't show detailed delivery logs. You **must** monitor your own endpoint's access logs or use a request bin service during setup to see the actual incoming payload.
* **Security:** While not covered in depth here, consider adding a simple secret token validation in your endpoint to verify the requests are truly from Resemble.
* **Idempotency:** Be prepared for potential duplicate events. Your endpoint's logic should handle receiving the same completion notification more than once gracefully.
Integrating this properly has made our dashboard so much more responsive. Instead of users wondering if their audio is ready, the system now updates instantly and fetches the file. For anyone building similar self-serve analytics tools that incorporate AI-generated voice, this workflow is a game-changer for user experience.
Has anyone else set this up and found different challenges or added additional validation steps? I'd be curious to compare notes, especially around error handling for failed jobs.
~jenny
Let the data speak.
Absolutely spot on about the public HTTPS endpoint being non-negotiable. That's the first wall so many people hit. Using ngrok is the perfect way to prototype.
One extra thing I learned the hard way with similar webhook setups for email events - you mentioned parsing the JSON, but I'd stress validating the payload structure *before* you even try to process the data. I've seen services change a field name from `status` to `job_status` in a minor update and it broke our pipeline for hours because we weren't checking for the presence of expected keys first.
Also, a quick tip on that `2xx` status code. You have to respond *fast*. Some services have a very short timeout window, like 3-5 seconds, and if your endpoint does any heavy lifting before sending the response, you might send a 200 but the webhook provider will still consider it a failed delivery and retry.
don't spam bro
That's a critical point about validation. I've taken it a step further by storing the raw payload in a staging table before any logic runs. My endpoint only does two things: logs the event and immediately acknowledges it.
The structure validation and business logic run in a separate batch job from the staging data. It decouples the webhook's speed requirement from the processing reliability. You can also track schema drift over time this way.
EXPLAIN ANALYZE
The point about using a staging table is solid, especially for tracking schema changes. I've found that approach also helps with retry logic down the line.
One thing I'd add is that even when you're just logging and acknowledging, you should still validate the webhook signature if the service provides one (Resemble does). A quick signature check before logging prevents your staging table from filling up with junk from random POSTs. It's a lightweight step that doesn't hurt the response time.