Zum Inhalt springen

Public Enrollment

publicEnrollToCourse is the only mutation that creates a registration without an authenticated user. It is the integration point for external course portals, your school’s public website, or landing pages that list courses and accept sign-ups.

Server-side it is annotated with @Authorized(auth('Public')), which places it on a dedicated public rate-limiter and enforces strict input validation.

mutation PublicEnrollToCourse($input: PublicEnrollmentInput!) {
publicEnrollToCourse(input: $input) {
status
message
autoLoggedIn
}
}
input PublicEnrollmentInput {
"Course GUID (the UID of the course to enroll in)"
courseGuid: String!
"Optional platform GUID. Omit to use the default platform of the course listing."
platformGuid: String
"Person data. Required for new registrations."
person: PublicPersonInput
"OTP sign-up token issued after email verification. Required when the caller is not authenticated."
signupToken: String
}
input PublicPersonInput {
prename: String!
lastname: String!
"Birth date in YYYY-MM-DD format"
birthdate: String!
address: PublicAddressInput!
}
input PublicAddressInput {
street: String!
streetNr: String!
city: String!
"Postal code"
areaCode: String!
"State / Canton"
state: String!
country: String!
email: String!
phone: String!
}

Every field on PublicPersonInput and PublicAddressInput is required — the public form must collect all of them before submitting.

{
"input": {
"courseGuid": "4a9e2c17-...-b3",
"signupToken": "eyJhbGciOi...",
"person": {
"prename": "Anna",
"lastname": "Müller",
"birthdate": "1998-03-21",
"address": {
"street": "Marktgasse",
"streetNr": "12",
"areaCode": "3011",
"city": "Bern",
"state": "BE",
"country": "CH",
"email": "anna.mueller@example.ch",
"phone": "+41 31 123 45 67"
}
}
}
}

Response:

{
"data": {
"publicEnrollToCourse": {
"status": "SUCCESS",
"message": "Anmeldung wurde erfasst.",
"autoLoggedIn": false
}
}
}

status uses the shared OperationResultStatus enum — typically SUCCESS, WARNING or ERROR. The human-readable message is safe to show directly to the visitor.

signupToken is required whenever the caller is not authenticated. It is issued by the OTP verification endpoint after the visitor confirms their email address. The token binds the enrollment request to a verified email, which prevents bots from creating spurious person records.

Typical flow from the browser:

  1. Visitor enters email → server sends OTP and returns a challenge.
  2. Visitor enters the OTP code → server returns a signupToken (JWT, short-lived).
  3. Visitor fills out the enrollment form → browser sends publicEnrollToCourse with signupToken.

If the visitor is already authenticated (recurring customer logging in before enrolling), omit signupToken and let the authenticated variant enrollToCourse handle it.

When the caller already has a JWT, use enrollToCourse with the same input shape — person then defaults to the current user and can be omitted:

mutation EnrollToCourse($input: PublicEnrollmentInput!) {
enrollToCourse(input: $input) {
status
message
}
}
Terminal-Fenster
curl -X POST https://your.server/graphql \
-H "Content-Type: application/json" \
--data '{
"query": "mutation($input: PublicEnrollmentInput!) { publicEnrollToCourse(input: $input) { status message } }",
"variables": {
"input": {
"courseGuid": "4a9e2c17-...-b3",
"signupToken": "eyJhbGciOi...",
"person": { "prename": "Anna", "lastname": "Müller", "birthdate": "1998-03-21",
"address": { "street": "Marktgasse", "streetNr": "12", "areaCode": "3011",
"city": "Bern", "state": "BE", "country": "CH",
"email": "anna.mueller@example.ch", "phone": "+41 31 123 45 67" } } }
}
}'
  1. The server validates the token, input and course availability.
  2. If the person does not exist yet (matched on email + lastname + birthdate) a new Person record is created in the default person folder configured for the platform.
  3. A CourseRegistration with registrationType: COURSE and the single course in courseIDs is created.
  4. No CourseParticipant is created yet — staff still has to confirm the booking. See Course Participants for that step.

Common failure cases:

statusCause
ERRORInvalid signupToken, expired OTP, unknown courseGuid.
ERRORCourse is full and the platform is configured to reject waitlist.
WARNINGDuplicate registration detected; original registration was kept.

The message field is localized to the course listing’s platform language and is safe to display as-is.