Signed-in visitors

Find out who is signed in to your website with their Lahuta account, and whether they're on your team.

GET /v1/me answers two questions about the person looking at your site: who they are, and whether they're a member of your organization. Use it to greet people by name, prefill forms, or show staff-only links to your own team.

This endpoint is for sites that sign visitors in with their Lahuta account, so your server already holds the visitor's Lahuta access token. If your site has its own separate login, GET /v1/me doesn't apply, and you can skip this page.

Make the call

Send two credentials: your API key as usual, plus the visitor's access token as a bearer token. The key says which organization. The token says which person.

curl https://api.lahuta.org/v1/me \
  -H "X-Api-Key: $LAHUTA_API_KEY" \
  -H "Authorization: Bearer $VISITOR_ACCESS_TOKEN"

A customer who isn't on your team:

{
  "user": {
    "id": "0197a2b8-6d14-7c09-8e3f-1a5b9d2c4e76",
    "email": "jordan.ellis@example.com",
    "firstName": "Jordan",
    "lastName": "Ellis",
    "image": null
  },
  "membership": null
}

One of your own team members:

{
  "user": {
    "id": "0197a1c0-2f83-7b41-9d06-5e8a3c1f7b29",
    "email": "tomas@northsidepottery.com",
    "firstName": "Tomás",
    "lastName": "Rivera",
    "image": null
  },
  "membership": {
    "roles": ["member"],
    "permissions": [
      "contacts:read",
      "contacts:write",
      "inbox:read",
      "inbox:write",
      "campaigns:read",
      "campaigns:write",
      "campaigns:send",
      "newsletter:read",
      "newsletter:write",
      "newsletter:send",
      "events:read",
      "products:read",
      "orders:read",
      "services:read",
      "blog:read",
      "workflows:read",
      "workflows:write",
      "workflows:publish"
    ]
  }
}

Reading the response

  • user is the signed-in person's Lahuta account: their name, email and picture.
  • membership is null for most visitors. It's only set when the person is a member of the organization your API key belongs to.
  • roles lists their roles in your organization, such as admin or member. A person can have more than one. It can be empty for a moment right after someone joins.
  • permissions lists everything their roles allow in your dashboard, added up across all their roles:
PermissionLets them
contacts:read, contacts:writeSee and edit contacts, groups, notes and reminders
inbox:read, inbox:writeRead and answer inbox threads
campaigns:read, campaigns:write, campaigns:sendSee, edit and send campaigns, and edit templates
newsletter:read, newsletter:write, newsletter:sendSee, edit and send the newsletter
events:read, events:writeSee and manage events
events:checkinCheck guests in at the door
bookings:read, bookings:writeSee and manage bookings and booking pages
products:read, products:writeSee and manage products, collections and coupons
orders:read, orders:writeSee and fulfill shop and service orders
orders:refundGive money back
services:read, services:writeSee and manage services and custom offers
blog:read, blog:writeSee and write blog posts
social:read, social:write, social:publishSee, draft and publish social posts
workflows:read, workflows:write, workflows:publishSee, edit and publish workflows
payments:read, payments:manageSee and connect Stripe
settings:manageChange organization settings and the Express Page
members:manageInvite people, change their roles and remove them
api-keys:manageCreate and revoke API keys

A write or manage permission includes read for the same area, so treat someone with events:write as able to see events even if events:read isn't in the list. The list can also hold permissions that aren't in this table. Ignore any you don't use. See Organizations and permissions for what each one covers.

Permissions are for display only

permissions helps you decide what to show, like a "Studio dashboard" link for admins or an "Edit this class" button for people with events:write. It doesn't let the visitor do anything through the Org API. Every Org API call still runs with your API key and its permissions, whoever the visitor is.

So if your site offers an action that only staff should take, your own server has to enforce it: check membership and permissions from GET /v1/me before your server makes the Org API call on their behalf.

A contact you send to PUT /v1/contacts, or with an email, text, checkout, booking, signup or workflow start, can carry userId. It links that contact to the visitor's Lahuta account. Send the visitor's token with the call too, as Authorization: Bearer <token>, and use the user.id that GET /v1/me gave you for that token.

Lahuta only links the visitor the call proves. A userId sent without a token, or with someone else's token, returns 403 with {"_tag":"VisitorNotProven"}, and nothing is written. Leave userId out when there's no signed-in visitor.

When the token doesn't work

On GET /v1/me, a missing, expired or invalid token returns 401 with {"_tag":"Unauthorized"}. Treat it as signed out: show your site as a guest would see it, and offer to sign in again.

A wrong API key returns the same 401. If every visitor suddenly looks signed out, check your key with GET /v1/org, which doesn't need a visitor token.

Every other call ignores a token that doesn't work and runs as if you sent none. You only notice when the call carries userId: it returns 403 with {"_tag":"VisitorNotProven"}, and nothing is written.

Edge cases

  • Don't share the answer between visitors. It depends on each visitor's token, so never put it in a shared cache.
  • Keep the token on your server. Like your API key, the visitor's access token should travel from your server to Lahuta, not from the browser.
  • Other organizations. membership only describes your organization, the one the API key belongs to. A person who runs their own organization on Lahuta still shows membership: null on your site.

See Me in the API reference.

On this page