Summary: Aury is the third-party vendor behind the in-app AI chat companion that users see as “Seven”. There is only one Aury. The backend mints a session URL server to server, the app opens that URL in a webview, and access is gated by subscription state plus a short grace period after signup. Sources: direct code inspection (lib/external/aury/, lib/backend/practice/ai_companion/, lib/backend/web/public_api/ai_companion/, config/runtime/ in elixir-backend; lib/features/ai_companion/ in 7mind-mobile-apps-monorepo) Last updated: 2026-08-26


Correction to the earlier version of this page

An earlier version of this page claimed there were “two Aurys”, a mobile AI chat companion and a separate B2B2C partner integration in the backend, and marked the relationship between them as TBD. That was wrong, and an agent acting on it would draw the wrong boundary.

There is one Aury. The confusion came from the word “partner” in the backend integration. 7Mind is Aury’s partner, not the other way round: the request body carries partnerId: "7mind" and partnerUserId: <user uuid>, which is how Aury identifies its own customers. This has nothing to do with 7Mind’s B2B2C insurance partners (Barmer, DAK, Charité), which live in the monetization and prevention domains and share no code with it.

Naming

  • Aury is the vendor, and the name used throughout the code: External.Aury, Backend.Practice.AiCompanion, lib/features/ai_companion/, the AURY_* env vars.
  • Seven is the user-facing name in the German app copy and in Linear tickets.

They are the same thing. Expect both spellings in any conversation about this feature.

How a session starts

  1. The app calls POST /ai_companion/companion_session/start on the Public API.
  2. The backend assembles a context for the user: display name, subscription tier, and completed content history from the last 30 days.
  3. The backend calls POST {AURY_BASE_URL}/api/partner/start with an x-api-key header, sending that context as the data field.
  4. Aury returns a URL. The backend passes it back as session_url.
  5. The app opens that URL in a webview.

The chat itself is entirely Aury’s. 7Mind hosts none of it. What 7Mind controls is who gets a session URL, and what context Aury sees.

What the backend tells Aury

The data payload carries:

  • username
  • subscription_status, one of freemium, trial, premium
  • app_usage_history, completed content from the last 30 days with course and category names resolved

The subscription tier is there so Aury can adjust how hard it pushes content at a user who cannot open it. The three values deliberately match the UserType enum the mobile app already uses, so the same three words mean the same three things on both sides of the API.

Access rules

Seven is not available to everyone who can see it. A user has it when any of these holds:

  • they have an active premium subscription, or
  • they are in an active free trial, or
  • their account is less than 4 days old and has never had a trial or a subscription

That third clause is the grace period that lets a new freemium user try Seven at all. It is anchored on signup date, not on first use and not on consent, because signup is the only anchor the backend has. It excludes accounts that already had and lost paid access, so a trial ending inside the first 4 days does not hand the user the remainder of the window back.

Two things to know before changing anything here:

  • This is not a Contentful package feature. Backend.Access derives packages strictly from trials and subscriptions, so a window counted from signup has no representation there. The rule lives in Backend.Practice.AiCompanion.Access instead and is merged into the feature lists at the API boundary. Do not try to move it into a package bundle.
  • The lock is enforced, not merely described. companion_session/start answers 402 Payment Required with the error code ai_companion_locked. A client-only lock would still let any caller with a valid token mint a session URL, which 7Mind pays Aury for.
  • Never answer 401 or 403 from an endpoint the app calls. The mobile apps run a global Dio interceptor (magic_user_token_interceptor.dart) that treats either as an expired session: it deletes the stored auth values and signs the user out of the whole app. A per-feature refusal must use some other status. 404 was the other candidate here and was rejected because this endpoint already answers 404 for a user that cannot be found.

Status as of 2026-08-26: the rule and its exposure to clients are in review, not yet merged.

How the client learns the lock state

Through unlockedFeatures on the account endpoints (/user/me and the signin and signup responses), the sibling of the visibleFeatures list that gates prevention. visibleFeatures answers “show this” and covers locked and unlocked alike; unlockedFeatures answers “the user may actually use this”.

The app already fetches /user/me on every For You render to gate prevention, so the lock state arrives without an extra request.

ai_companion is reported in unlockedFeatures only, never in visibleFeatures. For a package feature like prevention, presence in the first list but absence from the second is what signals a padlock. The companion does not work that way, because the backend does not decide whether it is shown: pilot membership is a client-side call (see below). Listing it as visible would assert something this side does not know, for every 7Mind user, regardless of the real answer. So for the companion, plain absence from unlockedFeatures is the lock.

Cohort and flags

Pilot membership is a client-side decision, not a backend one:

  • ConfigCat flag isAuryEnabled
  • Amplitude Experiment aury-experiment
  • A German-locale guard on the home screen, so the entry point only appears when the app is in German

See mobile-analytics-stack. Consent is stored in Flutter local storage rather than on the backend, so the backend has no record of who opted in.

Gotchas

  • The Aury webview emits deep links with the singular spelling /courseDetail. A route alias exists for exactly this reason and must not be refactored away. See mobile-deep-linking.
  • Aury is 7Mind only. 7Sleep never sees the feature, and the backend scopes it by app.
  • Subscription state is per app. A 7Sleep subscription does not unlock Seven.