Skip to Content
The AKIN Travel developer platform is in beta — APIs may change. Get started →
Server-side enrollment

Server-side enrollment

If you own your own user registration — your users sign up inside your app, not on an AKIN surface — you can enrol them in AKIN loyalty server-to-server, at registration time, without the member ever seeing an AKIN login.

This is a single mutation, enrollMember, authorised on your x-partner-api-key. It creates (or finds) the AKIN member, enrols them in your program, and returns the AKIN member id for you to persist.

Requires a secret key with member:write. Enrolling a member is a write, so it needs a secret (server-only) key carrying the member:write scope — a publishable/browser-safe or read-only key is rejected. Grant the scope when you create the key in the dashboard, and keep the key on your server. See publishable vs secret keys.

On Node? The typed Server SDK exposes this as akin.enrollMember(...) — typed input/result, structured errors, and rate-limit handling — instead of hand-rolling the request below.

When to use this

You want…Use
To enrol a user you just registered in your own appenrollMember (this page)
The member to sign in on an AKIN surface (magic link, passkey)The authentication flows

enrollMember is headless: no magic link, no email, no password — the member is never prompted to do anything. If that same member later signs in on an AKIN surface with the same email, they land on the same account (accounts are keyed by email), so there is never a duplicate.

The mutation

mutation EnrollMember($input: EnrollMemberInput!) { enrollMember(input: { email: "ada@example.com" firstName: "Ada" lastName: "Lovelace" externalId: "your-loyalty-id-123" # optional }) { memberId # AKIN member id — persist this created # true if a new AKIN account was created enrollmentChanged # true if this enrolment was new (vs an idempotent replay) } }

Send it with your partner API key:

curl https://api.akintravel.com/graphql \ -H "Content-Type: application/json" \ -H "x-partner-api-key: $AKIN_PARTNER_API_KEY" \ -d '{ "query": "mutation($i: EnrollMemberInput!){ enrollMember(input:$i){ memberId created enrollmentChanged } }", "variables": { "i": { "email": "ada@example.com", "firstName": "Ada", "lastName": "Lovelace", "externalId": "your-loyalty-id-123" } } }'

Input

FieldRequiredNotes
emailyesMatched case-insensitively for idempotency.
firstNameyesUsed only when creating a new account.
lastNameyesUsed only when creating a new account.
externalIdnoYour own loyalty key for this member. Stored on the enrolment and unique within your partner — re-send it to correct a mapping. Lets you look the member up later by your own id.

There is no partnerId field — the partner is always derived from your API key. You cannot enrol a member into another partner’s program, and you cannot set a member’s tier, points, or status (those are AKIN-controlled).

Idempotency

enrollMember is safe to call repeatedly for the same (your partner, email):

  • If the email already maps to an AKIN member, that member is reused — created is false and the existing memberId is returned. No profile fields are overwritten.
  • If the member is already enrolled in your program, enrollmentChanged is false. The call still succeeds and returns the same memberId.
  • A re-send that omits externalId never clears a previously-stored one; a re-send that includes a different externalId updates it.

This means you can call it on every registration (and on retries) without risk of duplicates.

Webhooks

A fresh account fires member.created; a new (or reactivated) enrolment fires member.enrolled. Idempotent replays that change nothing are silent. See Webhooks.

Last updated on