---
title: "Day-1 nudge email to stalled sign-ups, dry run by default (POST)"
method: POST
path: "/cron/stalled-signup-nudge"
tags: ["Cron"]
---

# Day-1 nudge email to stalled sign-ups, dry run by default (POST)

`POST /cron/stalled-signup-nudge`

## Request

- Base URL: `https://api.apphandoff.com/api`
- URL: `https://api.apphandoff.com/api/cron/stalled-signup-nudge`
- Auth: none required

Same as GET. A JSON body `dry_run` is read only when the query string has
none. Protected by CRON_SECRET via the x-cron-secret header.

## Query parameters

- `dry_run` string

## Response `200`

Nudge run counts

- CronStalledSignupNudgeResult
  - `ok` boolean, required: False on any error.
  - `dry_run` boolean, required: True unless the caller sent dry_run=0.
  - `would_claim` integer, nullable, required: Dry run only — users a live tick would claim now; null on a live run or a failed preview.
  - `claimed` integer, required: Users claimed by this run.
  - `sent` integer, required: Nudges accepted by Mailgun.
  - `skipped` integer, required: Claimed users deliberately not emailed (E2E identities, or no longer eligible at send time).
  - `failed` integer, required: Definite pre-delivery failures; retried after the lease until the attempt ceiling.
  - `unknown` integer, required: Sends whose delivery is unknown (timeout/abort); terminal, never retried.
  - `deferred` integer, required: Claimed users not attempted this run (the circuit breaker after a failed or unknown send, or the 90s send deadline); left pending and re-claimed after the lease.
  - `errors` integer, required: Failures of any kind (preview, claim, send, or outcome bookkeeping).

## Other responses

- `403`: Missing or invalid CRON_SECRET

---

[API](https://skmtc.dev/apphandoff/apis/apphandoff-api.md) · [All operations](https://skmtc.dev/apphandoff/apis/apphandoff-api/llms.txt) · [OpenAPI document](https://skmtc.dev/apphandoff/apis/apphandoff-api/revisions/9f138fe46d56?raw)
