---
title: "Comp User"
method: POST
path: "/api/v1/admin/users/comp"
tags: ["admin"]
---

# Comp User

`POST /api/v1/admin/users/comp`

## Request

- Base URL: `https://yondry.app` (the document declares no server; this is the origin it was published from)
- URL: `https://yondry.app/api/v1/admin/users/comp`
- Auth: none declared

Grant/revoke free Plus for a user by email. Requires X-Admin-Key.

Fixes the "we keep gating ourselves / how do I comp someone" problem
without hand-editing production rows.

## Headers

- `X-Admin-Key` string, nullable

## Request body

- CompUserRequest: Grant or revoke free Plus access for a user, by email. modes: - "tester": is_tester=True — permanent free access (team / internal). - "lifetime": is_lifetime=True — gifted lifetime access. - "until": plus_until set to a future date — time-limited comp (e.g. a Product Hunt winner gets 1 year). Provide `days` OR `until`. - "revoke": clear all three (is_tester=False, is_lifetime=False, plus_until=None) — remove any comp granted here. Note: this sets Yondry's own entitlement flags directly. It does NOT create a RevenueCat entitlement — for externally-visible comps that should show in the RC dashboard, grant a promotional entitlement in RC instead. Both make `_is_plus()` return true; this is the fast in-house path.
  - `email` string, required
  - `mode` 'tester' | 'lifetime' | 'until' | 'revoke', required
  - `days` integer, nullable
  - `until` string, date-time, nullable

## Response `200`

Successful Response

- CompUserResponse
  - `user_id` string, required
  - `email` string, required
  - `is_tester` boolean, required
  - `is_lifetime` boolean, required
  - `plus_until` string, date-time, nullable, required

## Other responses

- `422`: Validation Error

---

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