# Meshy API Webhooks vs Polling: When Results Are Ready

> URL: https://help.meshy.ai/en/articles/16102100-meshy-api-webhooks-vs-polling-when-results-are-ready
> Language: en
> Last updated: 2026-09-04T08:30:31Z

Meshy API generation tasks (Text to 3D, Image to 3D, Rigging, and more) run asynchronously — you submit a task and then need to find out when it's done before fetching the result. This article explains the task lifecycle and the two supported ways to know when a task has finished: **polling** and **webhooks** — plus how to avoid the most common "errors retrieving the model" issue.

# Overview

## Task lifecycle

Every generation task moves through a small set of states, returned in the `status` field of the task object:

- `PENDING` — the task has been queued but processing hasn't started yet.

- `IN_PROGRESS` — the task is actively being processed. The `progress` field (0-100) increases as work completes.

- `SUCCEEDED` — the task finished successfully and `progress` is 100. Result URLs (model files, textures, previews) are now available in the response.

- `FAILED` — the task could not complete. Credits for failed tasks are automatically refunded.

- `CANCELED` — the task was canceled before completing.

The single most important rule when integrating with the API: **never try to fetch or use result URLs until the task's `status` is `SUCCEEDED`**. Reading results while a task is still `PENDING` or `IN_PROGRESS` is the most common cause of "errors retrieving the model" reports.

## Polling sample

Polling means repeatedly calling the "get task" endpoint for your task ID until it reaches a terminal state (`SUCCEEDED`, `FAILED`, or `CANCELED`). A simple polling loop looks like this:

- Submit the generation request and store the returned task `id`.

- Call the corresponding "retrieve task" endpoint (for example, the Text to 3D or Image to 3D task-by-id endpoint) on an interval — a few seconds is typical.

- Check the `status` field on each response. Keep polling while it's `PENDING` or `IN_PROGRESS`.

- Stop polling as soon as `status` is `SUCCEEDED` (read the result URLs), `FAILED`, or `CANCELED`.

- Add a reasonable timeout/max-attempts guard in your client so a stuck task doesn't poll forever.

Polling is simple and works well for scripts, batch jobs, and low-volume integrations. For high-volume or latency-sensitive integrations, a webhook is usually a better fit.

## Webhook setup

Instead of repeatedly asking "is it done yet?", you can ask Meshy to notify your server the moment a task finishes. To use webhooks:

- Configure a webhook (callback) URL that Meshy can reach — this is typically set at the account/API settings level or passed as a parameter on the generation request, depending on the endpoint.

- Ensure your endpoint is publicly reachable over HTTPS and responds quickly (return a 2xx status immediately, then process the payload asynchronously).

- When the task reaches a terminal state, Meshy sends a payload to your endpoint containing the task `id` and its final `status`.

- On receipt, look up the full task details by `id` via the API rather than trusting the webhook body alone, to make sure you have the authoritative, up-to-date result.

Webhooks reduce unnecessary API calls and give you near-instant notification, but you should still keep a periodic polling fallback for tasks where a webhook delivery might be missed or delayed (e.g. due to a transient network issue on your side).

## Idempotency

Whether you use polling or webhooks, your result-handling code should be idempotent — safe to run more than once for the same task without side effects. This matters because:

- A webhook may be delivered more than once for the same task (retries on the sender side, network duplication, etc.).

- A polling loop and a webhook handler might both try to process the same completed task if both are running.

To stay idempotent, key your processing logic off the task `id` — for example, check whether you've already stored/downloaded results for that `id` before doing it again, and make "mark as processed" a single atomic step in your own database.

## status = SUCCEEDED

A response with `"status": "SUCCEEDED"` and `"progress": 100` is the only signal that guarantees the result payload (model URLs, textures, thumbnails) is complete and safe to use. Concretely, in your code:

- Verify `status === "SUCCEEDED"` before reading anything out of the `result`/model URL fields.

- Don't rely on `progress` alone — always check `status` as well, since progress can briefly show high values before the task is fully finalized.

- Download result files promptly once `SUCCEEDED` — generated assets are only retained on Meshy's servers for a limited time, after which the URLs will no longer resolve.

# Common errors

Most "I can't retrieve my model" reports trace back to one of these causes:

- **Fetching too early.** Calling the result URL, or reading the model fields, before `status` is `SUCCEEDED`. This is by far the most frequent cause.

- **Expired assets.** Waiting too long after `SUCCEEDED` to download — result URLs stop working after the retention window for that task type has passed.

- **Using a stale or wrong task ID** — for example, re-using an ID from a previous, unrelated request.

- **Treating `FAILED` as a transient state** and continuing to poll a task that has already failed instead of resubmitting.

- **Network/timeout issues** between your server and Meshy that get misread as a generation problem.

# Retries

If a generation doesn't meet your expectations, or a request fails outright, keep the following in mind:

- The Meshy API does not currently support retrying an existing task in place — to try again, submit a new generation request, which will consume credits normally.

- For transient network failures when calling the API (timeouts, 5xx responses), a short exponential backoff before resubmitting the request is reasonable.

- For polling itself, retry the "get task" call on transient network errors, but don't treat a single failed poll as a generation failure — only trust the `status` field once you get a successful response.

- If you need built-in retry functionality for generations, reach out to Meshy's sales team about enterprise plan options.

# FAQ

## 1. Why do I consistently get errors when retrieving models from a generation result via the API?

This almost always happens because the code is trying to read the result before the task has finished. Always confirm `status` is `SUCCEEDED` (and `progress` is 100) before retrieving model URLs.

## 2. Should I use polling or webhooks?

Polling is simpler to set up and fine for low-volume or one-off scripts. Webhooks are better for production integrations with many concurrent tasks, since they avoid unnecessary repeated requests and notify you immediately when a task completes.

## 3. What should my server do if it receives the same webhook twice?

Handle it idempotently — check the task `id` against what you've already processed, and skip re-processing if it's already been handled.

## 4. My webhook never arrived — what should I do?

Fall back to polling the task by `id` directly. Also confirm your endpoint is publicly reachable over HTTPS and returns a fast 2xx response, since slow or unreachable endpoints can cause delivery issues.

## 5. Can I retry a failed or unsatisfying generation directly through the API?

Not currently — you'll need to submit a new generation request, which consumes credits normally. Contact sales about enterprise options if you need built-in retry support.

## 6. How long do I have to download my results after status is SUCCEEDED?

Result files are only retained on Meshy's servers for a limited time after a task completes, so download outputs to your own storage as soon as the task succeeds rather than waiting.