# invite codes ZDS invite codes are modeled after the official PDS tables and XRPC surface. They are account-creation credentials, not sessions and not repo records. ## shape - `com.atproto.server.describeServer` reports whether account creation requires an invite through `inviteCodeRequired`. - `com.atproto.server.createInviteCode` creates one code with a configured `useCount`. - `com.atproto.server.createInviteCodes` creates batches of codes. - `com.atproto.server.getAccountInviteCodes` lists codes owned by the current account and their recorded uses. Admin code creation requires `Authorization: Bearer $ZDS_ADMIN_TOKEN`, matching the official PDS admin-token boundary. Tranquil routes invite administration through its own infra/user store traits, but it is still privileged infrastructure behavior rather than normal account auth. ## storage The official PDS stores invite metadata in `invite_code` and each redemption in `invite_code_use`. Availability is computed by comparing `availableUses` with the number of uses. ZDS follows that model: - `invite_codes.available_uses` is the total allowed redemptions. - `invite_codes.disabled` prevents future redemptions. - `invite_codes.for_account` records which account owns or was gifted the code. - `invite_codes.created_by` records who minted it. - `invite_code_uses` records each account that consumed a code. Tranquil has the same conceptual model, but its PostgreSQL path decrements `available_uses` as part of consumption and also records the use. Both implementations treat disabled or exhausted codes as invalid. ## behavior Invite codes do not expire in the official PDS, Tranquil, or ZDS. A code can be used more than once only when it was created with `useCount > 1`. Once the number of recorded uses reaches `available_uses`, `createAccount` returns `InvalidInviteCode`. When `ZDS_INVITE_REQUIRED=true`, `createAccount` rejects missing, unknown, disabled, or exhausted invite codes. Account creation and invite use recording happen in the same SQLite transaction while the store lock is held, so racing requests cannot both consume a one-use code. When invite-required mode starts against an empty database, ZDS creates one bootstrap code and logs it. After that, mint codes through the XRPC endpoint. For local admin operations, assume `ZDS_ADMIN_TOKEN` is set in the repo `.env` and source it before running the Just target: ```sh set -a; . ./.env; set +a; just invite https://pds.zat.dev ``` For a multi-use code: ```sh set -a; . ./.env; set +a; just invite https://pds.zat.dev 3 ``` For a code assigned to a specific DID: ```sh set -a; . ./.env; set +a; just invite https://pds.zat.dev 1 did:plc:... ``` ## reference notes - The official PDS can periodically create account-owned invite codes when `createAvailable=true` and invite interval/epoch config is enabled. - ZDS supports bootstrap and admin-minted invite codes for gated onboarding. Routine interval-based account issuance is a separate policy surface. - PDS Gatekeeper is adjacent prior art for captcha, 2FA, and migration-only account creation at the boundary; those policies are separate from core invite-code accounting.