> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datalane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Campaign lifecycle

> Understand campaign states, enrichment retries, and result expiry.

An API-created campaign normally moves through four states:

```text theme={null}
draft -> enriching -> enriched -> expired
```

| Status      | Meaning                                                    | Recommended action                     |
| ----------- | ---------------------------------------------------------- | -------------------------------------- |
| `draft`     | The account list is stored but enrichment has not started. | Call `campaigns/enrich`.               |
| `enriching` | Eligible accounts are being processed.                     | Poll `campaigns/get` with backoff.     |
| `enriched`  | Results and metrics are ready.                             | Call `campaigns/export` before expiry. |
| `expired`   | The results access window has ended.                       | Downloads are no longer available.     |

`campaigns/get` and `campaigns/list` may also return `tam_only` for campaigns created in the DataLane application. Those campaigns are readable through the API but cannot be enriched through it.

Expiry is evaluated when you read the campaign, so `enriched` becomes `expired` the moment the access window lapses. An expired campaign keeps `resultsExpireAt` (now in the past) but no longer reports `completedAt` or `results`, and exports return `410 results_expired`.

## Eligibility and credits

Before launching, DataLane deduplicates the input list, validates it, and removes recently enriched accounts according to the campaign's `excludeEnrichedWithinDays` setting (set at creation, changeable via `campaigns/update` while the campaign is a `draft`). One credit is required for each eligible account.

`accounts.requested` reports the distinct submitted account count. After the first launch, `accounts.eligible` reports the eligible count and `accounts.excluded` breaks exclusions down into invalid, recently enriched, and CRM-excluded accounts. A failed or canceled attempt that returns to `draft` retains its latest evaluation; the counts can change when the campaign launches again.

Use `org/describe` to inspect available credits, the maximum input size, and the organization-wide in-flight account limit before scheduling large jobs.

## Safe retries

Calling `campaigns/enrich` for a campaign that is already `enriching` returns its current state. This makes it safe to retry a launch whose response was lost.

If the launch is still converging, the API can return `409 enrichment_pending`. Retry the same request after a short exponential backoff. Do not create a replacement campaign unless you intend to create a second job.

An enrichment attempt that fails or is canceled returns the campaign to `draft`. `lastEnrichment` describes the latest reverted attempt and whether its credits were refunded.

## Polling

Start with a two-second interval and back off to a reasonable ceiling. Stop polling on `enriched`, `expired`, or when `lastEnrichment` indicates that the campaign returned to `draft` after an attempt.
