---
title: "Ingest Paywall Events"
method: POST
path: "/paywall-events"
tags: ["paywall-events"]
---

# Ingest Paywall Events

`POST /paywall-events`

## Request

- Base URL: `https://api.projectindi.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.projectindi.com/paywall-events`
- Auth: none declared

Fold a batch of paywall funnel events onto the caller's journey row.

A non-consented caller gets the same 200 and the same body as a consented
one: the client did nothing wrong, must not retry, and must not be able to
read its consent verdict off the response.

Auth is enforced by the global JWT middleware before we get here (this
prefix is absent from ``AuthMiddleware.public_paths``), so
``request.state.user_id`` is already populated - identity never comes from
the request body.

## Request body

- PaywallEventBatch
  - `events` PaywallEvent[], required
    - `event` 'viewed' | 'checkout_started' | 'checkout_dismissed' | 'converted' | 'web_fallback_tapped', required
    - `platform` 'ios' | 'android' | 'web', required
    - `surface` 'onboarding' | 'dashboard', nullable
    - `billing_period` string, nullable

## Response `200`

Successful Response

- SrcApiPaywallEventsRoutesIngestResponse: ``accepted`` counts events taken off the client's hands, NOT rows written. It is deliberately the same for a consented and a non-consented caller: the old event table let "0 rows written" stand in for both, and losing that would turn the response into a consent oracle. Nothing here reports what was stored - a journey row has no per-event acceptance to report, and both clients are fire-and-forget and never read the body.
  - `accepted` integer, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/projectindi/apis/indi-agent-api-first-principles.md) - [All operations](https://skmtc.dev/projectindi/apis/indi-agent-api-first-principles/llms.txt) - [OpenAPI document](https://skmtc.dev/projectindi/apis/indi-agent-api-first-principles/revisions/25a7813e21fd?raw)
