Webhooks tell your server when each file is done or failed. Without a server to receive them, or to catch up after one was down, poll. One call tells you everything about a project’s files, and meta counts them by state:
?status=failed lists only the failed files (meta still counts all of them), and GET /projects/{id}/files/{name} answers one file, the call to poll when you wait for one.

A good polling loop

  • Poll GET /projects/{id}/files every 30 to 60 seconds. Files take minutes, and faster polling gains nothing.
  • Stop when meta.pending and meta.processing are both 0. Files wait pending while the project is stopped, so a loop that runs long should check GET /projects/{id}/status too (When a file stays pending). An API upload or a retry starts a project that ran before; a file copied in with the AWS CLI does not.
  • Renew the token when a call answers 401, once: a season takes longer than a token lasts (30 minutes). If the new token is refused too, stop: the key pair is wrong.
  • For many projects, poll each one in turn: 1000 requests a minute is plenty, and a 429 says in Retry-After how long to wait.
This loop does all four, and prints each file’s state as it goes:

When a file stays pending

1

Is the project running?

NOT_RUNNING (projectStatus: "stopped"): it stopped itself after being idle, or was stopped. Start it: POST /projects/{id}/start. A project that stopped itself after its last file starts on its own within a minute of a new file; one stopped with POST …/stop only when an API upload in parts completes or a file is retried; one with startOnNewFiles off only on a retry. See Starting again on a new file.
2

Did the service fail?

status: "ERROR" means the service did not launch (lastError says so) or launched and then stopped working (pod.status is failed, since pod.at). POST /projects/{id}/start replaces it. A service that has read failed for 2 hours is stopped, and reads NOT_RUNNING.
3

Are other files still running?

The service processes a few files at a time; the rest wait pending until one finishes. Nothing to do but wait.

When a file failed

failureCode says why, when the cause is one you can fix yourself:
A failed file’s replacement needs a new name for now. The processing service keeps its own copy of a failed input, found by the file’s name, and processes that copy again when the name comes back, even with new content: overwrite: true, copying over it with the AWS CLI, or deleting and uploading it again all reprocess the old bytes.
If a retry fails again, contact support with the project id, the file name and its hash.

A file the engines failed on

A file whose voice or translation engine reported an error, such as a line the voice could not say, is failed, not done with silent gaps. Retry it: a retry processes it from the start, so a voice or engine changed in the config since applies. If it fails again, contact support with the project id, the file name and its hash, which finds the file’s log.

Project status at a glance