Skip to main content

Launch (signing a user in)

Your ERP is the identity provider. TimetableMaster never stores or checks a password for your users, and never shows them a login screen.

The flow

1. User clicks "Timetable" in your product
2. Your BACKEND calls POST /api/partner/v1/auth/token (API key, server-to-server)
3. You redirect the user's browser to the returned launchUrl
4. We set a session cookie and drop them into the timetable UI

The token you get back is single-use and expires in 60 seconds. It has to travel through a browser, and URLs leak into history, Referer headers and proxy logs. A short single-use token means a leaked launch URL is worthless almost immediately. Mint one per click; never cache them.

Mint a token

POST /api/partner/v1/auth/token
Authorization: Bearer ttm_<your api key>
Content-Type: application/json

{
"externalUserId": "EMP-1001",
"name": "Edna Krabappel",
"email": "edna@northwood.example",
"shortName": "EK",
"role": "Registrar"
}
FieldRequiredNotes
externalUserIdYesYour opaque id for this user. This is the identity we key on
nameOn first launchRequired only when we have not seen this externalUserId before
emailNoLinks a login account. Omit for users who only need to be scheduled
shortNameNoUsed in compact timetable views
roleNoYour role name; mapped to ours per organisation (see below)

Response:

{
"success": true,
"data": {
"token": "…",
"launchUrl": "https://api.timetablemaster.com/launch?token=…",
"expiresIn": 60,
"userCreated": true
}
}

Then 302 the browser to launchUrl.

Users are created automatically

The first time an externalUserId arrives, we create the user. Every later launch reuses it. You never pre-provision anyone.

Two behaviours worth knowing:

Identity is externalUserId, never email. Matching on email would let anyone holding the API key bind a launch onto an existing account by claiming its address. Emails are stored as a contact detail, not as identity.

Names must be unique within an organisation. If two people share a name, the second is created as "John Smith (EMP-2002)" and the response includes renamedTo so you can reconcile. We never merge two of your users into one of ours. That would fuse their timetables.

A launch never renames an existing user. Name changes belong to entity sync.

Role mapping

Send your own role name in role. We map it per organisation, configured during onboarding:

"Registrar" → admin
"Faculty" → member

Anything unmapped falls back to the organisation's default role, so a new role on your side can never silently grant elevated access. owner is not assertable: it carries ownership-transfer semantics and cannot be assigned from a payload.

Logout

Hitting logout clears the session and returns a returnUrl pointing back into your product. We never render a login page for a partner user. Configure the URL during onboarding.

Errors

CodeStatusMeaning
EXTERNAL_USER_ID_REQUIRED400externalUserId missing or blank
NAME_REQUIRED400First launch for this user, and no name was supplied
NAME_COLLISION409The name and its disambiguated form are both taken
MEMBER_INACTIVE403The user is archived in TimetableMaster
PARTNER_ACCESS_DISABLED403Partner access is not enabled for this organisation
INVALID_LAUNCH_TOKEN401Already used, expired, or never existed

Access is re-checked when the token is redeemed, not only when it is minted. Revoking access invalidates tokens already in flight.