# Status Codes


There are two distinct kinds of "status" in the Intuizi API. Do not confuse them.

## 1. HTTP / envelope code

The transport-level result of the request. This is the HTTP status code, and it
is mirrored in the `code` field of the [envelope](/concepts/envelope).

| Code | Meaning |
| --- | --- |
| `200` | Success. |
| `201` | Created - a resource create succeeded. |
| `401` | [Unauthenticated](/concepts/errors#401-unauthenticated) - missing/invalid/expired token. |
| `404` | [Not found](/concepts/errors#404-not-found) - the id does not exist for your account. |
| `406` | [Not Acceptable](/concepts/errors#406-not-acceptable) - you did not send `Accept: application/json`. |
| `409` | [Conflict](/concepts/errors#409-conflict) - an `Idempotency-Key` was reused with a different body. |
| `422` | [Validation error](/concepts/errors#422-validation-error) - see the `errors` object. |
| `429` | [Too Many Requests](/concepts/errors#429-too-many-requests) - rate limit exceeded; wait `Retry-After` seconds. |

## 2. Business lifecycle status

Audiences and activations are processed asynchronously. A read of one of those
resources includes a **lifecycle status** inside `data` that is separate from
the HTTP code. A `200 OK` simply means "we successfully told you the current
state"; the lifecycle status tells you whether the underlying job has finished.

| Status id | Name | When polling |
| --- | --- | --- |
| `100` | Initiating | Keep polling |
| `101` | Processing | Keep polling |
| `102` | Analyzing | Keep polling |
| `103` | Decryption Requested | Keep polling |
| `104` | Completed | Stop - the only success |
| `105` | DataStreaming | Keep polling - it comes before `104` |
| `106` | Expired | Stop - final |
| `107` | Additional Info | Stop - the build stopped and will not continue |
| `108` | Modeling | Keep polling |
| `109` | Visualizing data streams | Keep polling |
| `4xx` | Error states | Stop - failed |

{{< callout type="warning" >}}
A `200 OK` on an audience read does **not** mean the audience is ready. Check
the lifecycle status id in `data` - keep polling until it reaches `104`
(Completed) before acting on the result. The same applies to activations, which
also finish at `104` (Completed). Note the ids are not sequential: `105`
(DataStreaming) happens **before** `104` - it is the delivery step, added later
with the next free id. At `105` the results are still being delivered, a
Lookalike Model in `108` (Modeling) is still training, and an audience in `109`
(Visualizing data streams) is still drawing the
[data stream visualizations](/api/v2/audiences#datastream-visualizations) it
opted into, before `105` and `104` - keep polling through all three. `107`
(Additional Info) is not one of them: it is a stop that never changes and is
not resumed, and `106` (Expired) and the `4xx` error states are final too.
{{< /callout >}}

`104` Completed is the only success. A build that stops at `107` Additional
Info or at a `4xx` error state has failed and does not change again: stop
polling, fix the cause, and create it again. Both send the `audience.failed`
or `activation.failed` [webhook](/concepts/webhooks). At `107` the worker
stopped the build and said why, and Audience Manager shows the reason. A
resource at `106` Expired has aged out and does not change again either.

A [Lookalike Model](/guides/build-a-lookalike-model#cancel-an-in-flight-run)
you cancel reads `108` Modeling until the run reaches its next checkpoint and
stops, then ends at `400` Error, which Audience Manager shows as
`Cancelled on request.` A cancel that arrives once the result is already being
published is ignored, and the run completes at `104`.

The full create-then-poll flow is described in
[The Async Model](/concepts/async-model).

## 3. Cohort status scale (1-5)

[Cohorts](/api/v2/cohorts) do not use the 1xx audience/activation lifecycle -
they run on their own small scale. Poll
[`GET /api/v2/analyses/cohorts/{id}`](/api/v2/cohorts) until it reaches `4`
Completed before using the cohort in an audience.

| Status | Name | Meaning |
| --- | --- | --- |
| `1` | Uploading | The cohort row exists; the import has not been queued yet. |
| `2` | Initiating | The import is queued for processing. |
| `3` | Processing | The file is being imported and matched. |
| `4` | Completed | The cohort is ready to use in an audience. |
| `5` | Not Available | The import failed. The cohort cannot be used in an audience. |

`4` and `5` are final, so stop polling at either. A cohort that failed before
failures were reported as `5` can still read the error code it failed with,
which the API names `Unknown`. Treat that as a failed import too. What to do
after a failed import depends on the source:

- `file_uri`: fix the file, then create the cohort again.
- `upload_reference`: the failed create used the reference up, so upload the
  file again for a new reference.
- `audience_id` with a regular audience: the failed cohort still counts as the
  audience's one cohort, so
  [delete it](/api/v2/cohorts#post-apiv2analysescohortsdelete-by-id) before
  creating from that audience again. A Lookalike Model audience needs no
  delete.

## 4. POI submission status

[POI submissions](/api/v2/poi/submissions) carry their own small status on the
submission read, separate from both scales above. In the order a submission
goes through them:

| Status | Name | Meaning |
| --- | --- | --- |
| `4` | Importing | Just created. Intuizi is reading the locations. |
| `1` | Waiting | The locations have been read, and the submission waits for Intuizi to review it. The only status in which it can be deleted. |
| `2` | Imported | Intuizi approved it, and its locations are now in your POI data. |
| `3` | Disabled | Intuizi declined it. |

A submission moves from `Importing` to `Waiting` on its own. The move from
`Waiting` to `Imported` or `Disabled` is a review done by hand, not a
processing step, so do not script a wait for it. See
[My POI Data - Submissions](/api/v2/poi/submissions) for the read shape.
