Skip to main content
Members are contacts. They authenticate with the contact-auth API, not the platform auth API.

Register a new member

Registration is magic-link only — there is no password-at-signup. A registration request sends a magic link email with a verify-and-sign-in link. The response is always 202 Accepted regardless of whether the email already exists (enumeration-safe). Provide either team_id or slug — exactly one is required.
# Register via hub slug (most common for public-facing flows)
curl -X POST "$MIO_BASE_URL/api/v1/contact-auth/register" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "register_requests",
      "attributes": {
        "email": "member@example.com",
        "slug": "my-hub"
      }
    }
  }'
# Register via team_id (server-side flows where you know the team)
curl -X POST "$MIO_BASE_URL/api/v1/contact-auth/register" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "register_requests",
      "attributes": {
        "email": "member@example.com",
        "team_id": "team_abc123"
      }
    }
  }'
Request body attributes:
AttributeTypeRequiredNotes
emailstringYesThe member’s email address
slugstringOne ofHub slug (URL-friendly handle)
team_idstringOne ofTeam UUID — use when you already have it
redirect_urlstringNoDeep-link for the magic-link email. Requires slug — there is no per-hub allowlist to validate against on the team_id path. Validated against the hub’s settings.auth.allowed_redirect_origins allowlist; an unlisted URL returns 422.
Providing both slug and team_id, or neither, returns 422. Sending a password field returns 422. Password setup is done after sign-in via POST /api/v1/contact-auth/me/password. The response is always 202 Accepted with no body — even when the email is already registered or no hub with the given slug/team_id exists. Use a hub slug when you do not have the hub id yet.
curl -X POST "$MIO_BASE_URL/api/v1/contact-auth/magic" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "magic_link_requests",
      "attributes": {
        "email": "member@example.com",
        "slug": "member-academy"
      }
    }
  }'
If the hub has a custom frontend, include an allowlisted redirect_url. The hosted /m page consumes fragment-delivered magic links for the default flow. Custom frontends can call the consume endpoint directly:
curl -X POST "$MIO_BASE_URL/api/v1/contact-auth/magic/consume" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "magic_link_consumes",
      "attributes": {
        "token": "magic-token-from-email"
      }
    }
  }'

Log in with password

curl -X POST "$MIO_BASE_URL/api/v1/contact-auth/login" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "login_requests",
      "attributes": {
        "email": "member@example.com",
        "password": "password",
        "slug": "member-academy"
      }
    }
  }'
Use the returned contact access token on member-facing routes.