Ambassador Program
What's live in the Campus Ambassador program today — application intake, admin review, and what's still rolling out.
Ambassador Program
The Campus Ambassador program is rolling out in phases, following the same pattern the Affiliate program went through: application intake and review first, the rewards loop next.
This page describes a program mid-rollout
Application intake and admin review are live. The points economy previewed on the public marketing
page is direction, not yet shipped. If you are building against this, verify against
apps/server/src/routes/ambassador.ts and apps/server/src/routes/admin/ambassadors.ts.
Feature-flag gated
The whole program sits behind a boot-time flag, config.growth.ambassadorProgramEnabled, read once
from AMBASSADOR_PROGRAM_ENABLED at server startup.
- Default: enabled outside production, disabled in production unless explicitly turned on.
- When off: the ambassador API routes return
503("The ambassador program is not available yet"), and Studio's/ambassadorroute shows a "Coming Soon" screen. - Changing the flag requires a server restart — it is a config-only boolean, not a runtime toggle.
What's live today
Applying
The application form lives on the marketing site at veriworkly.com/ambassador/apply, not in Studio.
POST /api/v1/ambassador/apply accepts:
| Field | Required | Validation |
|---|---|---|
collegeName | Yes | 2–160 characters. |
graduationYear | Yes | A real 4-digit year (19xx or 20xx), validated client- and server-side. |
whyJoin | Yes | 20–1,000 characters. |
superpower | Yes | 2–300 characters. |
funFact | Yes | 2–300 characters. |
vibeCheck | No | Up to 80 characters. |
socialHandle | No | Up to 120 characters. |
Re-applying after a rejection is allowed — the application is upserted, its status reset to
PENDING, and the previous review metadata cleared. Applying while already PENDING, or while
already an approved AMBASSADOR, is rejected with a 400.
Applying sets the user's ambassadorStatus to PENDING in the same transaction that writes the
application.
Checking status
GET /api/v1/ambassador/me returns the user's role, ambassadorStatus, collegeName, and
graduationYear.
Admin review
The review workflow is live, both as an API surface and as a Studio screen:
| Endpoint | Purpose |
|---|---|
GET /api/v1/admin/ambassadors | List applications as { items, total, limit, offset }, filterable by status (PENDING, APPROVED, REJECTED), graduation year, and a free-text query. |
GET /api/v1/admin/ambassadors/summary | Counts by status, the number of active ambassadors, and applications received in the last 7 days. |
GET /api/v1/admin/ambassadors/roster | Everyone currently holding the AMBASSADOR role, with their campus and referral count. |
GET /api/v1/admin/ambassadors/:id | One application in full, plus who reviewed it and its admin audit history. |
PATCH /api/v1/admin/ambassadors/:id | Review an application: action is APPROVE or REJECT, with an optional reviewNote up to 500 characters. |
All require admin authentication. Approving flips the application's status and the user's
role to AMBASSADOR inside a single transaction; rejecting sets the role back to USER. Neither
ever changes a role it does not own, so an admin reviewing their own application keeps ADMIN.
Either way, an AdminAuditEntry is written recording the actor, the action
(ambassador.application.approve / .reject), the application id, and the review note.
An application that has already been reviewed cannot be reviewed again — a second PATCH returns a
400.
Reviews have a Studio screen
The review queue lives at /admin/ambassadors in Studio, with a per-application detail view and
an approved-ambassador roster. The singular /api/v1/admin/ambassador path still resolves as an
alias, but its list response is now paginated rather than a bare array.
Studio's /ambassador page
A status page reflecting two states:
- Pending — an "Application Under Review" badge, with copy explaining that a decision will be emailed.
- Active ambassador — an "Active Campus Ambassador" badge, and a placeholder for the perks, resources, and stats that ship with the rewards layer.
Applying itself happens on the marketing site, not here.
Data model
enum AmbassadorApplicationStatus { PENDING APPROVED REJECTED }
model AmbassadorApplication {
id String @id @default(cuid())
userId String @unique
collegeName String
graduationYear String
whyJoin String
superpower String
funFact String
vibeCheck String?
socialHandle String?
status AmbassadorApplicationStatus @default(PENDING)
reviewedBy String?
reviewedAt DateTime?
reviewNote String?
}The User record additionally carries an ambassadorStatus string (default "NONE") mirroring the
application status, and the Role enum includes a dedicated AMBASSADOR value.
What's still rolling out
The public marketing page at veriworkly.com/ambassador previews a fuller experience that is not yet implemented in the backend:
- Points for invites and invite conversions.
.edu-verified badges.- Points for video and article contributions.
- A redemption threshold for a 30-day Creator Pro voucher.
- An interactive points calculator and a public leaderboard.
There is no points, redemption, or leaderboard model in the database today. Treat the marketing page's numbers as a preview of intent, not as a live earning schedule.
API
See the Ambassador API reference for full request and response shapes.
Related
- Affiliate Program — the program whose rollout pattern this one is following, and which already has its full rewards loop live.