> ## Documentation Index
> Fetch the complete documentation index at: https://docs.modulex.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Account & access — help

> How to sign in, switch organizations, understand roles, and recover access in ModuleX.

export const MediaEmbed = ({id, type = 'screenshot', caption = '', ext, ratio = '16 / 9'}) => {
  const isVideo = type === 'video' || type === 'app_video';
  const resolvedExt = ext || (isVideo ? 'mp4' : type === 'screenshot' ? 'webp' : 'svg');
  const src = 'https://media.modulex.dev/' + id + '.' + resolvedExt;
  const [status, setStatus] = useState('loading');
  const [isDev, setIsDev] = useState(false);
  const [inView, setInView] = useState(false);
  const boxRef = useRef(null);
  useEffect(() => {
    if (typeof window === 'undefined') return;
    const h = window.location.hostname;
    setIsDev(h === 'localhost' || h === '127.0.0.1' || h.endsWith('.mintlify.app'));
  }, []);
  useEffect(() => {
    if (inView) return;
    if (typeof IntersectionObserver === 'undefined') {
      setInView(true);
      return;
    }
    const el = boxRef.current;
    if (!el) return;
    const io = new IntersectionObserver(entries => {
      if (entries.some(e => e.isIntersecting)) {
        setInView(true);
        io.disconnect();
      }
    }, {
      rootMargin: '300px'
    });
    io.observe(el);
    return () => io.disconnect();
  }, [inView]);
  if (status === 'missing') {
    if (!isDev) return null;
    return <div style={{
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center',
      gap: '0.4rem',
      padding: '1rem 1.25rem',
      margin: '1.25rem 0',
      width: '100%',
      aspectRatio: ratio,
      boxSizing: 'border-box',
      border: '1px dashed rgba(128,128,128,0.45)',
      borderRadius: '0.75rem',
      background: 'rgba(128,128,128,0.06)',
      color: 'currentColor',
      fontSize: '0.85rem',
      lineHeight: 1.45
    }}>
        <div style={{
      display: 'flex',
      alignItems: 'center',
      gap: '0.5rem',
      opacity: 0.75
    }}>
          <span aria-hidden="true">🎬</span>
          <code style={{
      fontSize: '0.75rem'
    }}>{id}</code>
          <span style={{
      fontSize: '0.65rem',
      textTransform: 'uppercase',
      letterSpacing: '0.04em',
      padding: '0.1rem 0.4rem',
      borderRadius: '0.4rem',
      background: 'rgba(128,128,128,0.18)'
    }}>
            {type}
          </span>
        </div>
        <div style={{
      opacity: 0.9
    }}>{caption || 'Media not uploaded yet.'}</div>
        <div style={{
      fontSize: '0.7rem',
      opacity: 0.5
    }}>
          Upload to R2 as <code>{id}.{resolvedExt}</code> — preview only, hidden in production.
        </div>
      </div>;
  }
  const mediaStyle = {
    display: status === 'loaded' ? 'block' : 'none',
    width: '100%',
    height: 'auto',
    borderRadius: '0.75rem'
  };
  const media = isVideo ? <video src={inView ? src : undefined} autoPlay loop muted playsInline preload="metadata" onLoadedData={() => setStatus('loaded')} onError={() => setStatus('missing')} style={mediaStyle} /> : <img src={inView ? src : undefined} alt={caption} onLoad={() => setStatus('loaded')} onError={() => setStatus('missing')} style={mediaStyle} />;
  return <figure style={{
    margin: '1.25rem 0'
  }}>
      <div ref={boxRef} style={status === 'loaded' ? {
    width: '100%'
  } : {
    width: '100%',
    aspectRatio: ratio,
    borderRadius: '0.75rem',
    background: 'rgba(128,128,128,0.06)'
  }}>
        {media}
      </div>
      {status === 'loaded' && caption ? <figcaption style={{
    marginTop: '0.5rem',
    textAlign: 'center',
    fontSize: '0.85rem',
    opacity: 0.7
  }}>
          {caption}
        </figcaption> : null}
    </figure>;
};

Short answers about signing in, working across organizations, and what each role can do. For the full picture, follow the links in each answer to the canonical page.

<CardGroup cols={2}>
  <Card title="Roles & permissions" icon="shield-check" href="/security/roles-permissions">
    What owners and admins can each do.
  </Card>

  <Card title="Org context" icon="building" href="/security/org-context">
    How `X-Organization-ID` picks which organization you act in.
  </Card>
</CardGroup>

## Common questions

<AccordionGroup>
  <Accordion title="How do I switch between organizations?">
    In the app, use the organization switcher to change which organization you are working in. From the API or an SDK, set the `X-Organization-ID` header (the organization's UUID) on each request. See [org context](/security/org-context).

    <MediaEmbed id="MX-MEDIA-4510" type="screenshot" caption={"The organization switcher in the ModuleX app."} />
  </Accordion>

  <Accordion title="What can each role do?">
    There are two roles: **owner** and **admin**. Owners manage billing and own the organization; admins can invite people, manage credentials, and build and run workflows, the AI Composer, and the Assistant. The `member` role has been retired, so there is no longer a read-only role. See [roles & permissions](/security/roles-permissions).

    <Note>
      A few older organizations may still show a leftover `member` value on some records. It is deprecated and not a role you can assign; treat owner and admin as the live roles.
    </Note>
  </Accordion>

  <Accordion title="How do I sign in?">
    ModuleX uses Clerk as its identity provider, so you sign in through Clerk. There is no separate ModuleX username and password. Your account and a starter organization are created on your first sign-in. See [getting started](/help/getting-started).
  </Accordion>

  <Accordion title="I lost my API key — can I get it back?">
    No. API keys (they start with `mx_live_`) are shown only once when you create them and are not stored in a way that lets us show them again. Delete the old key and create a new one in Settings, then update wherever the old key was used. See [authentication](/api-reference/authentication).
  </Accordion>

  <Accordion title="Why do I see &#x22;User is not a member of organization&#x22;?">
    The organization you are calling is not one you belong to. This usually means `X-Organization-ID` is set to the wrong organization, or your API key is scoped to a different one. Set the header to an organization you are a member of. See [org context](/security/org-context).
  </Accordion>

  <Accordion title="I'm locked out — how do I sign back in?">
    Use Clerk's sign-in and recovery options (password reset, single sign-on, and any other method your organization has enabled). If you still cannot get in after that, reach out through [getting help](/help/getting-help).
  </Accordion>
</AccordionGroup>

## Selecting your organization from code

Every organization-scoped request needs an organization. Send your API key in the `Authorization` header and the organization UUID in `X-Organization-ID`. The SDKs take the same two values when you create the client.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.modulex.dev/auth/me \
    -H "Authorization: Bearer mx_live_2J9vK4xM..." \
    -H "X-Organization-ID: a1b2c3d4-0000-0000-0000-000000000000"
  ```

  ```python Python theme={null}
  import asyncio
  from modulex import Modulex

  async def main():
      async with Modulex(
          api_key="mx_live_2J9vK4xM...",
          organization_id="a1b2c3d4-0000-0000-0000-000000000000",
      ) as client:
          me = await client.auth.me()
          print(me)

  asyncio.run(main())
  ```

  ```javascript JavaScript theme={null}
  import { Modulex } from "modulex-js";

  const client = new Modulex({
    apiKey: "mx_live_2J9vK4xM...",
    organizationId: "a1b2c3d4-0000-0000-0000-000000000000",
  });

  const me = await client.auth.me();
  console.log(me);
  ```
</CodeGroup>

<Note>
  If you leave `X-Organization-ID` off an organization-scoped request, the API returns `400` with `X-Organization-ID header is required`. If it points at an organization you are not in, you get `403` with `User is not a member of organization`. See [org context](/security/org-context).
</Note>

## Keep reading

<CardGroup cols={2}>
  <Card title="Organizations, roles & membership" icon="users" href="/concepts/organizations-roles">
    How organizations, membership, and roles fit together.
  </Card>

  <Card title="Getting started — help" icon="rocket" href="/help/getting-started">
    Signing up and making your first call.
  </Card>
</CardGroup>
