Base URL, authentication, and limits
Production base URL:
All responses are JSON regardless of the
Accept header. Every endpoint is rate-limited to 60 requests per minute per token, or per IP address when unauthenticated. An invalid ID token returns 401 with an empty message. An invalid machine token returns 401 with {"message":"Unauthenticated."}.
Endpoints
Create an invite
POST /api/v1/me/invites
Before creating, the service resolves the referrer’s Invite Definition from their profile status and checks eligibility: the definition is within its campaign window, and the referrer has invites remaining or an override. If the address has opted out, the request is refused. If the address has already accepted an invitation, the service returns a normal-looking pending invite and sends no email, so the response never reveals whether an address is already in the program.
Returns
200 with the invite object in data. The invitation email is sent during the request.
List invites
GET /api/v1/me/invites
Returns every invite the referrer has sent, ordered oldest first by invited_at, plus a meta object:
Read one invite
GET /api/v1/me/invites/{id}
Returns 200 with the invite object, or 404 if the invite does not exist or belongs to a different referrer.
Resend an invite
POST /api/v1/me/invites/{id}/resend
Returns 202 with {"data":{"message":"Invite scheduled for re-send."}}, or 400 with {"data":{"error":"Invite expired."}}. Resends are capped by a tenant setting, three by default. Beyond the cap the call still returns 202 and no email is sent. Resends are also suppressed for invites that are not pending or whose address has opted out.
Revoke an invite
POST /api/v1/me/invites/{id}/revoke
Returns 200 with the invite now REVOKED, or 400 with {"data":{"error":"Cannot revoke a non-pending invite."}}. Revoked invites do not count against quota.
Validate an invite
POST /api/v1/invites/{id}/validate
Returns
200 with an empty body when the invite is pending, unexpired, and the address matches. Otherwise returns 422 with {"data":{"error":"Validation failed as incoming email is different to invite email."}}, or one of the state errors.
Accept an invite
POST /api/v1/invites/{id}/accept
The service checks the invite state before validating the body, so a malformed request against an expired invite returns
410, not 422. On success it finds the profile by recipient_external_id, then by email, or creates one; writes the custom attribute invites.invited_by with the referrer’s profile ID; applies the definition’s default statuses; marks the invite ACCEPTED; and marks any other pending invites to the same address DECLINED.
Returns 200 with the profile, not the invite:
422 with {"data":{"error":"Refusing to accept as incoming email is different to invite email."}} on an address mismatch, or one of the state errors.
Read any invite
GET /api/v1/invites/{id}
Returns 200 with the invite object for any referrer, or 404.
The invite object
The response does not include
recipient_first_name or public_message.
Status lifecycle
Invites past
expires_at are refused at validate and accept with 410, but their status field is not automatically changed to EXPIRED. When displaying a referrer’s invites, treat status equal to PENDING with expires_at in the past as expired.
Error responses
Three envelopes appear. Check the status code first, then the body.400, 403, 409, 410, and the 422 email mismatch.
422.
401 on machine-token routes. ID-token routes return 401 with an empty message.
State errors from validate and accept:
Behaviour to design around
- Duplicates are not rejected. Inviting the same address twice creates two pending invites, and both count against quota. De-duplicate against the list endpoint if you care.
- Quota counts
PENDING,ACCEPTED,DECLINED, andEXPIREDinvites.REVOKEDinvites are free. Let referrers revoke stale invites to recover quota. - Profile lookups from an ID token are cached for five minutes. A status change that unlocks more invites can take that long to appear in
meta. - Email address is the matching key at accept. If the invitee joins with a different address, the referral is not credited.
- The email is sent during the create request. Response time includes email delivery.