2026-04-16 10:51:08 +08:00
# Invite Protocol (Frontend <-> Backend)
2026-05-21 16:26:58 +08:00
This document defines the invite/referral contract for authenticated web users.
2026-04-16 10:51:08 +08:00
Protocol verification status:
- Backend route source: `backend/src/v1/invite/router.py`
- Backend service source: `backend/src/v1/invite/service.py`
- Backend schema source: `backend/src/v1/invite/schemas.py`
2026-05-21 16:26:58 +08:00
- Web mapping source: `web/src/lib/api.ts`
2026-04-16 10:51:08 +08:00
## Compatibility strategy
- Additive evolution only.
- Existing response fields are stable and must remain backward-compatible.
## Route
### GET /api/v1/invite/me
2026-05-21 16:26:58 +08:00
Get the current user's invite overview.
2026-04-16 10:51:08 +08:00
**Authorization ** : Requires authenticated session. User identity from JWT `sub` .
**Response (200) ** :
``` json
{
2026-05-21 16:26:58 +08:00
"myCode" : "ABC123" ,
"binding" : {
"canBind" : false ,
"boundInviteCode" : "QWE789" ,
"boundAt" : "2026-05-21T10:30:00+00:00"
} ,
"summary" : {
"rewardPoints" : 40 ,
"invitedCount" : 3 ,
"rewardedCount" : 2 ,
"pendingCount" : 1 ,
"rewardedPoints" : 80 ,
"totalPotentialRewardPoints" : 120
} ,
"items" : [
{
"referralId" : "5ed7c3f0-6d1c-4f3f-8b40-2cb537da53e6" ,
"inviteCode" : "ABC123" ,
"boundAt" : "2026-05-18T09:00:00+00:00" ,
"firstCreemPaidAt" : "2026-05-20T11:15:00+00:00" ,
"rewardGranted" : true ,
"rewardGrantedAt" : "2026-05-20T11:15:02+00:00"
}
]
2026-04-16 10:51:08 +08:00
}
```
Field rules:
2026-05-21 16:26:58 +08:00
- `myCode` : string, unique invite code assigned to the current user
- `binding.canBind` : boolean, whether the current user can still bind another user's invite code
- `binding.boundInviteCode` : string or `null` , bound inviter code snapshot
- `binding.boundAt` : ISO 8601 datetime or `null`
- `summary.rewardPoints` : integer `>= 0` , reward granted to inviter and invitee per qualified post-bind CREEM payment
- `summary.invitedCount` : integer `>= 0`
- `summary.rewardedCount` : integer `>= 0`
- `summary.pendingCount` : integer `>= 0` , computed as `invitedCount - rewardedCount`
- `summary.rewardedPoints` : integer `>= 0` , computed as `rewardedCount * rewardPoints`
- `summary.totalPotentialRewardPoints` : integer `>= 0` , computed as `invitedCount * rewardPoints`
- `items` : inviter-side referral list, newest first
- `items[].firstCreemPaidAt` : present only when the invitee has completed the qualifying CREEM payment after binding
- `items[].rewardGranted` : whether inviter-side invite reward has been credited
- `items[].rewardGrantedAt` : present only when `rewardGranted=true`
### POST /api/v1/invite/bind
Bind another user's invite code to the current account.
This endpoint is write-once:
- a user can bind at most once;
- binding cannot be removed;
- self-binding is forbidden;
- binding is allowed even if the current user already has completed CREEM payments.
**Authorization ** : Requires authenticated session.
**Request ** :
``` json
{
"code" : "ABC123"
}
```
Field rules:
- `code` : string, exactly 6 uppercase alphanumeric invite characters after normalization
**Response (200) ** :
Same shape as `GET /api/v1/invite/me` after the bind succeeds.
2026-04-16 10:51:08 +08:00
## Error contract linkage
- RFC7807 + extension `code` , optional `params` .
- Shared registry: `docs/protocols/common/http-error-codes.md` .
- Error codes for this feature:
- `INVITE_CODE_NOT_FOUND` (404): Invite code not found for current user
2026-05-21 16:26:58 +08:00
- `INVITE_BIND_CODE_NOT_FOUND` (404): Invite code to bind does not exist
- `INVITE_ALREADY_BOUND` (409): Current user already bound an inviter
- `INVITE_SELF_BIND_FORBIDDEN` (409): Current user attempted to bind their own code
- `INVITE_CODE_NOT_BINDABLE` (409): Invite code is disabled, expired, or has no owner
- `INVITE_CODE_INVALID` (422): Invite code format is invalid
2026-04-16 10:51:08 +08:00
## Data model linkage
- Invite codes are stored in `invite_codes` table.
2026-05-21 16:26:58 +08:00
- Referral bindings are stored in `invite_referrals` .
- See `docs/protocols/common/user-points-chat-data-protocol.md` for `profiles.referred_by` , `invite_referrals` , `redeem_code_batches` , and `redeem_codes` .