---
title: "Jyotish Donation Decide Endpoint"
method: POST
path: "/jyotish/donation/decide"
---

# Jyotish Donation Decide Endpoint

`POST /jyotish/donation/decide`

## Request

- Base URL: `https://jyotish-api.bda.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://jyotish-api.bda.ai/jyotish/donation/decide`
- Auth: none declared

Deterministic donation prompt rule engine (Block 7).

Inputs:
  - state:   per-user DonationPromptState (client-persisted)
  - signals: surface + value_event + dwell + intent + question_text
  - consent: SEPARATE marketing/whatsapp/data-processing consent
             layers (NEVER bundled per Block 7 directive).

Returns the decision (should_show_prompt, prompt_type, copy_key,
rendered_copy) plus state_updates the client merges back into its
localStorage envelope.

NO server-side DB write happens in this pass. Storage migration
is a separate block (will be presented + approved before any DDL).

The LLM is NEVER called by this endpoint. Pure rules + lookup.

## Request body

- DonationDecideRequest: Inputs for the donation prompt rule engine. Client owns the state envelope (persisted in localStorage in pass 1 — no server DB writes). The endpoint runs deterministic rules and returns a decision plus a `state_updates` patch the client should merge back into its state. Audit trail (in `decision.audit_trail`) lists every rule that fired, so Codex can trace why a prompt did / did not show.
  - `state` DonationPromptState, required: Per-user/session counters + cooldowns. All fields are optional on the wire so a fresh visitor can post `{}` and the rule engine treats them as zeros/Nones.
    - `session_id` string, nullable
    - `profile_id` string, nullable
    - `impression_count` integer
    - `dismiss_count` integer
    - `donate_click_count` integer
    - `last_prompt_at` string, date-time, nullable
    - `last_prompt_surface` string, nullable
    - `last_prompt_reason` string, nullable
    - `last_prompt_copy_key` string, nullable
    - `questions_since_last_prompt` integer
    - `questions_since_donation` integer
    - `donation_cooldown_until` string, date-time, nullable
    - `last_donation_at` string, date-time, nullable
    - `donated_total` number, nullable
    - `donated_recently` boolean
    - `marketing_consent` boolean
    - `whatsapp_consent` boolean
    - `sensitive_suppression_count` integer
    - `created_at` string, date-time, nullable
    - `updated_at` string, date-time, nullable
    - `lifetime_dwell_seconds` integer
  - `signals` DonationSignals, required: The dynamic inputs the rule engine reads for the current turn.
    - `surface` 'soft_inline' | 'modal_after_value' | 'report_support_prompt' | 'recurring_support_prompt' | 'donor_thank_you' | 'passive_dwell' | 'email_footer' | 'whatsapp', required
    - `value_event` boolean
    - `dwell_seconds` integer, nullable
    - `questions_total` integer
    - `intent_domain` string, nullable
    - `question_text` string, nullable
    - `report_generated` boolean
    - `report_downloaded` boolean
    - `mobile_fullscreen` boolean
  - `consent` ConsentFlags, required: Codex rule: marketing/fundraising consent and WhatsApp consent are SEPARATE from birth-data processing consent. They are NEVER bundled. The rule engine reads them; the UI presents them as SEPARATE checkboxes (never one combined checkbox).
    - `data_processing_consent` boolean
    - `service_email_consent` boolean
    - `marketing_consent` boolean
    - `whatsapp_consent` boolean

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/bda/apis/bda-jyotish-panchang-service.md) · [All operations](https://skmtc.dev/bda/apis/bda-jyotish-panchang-service/llms.txt) · [OpenAPI document](https://skmtc.dev/bda/apis/bda-jyotish-panchang-service/revisions/90f241bf4009?raw)
