Apply to be a partner
/v1/events/{slug}/ambassadors/applicationsFor people with a following who want a cash rate for every ticket their crew brings, rather than the rewards. The application lands in the organiser's queue in Grofomo beside ones from the affiliate portal. When they approve it, the applicant becomes a commission partner and is emailed their link and a way to get paid.
Check partnerApplications.open on the programme first and hide the form when it is false: a submission is then refused with applications_closed.
Nothing is emailed to the address given until the organiser acts on the application, so there is no confirmation step to build. Sending again from the same email updates a pending application rather than adding another, and the answer is always received, whatever happened before.
Include an empty, visually hidden website field in your form and send whatever is in it. People never fill it; a submission that does is dropped as a bot. There is no Turnstile widget to render.
404 not_found for no visible reason.Request
curl -sS \
-X POST \
-H 'X-Grofomo-Key: pk_live_YOUR_PUBLISHABLE_KEY' \
-H 'Content-Type: application/json' \
-d '{"name":"Sam Rivera","email":"sam@example.com","phone":"07400 123456","instagram":"@samscrew","estimatedTickets":"25_50","audienceReach":"5k_20k","website":""}' \
'https://api.grofomo.com/v1/events/summer-fest/ambassadors/applications?surface=web'Request body
namestringrequired- Their name.
emailstringrequired- Where the organiser replies. Approval is sent here.
phonestring | null- Mobile number, optional.
instagramstring | null- Instagram handle or profile URL, optional.
estimatedTickets"under_10" | "10_25" | "25_50" | "50_plus" | null- One of `estimatedTicketsOptions[].value`, optional.
audienceReach"under_1k" | "1k_5k" | "5k_20k" | "20k_plus" | null- One of `audienceReachOptions[].value`, optional.
messagestring | null- Anything else they want the organiser to know, optional.
websitestring- Leave this out. A hidden form field people never fill; a submission that fills it is dropped as a bot.
Path parameters
slugstringrequired- The event's URL slug. Globally unique. It can change if the organiser renames the event, but an old slug keeps reaching the same event, so a stored one never breaks. Example: `summer-fest`.
Query parameters
surface'web'required- Must be `web` for a website. Omit it and you get the mobile-app surface, which is gated on a different visibility setting — so a perfectly live event can return 404. Example: `web`.
Response
{
"apiVersion": 1,
"data": {
"status": "received"
}
}status"received"- Always `received`, whether this is a new application or an update to one already sent, so the form cannot be used to find out who has applied.
Errors
unauthorizedHTTP 401- No key was sent and the organiser requires one — or the key is invalid, revoked, belongs to another organisation, or is scoped to a different event.
origin_not_allowedHTTP 403- Your site's domain is not on the organiser's allowed list. Browser calls only: a server sends no Origin header and is unaffected.
not_foundHTTP 404- No event with that slug is published on this surface. Check the slug, and check you sent `?surface=web`.
bad_requestHTTP 400- The body did not match the schema: a name and a valid email are required, and the two bands take only the listed values.
applications_closedHTTP 409- The organiser is not taking partner applications for this event.
rate_limitedHTTP 429- Too many applications from this address, or too many waiting for the organiser to review. Try again later.
Notes
- Rate limited to roughly 5 requests per minute per caller. Guidance, not a contract — see caching and rate limits.
Cache-Control: no-store