# Estimating and deleting

The two operations that act on a campaign which already exists: pricing a draft and removing one. Both are asynchronous, both are gated by the campaign's status, and both are learned about by reading the campaign back rather than from their own response.

**Language:** en
**Audience:** developer
**TLDR:** PATCH .../estimate returns 202 with the campaign in estimating and a worker fills the figures in about a minute later, so you re-read to collect them. It is a WRITE: on a prepared campaign it discards the prepared messages, and the 202 itself already clears the counts and prices. DELETE returns 204, is hard and has no undo, and for a prepared or scheduled campaign it goes through deleted first while a worker removes its messages, so a post-delete campaign still listed in deleted is cleanup in progress, not a failure.
**Search keywords:** estimate campaign, campaign estimate, campaign cost, how much will it cost, price a campaign, precision, delete campaign, remove campaign, cancel campaign, undo campaign, 409, 204, PROJECT_CAMPAIGN_WRITE
**Related pages:** /developers/product-api/campaigns/overview, /developers/product-api/campaigns/reading-campaigns, /developers/product-api/campaigns/creating-a-draft
**Docs index (every page):** https://docs.instasent.com/llms.txt
**This zone's index:** https://docs.instasent.com/developers/product-api/llms-full.txt
**This page:** https://docs.instasent.com/developers/product-api/campaigns/estimating-and-deleting/ (HTML) · https://docs.instasent.com/developers/product-api/campaigns/estimating-and-deleting.md (Markdown)

Two operations act on a campaign that already exists. **Estimate** prices it — how many contacts it would reach, how many message parts that becomes, what it would cost. **Delete** removes it. Both take the same `PROJECT_CAMPAIGN_WRITE` scope as creation, and both sit in the **restrictive** rate-limit class.

They share one property worth understanding before you call either: **neither has finished the work by the time it answers you.** Each hands back a status and leaves a worker to do the rest, so in both cases the way you learn the outcome is to [read the campaign again](/developers/product-api/campaigns/reading-campaigns).

## Estimating a draft

[`PATCH /v1/project/{project}/campaign/{id}/estimate` - Start the estimation of a campaign.](/developers/product-api/reference)

The call returns **`202 Accepted`** with the campaign in `estimating`, and a worker fills in the figures about a minute later. [Read the campaign again](/developers/product-api/campaigns/reading-campaigns) to collect them: `contactsCount` and `ignoredContactsCount` for the reach, `preparedUnits` for the message parts, and the campaign's price fields for the cost. While the worker is still running the status stays `estimating`.

- `precision` — `integer`, default: `derived from the audience size`
  How many contacts the estimate samples, from 100 to 20000. A bigger sample takes longer and buys accuracy. The body itself is optional — send no body at all to take the default.

The estimate walks that sample and extrapolates, deliberately erring on the high side, so the real cost of the send is never above the figure you get back.

> **Warning**: **Estimating a `prepared` campaign changes it.** Estimating is a write and behaves like one: on a campaign that is already prepared it discards the prepared messages and returns the campaign to the estimation pipeline, so do not call it on a campaign somebody is about to confirm. The figures go before the worker even starts: the `202` itself already clears `contactsCount`, `preparedUnits` and the prices, so there is no window in which to change your mind.
> 
> A `scheduled` campaign is refused outright with `409`, and unscheduling it in the dashboard is not the way around that: it leaves the campaign `prepared`, not back in draft, so estimating it afterwards still costs the preparation and it has to be prepared again before it can go out. To find out what a scheduled campaign costs, read the figures the previous estimate left on it with `GET /campaign/{id}` rather than starting a new one.

The states the endpoint accepts are `draft`, `preview`, `estimated`, `quoted` and `prepared`. See [Statuses and phases](/developers/product-api/campaigns/overview#statuses-and-phases) for what each one means.

### A `409` here is not only about state

This is the refusal an integration actually runs into, and the status alone will not explain it. **The campaign also has to be complete.** Every declared language needs its copy and a sender, so a draft missing its copy, missing a sender, or carrying a [language declared and left empty](/developers/product-api/campaigns/message#declaring-other-languages) is refused with the same `409` while sitting in a perfectly valid `draft`.

RCS adds a second gate: **the SMS fallback leg has to be complete too**, unless the campaign has no fallback or skips it. An RCS campaign whose own message is finished can still be refused because the fallback it inherited from the project has no sender — the part that fails is one the caller never wrote. The `no-default-sender` and `no-fallback-sender` [warnings](/developers/product-api/campaigns/creating-a-draft#warnings) returned at creation are what tell you this is coming.

## Deleting a campaign

[`DELETE /v1/project/{project}/campaign/{id}` - Delete a campaign.](/developers/product-api/reference)

> **Warning**: **Deletion is hard and there is no undo.** Nothing is archived and no copy is kept.

Anything that has not gone out can be deleted: a `draft` or `preview`, a campaign already `estimated` or `quoted`, one already `prepared`, and one still `scheduled` while its send time is **more than five minutes away**. A campaign that is sending, sent, aborted or unpaid is refused with `409`, and so is a scheduled one inside that five-minute edition window — for a campaign already on its way, cancelling in the dashboard is the alternative.

A campaign **mid-calculation cannot be deleted** either — neither `estimating` nor `quoting` is a deletable state, and this is the refusal most likely to surprise you, because you caused it yourself a moment earlier. If you have just started an estimate and want to undo it, wait for it to land and delete the campaign after.

### The `204` does not always mean it is gone

The response is **`204 No Content`** — there is no body to read, by design. And the deletion is not always immediate:

| The campaign was                          | What happens                                                                                                                                           |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `draft`, `preview`, `estimated`, `quoted` | Gone by the time the call returns.                                                                                                                     |
| `prepared` or `scheduled`                 | Moved to `deleted` first. A worker removes its prepared messages before the campaign itself goes, so it keeps appearing in listings for a short while. |

With no body to tell the two apart, **read the campaign again**: a `404` means it is gone, and a campaign still there in `deleted` means the cleanup is running and will finish on its own. Neither is an error, and an integration that treats a post-delete `404` as a failure will report problems that did not happen.

## What's next

- [Reading campaigns](/developers/product-api/campaigns/reading-campaigns) - How you collect the result of both operations: one campaign, the list, and the project digest.
- [Campaigns](/developers/product-api/campaigns/overview) - The status vocabulary both operations are gated by, and the rest of the section.
- [Dates and scheduling](/developers/product-api/campaigns/scheduling) - Why a scheduled campaign is a different animal, and what setting a date does and does not do.

---

This is one page of the Instasent documentation. For the complete machine-readable index of every guide and API reference, fetch https://docs.instasent.com/llms.txt — start there for full context.
