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

# Troubleshooting: sender warm-up pacing — a stalled or slow sender with no 429

> How to read the alphanumeric/international sender warm-up meter when a campaign paces past an advisory ceiling or a sender's ramp pins, and the fix paths that actually clear the stall.

# Troubleshooting: sender warm-up pacing

A campaign targeting an alphanumeric sender ID or an international long code can stall mid-batch **without a single 429**. The sender warm-up meter is advisory — it recommends a daily ceiling instead of hard-refusing overflow — so pacing damage shows up as carrier-side filtering and a rising failure rate, not as `DAILY_CAP_EXCEEDED`. This page tells you which gate you are actually dealing with, how to read the meter, and what to do besides pushing more traffic.

## Symptom map — advisory meter vs hard gate

Before you tune anything, separate the two families of volume control. They look alike in a message log and they demand opposite responses.

| What you see                                                                                                                                           | Which surface owns it                               | Response                                                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The API refuses sends with `429 DAILY_CAP_EXCEEDED`, `WARMING_QUOTA_EXCEEDED`, or `NUMBER_MPS_EXCEEDED`                                                | The **hard pre-send gates** on a US/CA 10DLC number | [Number warming caps](/troubleshooting/number-warming-caps) — resolve the coded rejection there. This page is for the sender that does **not** hard-refuse. |
| A campaign on an alphanumeric sender ID or an international long code stalls mid-batch, deliveries slow, or failure-clasps rise — no 429 ever returned | The **advisory sender warm-up meter** (this page)   | Read the meter; pace the campaign down to `recommended_daily_ceiling`.                                                                                      |
| The dashboard warm-up card pins at a `poor` or `critical` reputation tier and the recommendation stops growing                                         | The **closed-loop factor** on the advisory meter    | Jump to [Reputation-kernel tiers](#reputation-kernel-tiers) below; this is carrier feedback holding the ramp, not a bug.                                    |

Both gates can coexist on the same tenant — one campaign can be hard-refused on its 10DLC numbers while an advisory sender quietly overruns its recommendation. Run the classifier first; the fix paths differ.

## Read the sender warm-up meter

The meter is a pure read of your tenant's own send history — a detailed per-sender ceiling with no migration step. Two endpoints cover the fleet and one sender respectively.

### Fleet view

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/messages/senders/warmup?limit=100" \
  -H "X-API-Key: dv_live_sk_..."
```

Returns every **warmable** sender you send from, busiest first:

* `scope` — the classification that decides whether a sender gets warmed at all:
  * `alphanumeric` (e.g. `ACME`) and `international_long_code` (a non-US long code) → **warmed here**; that is the point of this page.
  * `domestic_10dlc` → **excluded** from these results; the hard-gate number-warming engine owns it (see the split table above).
  * `short_code` → **excluded**; short codes are pre-vetted, so a ramp would be a mismatch.
* `days_active` — whole UTC days since the sender's first outbound send.
* `recommended_daily_ceiling` — today's advisory ceiling on the geometric ramp, **after** the reputation factor pulled it down where applicable. Pace against this.
* `warmup_complete` — `true` once the time-curve has topped out (≈ day 24 at the default ramp); after that the advisory ramp no longer binds and your sender's ceiling is tenant-level.
* `reputation.score` (0–100) + `reputation.tier` — the same DLR window the per-DID surface uses; a sender's 42 means the same thing as a 42 on a DID.

The response also echoes the ramp constants in `ramp` (`base_daily`, `growth_factor`, `max_daily`, `ramp_days`), so a forecast chart stays honest across versions.

### Per-sender drill-down

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/messages/senders/warmup/lookup?sender=ACME" \
  -H "X-API-Key: dv_live_sk_..."
```

Returns the same meter for one sender plus a day-by-day `forecast` of the ceiling curve (day 0 → ramp end), the same shape the dashboard chart renders. Use it to plan a launch, not to poll minute-by-minute — the recommendation moves once a day.

A `null` data payload means the API found no warmable sender by that exact value: check spelling/case (the lookup is exact), or the sender you are querying is a `domestic_10dlc` number — that case is owned by `GET /api/v1/numbers/:id/warming`.

## Reputation-kernel tiers

The reputation score decides how much of the base curve the ramp actually allows, and it is recomputed from your own delivery receipts. The factor table is deliberately conservative — carrier feedback can only pull the ramp back, never lift it above the fixed curve:

| Tier                          | Ramp factor       | Ramp state  | Meaning                                                                                                    |
| ----------------------------- | ----------------- | ----------- | ---------------------------------------------------------------------------------------------------------- |
| `excellent` / `good` / `fair` | 1.00 (full curve) | `ramping`   | Healthy — the ceiling moves at the base rate                                                               |
| `unknown` or null sample      | 1.00 (full curve) | `ramping`   | Not scored yet — benefit of the doubt                                                                      |
| `poor`                        | 0.50              | `holding`   | Degraded — ceiling holds at half the curve                                                                 |
| `critical`                    | 0.25              | `throttled` | Error-code spike — hard throttle, floored at the day-0 base so a recovering sender can still earn receipts |

Interpretation rules that save a ticket:

* A **factor of exactly 1.00 is not a healthy guarantee**; it means the tier read is not degraded. Check `reputation.tier` whenever you see a stall — a `holding` or `throttled` state prints the reason in `ramp_reason`.
* The **tier drop pins the ramp**: `poor` halves the growth, `critical` quarters it. That is the same closed loop the per-number warming engine runs, so the numbers are comparable.
* A **sender at `warmup_complete=true` can still be throttled** — completion is time-curve only; the reputation factor still applies on top. `warmup_complete` is not a clean bill of health.

## Pace-overflow fix paths

Work these in order; the first one that fits is the right answer.

1. **Pace the campaign throttle to `recommended_daily_ceiling`.** Read the fleet meter, take the sender's current recommendation, and cap your sender loop below it. The advisory meter is not a refusal — your loop is the one that must respect it.
2. **Spread traffic across more senders.** If real volume exceeds one sender's recommendation, add senders and warm them in parallel. The ramp is per-sender, so a fleet of alphanumeric senders ramps faster than one ever will.
3. **Never retry-loop past the recommendation.** The lookup returns a 15-day forecast; queue the overflow for the next UTC day or for a less-busy sender instead of hammering the same corridor. Retry-looping is exactly how a fresh sender earns the complaint failures that drop its tier to `poor`.
4. **Do not mistake the scope.** If the troublesome sender is `domestic_10dlc`, this page is not the fix — the hard gates on [Number warming caps](/troubleshooting/number-warming-caps) own it. If it is a `short_code`, there is no ramp to fix either.

## Escalate to support

Escalate when one of these holds; include the sender value, the output of both endpoints above, and the campaign id you were pacing:

* `warmup_complete=false` stays false while `days_active` grows past the ramp window (≈24 days at the default constants) — the curve should have topped out, so the pin means the reputation tier has locked to `poor`/`critical`.
* `reputation.tier` flips to `critical` on a previously healthy sender — check your recent failure-coded traffic before assuming a scoring bug.
* The fleet list `senders[]` does not contain a sender you are actively sending from — either the value has not been a warmable scope (check the scope split above) or the history window has not observed it yet.
* The lookup returns `null` for a sender you know is live — re-check the exact `sender` value; if spelling/case is correct, escalate with the exact request.

## See also

* [Sender warming and reputation](/concepts/sender-warming-and-reputation) — the model behind the meter (ramp, phases, reputation kernel)
* [Number warming caps](/troubleshooting/number-warming-caps) — the hard 429 gates on 10DLC DIDs (`DAILY_CAP_EXCEEDED`, `WARMING_QUOTA_EXCEEDED`, `NUMBER_MPS_EXCEEDED`)
* [Number warming guide](/guides/number-warming) — the 10DLC ramp walkthrough and progression endpoint
* [Number health, warming, and carrier reputation tracking](/numbers/health) — the per-DID reference that owns `domestic_10dlc` scopes

<Note>
  An advisory sender is a recommendation surface, not a pocket refusal. Pace to `recommended_daily_ceiling` and let the reputation tier recover; the ramp moves on its own clock.
</Note>
