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

# User Context Management

> Learn how to manage user contexts in Opigno Enterprise, including their creation, updating, retrieval, and activation or deactivation. This guide covers best practices for handling identity, permissions, and privacy through user contexts.

## What is a User Context?

A user context is a record that represents a user's identity and permissions. It helps the system track what a user is doing, what trainings they have, and what they are allowed to access.

<AccordionGroup>
  <Accordion title="Is the Opigno-Client-UUID required for every API request?">
    Yes, the `Opigno-Client-UUID` header is required for every API request, regardless of whether the user is authenticated or anonymous. This ensures that every user interaction—authenticated or anonymous—can be tracked and managed via a unique user context.
  </Accordion>

  <Accordion title="Can the Opigno-Client-UUID value be empty?">
    Yes, the value may be empty for anonymous users when you don't want to track their progress. In this case, access is limited to only certain API queries, such as `getLearningPath`, `getCatalogData`, and other similar operations.
  </Accordion>

  <Accordion title="What is the difference between an Authorization header and Opigno-Client-UUID?">
    The `Authorization` header is used for server-to-server authorization, allowing your application to access the API and make GraphQL requests. However, it does not identify or link the request to a specific user.

    The `Opigno-Client-UUID` is a unique identifier for the user and is required to display user-related data, track progress, and associate actions with a particular user context.
  </Accordion>

  <Accordion title="What headers are required for API requests?">
    You must include two headers in every API request:

    * **Authorization: Bearer YOUR\_ACCESS\_TOKEN**\
      This header contains the access token you received after authenticating. It proves that your application is allowed to use the API.
    * **Opigno-Client-UUID: `your-user-uuid`**\
      This header tells the system which user the request is about. The UUID is a unique identifier for the user. The system checks if your application is allowed to act on behalf of this user.

    <Info>
      The `Authorization` header shows who you are (your application's identity), and the `Opigno-Client-UUID` header shows which user you want to manage or get information about.
    </Info>
  </Accordion>

  <Accordion title="How do I handle authenticated vs. anonymous users?">
    * For **authenticated users**: Generate a unique UUID and call `setUserContext` with the `scope` set to `AUTHENTICATED`.
    * For **anonymous users**: Generate a unique UUID for each user and call `setUserContext` without the `scope` field. This allows tracking of progress and actions for anonymous users, without exposing PII or requiring authentication.
  </Accordion>
</AccordionGroup>

## Types of User Contexts and When to Create

All API requests must include the `Opigno-Client-UUID` header, regardless of whether the user is authenticated or anonymous. This ensures that every user interaction—authenticated or anonymous—can be tracked and managed via a unique user context.

* **Authenticated Users:**
  * Generate a unique UUID for each user.
  * Call `setUserContext` with the `scope` set to `AUTHENTICATED`.
  * This enables full tracking, personalization, and access control.

* **Anonymous Users:**
  * Generate a unique UUID for each anonymous user.
  * Call `setUserContext` without the `scope` field.
  * This allows tracking of progress and actions for anonymous users, without exposing PII or requiring authentication.

Refer to the `setUserContext` mutation examples below for both cases.

<Tip>
  Create a user context for any user whose actions or progress you want to track and who is authenticated.
</Tip>

## Understanding Scopes

Scopes define the level of access and permissions granted to a user context. Common scope values include:

* `AUTHENTICATED`: Standard authenticated user

<Accordion title="Click here to see the scopes">
  <ParamField path="scope" type="enum">
    User's access scope. Determines available features and permissions. This field is optional. For anonymous users, you may omit this field.
  </ParamField>

  <Info>
    Assign the appropriate scope when creating or updating a user context to control access and features. For anonymous users, omit the scope or leave it empty.
  </Info>
</Accordion>

<Tabs>
  <Tab title="Authenticated User">
    You create a user context for a registered, authenticated user by specifying a unique UUID, display name, and setting the scope to `AUTHENTICATED`.

    ```graphql theme={null}
    mutation setUserContext {
      setUserContext(
        uuid: "3bc5b83f-7d96-4b0c-b1e6-627a01d1ab77",
        displayName: "Andrew M. Pearson",
        isActive: true,
        scope: AUTHENTICATED
        isPrivate: false,
        email: "apearson@mail.com"
      ) {
        errors
        response {
          displayName
          id
          isActive
          scope
          uuid
          isPrivate
          email
        }
      }
    }
    ```
  </Tab>

  <Tab title="Anonymous User">
    For anonymous users (such as those taking a Learning Path without registration), omit the `scope` field. Use a unique but non-identifiable UUID and a generic display name.

    ```graphql theme={null}
    mutation setUserContext {
      setUserContext(
        uuid: "anon-123456",
        displayName: "Anonymous User",
        isActive: true,
        isPrivate: true
        # scope omitted for anonymous
      ) {
        errors
        response {
          displayName
          id
          isActive
          scope
          uuid
          isPrivate
        }
      }
    }
    ```
  </Tab>
</Tabs>

## Special Case: Anonymous User Contexts for Learning Path

In some scenarios, you may want to create a user context for an anonymous user (e.g., to allow them to take a Learning Path without registration). In this case:

* Use a unique but non-identifiable `uuid` (e.g., `anon-<random>`)
* Set a generic `displayName` (e.g., "Anonymous User")
* Set `isActive: true`
* We recommend to set `isPrivate: true`, but in fact it's optional and anonymous users will be excluded from the social features in any case.
* Omit the `scope` field

This allows tracking progress for anonymous users without requiring authentication or exposing PII.

## Creating a User Context

To register a new user context, use the `setUserContext` GraphQL mutation.

<Steps>
  <Step title="Prepare the GraphQL Mutation">
    Use the following mutation, replacing example values with your user data:

    <CodeGroup>
      ```graphql GraphQL theme={null}
      mutation setUserContext {
        setUserContext(
          uuid: "3bc5b83f-7d96-4b0c-b1e6-627a01d1ab77",
          displayName: "Andrew M. Pearson",
          isActive: true,
          scope: AUTHENTICATED,
          isPrivate: false,
          email: "apearson@mail.com"
        ) {
          errors
          response {
            displayName
            id
            isActive
            scope
            uuid
            isPrivate
            email
          }
        }
      }
      ```
    </CodeGroup>

    <Accordion title="Click here to see the parameters">
      ### Parameters

      <ParamField path="uuid" type="string" required>
        Unique identifier for the user. A uuidv4 string is recommended, but any unique string may be used if your project requires a different format.
      </ParamField>

      <ParamField path="displayName" type="string" required>
        Full name or pseudonym to display for the user. Avoid exposing PII if not necessary.
      </ParamField>

      <ParamField path="isActive" type="boolean" required>
        Set to `true` to activate the user context upon creation. Otherwise the user will be considered as blocked and API queries will be not accessible for such users.
      </ParamField>

      <ParamField path="scope" type="enum">
        User's access scope. Optional. Typically set to `AUTHENTICATED` for registered users. Omit for anonymous users.
      </ParamField>

      <ParamField path="isPrivate" type="boolean">
        Set to `true` to mark the user as a private. Social features like posts, connections, communities are not accessible for the private users.
      </ParamField>

      <ParamField path="email" type="String">
        Email associated with the user context.
      </ParamField>
    </Accordion>
  </Step>

  <Step title="Verify the Response">
    A successful registration returns the new user's details. Check for errors in the response.

    <CodeGroup>
      ```json Success theme={null}
      {
        "data": {
          "setUserContext": {
            "errors": [],
            "response": {
              "displayName": "Andrew M. Pearson",
              "id": "4874",
              "isActive": true,
              "scope": ["AUTHENTICATED"],
              "uuid": "3bc5b83f-7d96-4b0c-b1e6-627a01d1ab77"
              "isPrivate": false,
              "email": "apearson@mail.com"
            }
          }
        }
      }
      ```
    </CodeGroup>

    <Check>
      If the `errors` array is empty, the user context was created successfully.
    </Check>
  </Step>
</Steps>

## Updating a User Context and Anonymization

To update an existing user context, use the same `setUserContext` mutation with the updated fields. For anonymization:

* Use a pseudonymous value for `displayName` if you do not want to expose real names.
* Never use personally identifiable information (PII) if not required.

<CodeGroup>
  ```graphql GraphQL theme={null}
  mutation updateUserContext {
    setUserContext(
      uuid: "3bc5b83f-7d96-4b0c-b1e6-627a01d1ab77",
      displayName: "user_12345",
      isActive: true,
      scope: AUTHENTICATED
      isPrivate: false,
    ) {
      errors
      response {
        displayName
        uuid
        isActive
        scope
        isPrivate
      }
    }
  }
  ```
</CodeGroup>

<Accordion title="Click here to see the parameters">
  <ParamField query="uuid" type="string" required>
    The unique identifier for the user context. Typically, this is a uuidv4 string, but any unique string can be used to suit your project's requirements.
  </ParamField>

  ### Response fields

  <ResponseField name="displayName" type="string" required>
    The user's display name or pseudonym.
  </ResponseField>

  <ResponseField name="id" type="string" required>
    Internal user context ID.
  </ResponseField>

  <ResponseField name="isActive" type="boolean">
    Whether the user context is active.
  </ResponseField>

  <ResponseField name="scope" type="array">
    List of roles or permissions assigned to the user.
  </ResponseField>

  <ResponseField name="uuid" type="string" required>
    The unique identifier for the user context. Typically, this is a uuidv4 string, but any unique string can be used to suit your project's requirements.
  </ResponseField>

  <ParamField path="isPrivate" type="boolean">
    Set to `true` to mark the user as a private. Social features like posts, connections, communities are not accessible for the private users.
  </ParamField>
</Accordion>

<Tip>
  For privacy, generate a pseudonymous string for `displayName` if you do not want to expose real names.
</Tip>

## Retrieving a User Context

Use the `getUserContext` GraphQL query to fetch details about a user context.

<Steps>
  <Step title="Construct the GraphQL Query">
    <CodeGroup>
      ```graphql GraphQL theme={null}
      {
        getUserContext(uuid: "17adb4c1-eb29-44bf-9d9a-5f8d056e58ee") {
          displayName
          id
          isActive
          scope
          uuid
          isPrivate
          email
        }
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Review the Response">
    <CodeGroup>
      ```json Success theme={null}
      {
        "data": {
          "getUserContext": {
            "displayName": "John Doe",
            "id": "914",
            "isActive": true,
            "scope": ["AUTHENTICATED"],
            "uuid": "17adb4c1-eb29-44bf-9d9a-5f8d056e58ee"
            "isPrivate": false,
            "email": "jdoe@mail.com"
          }
        }
      }
      ```
    </CodeGroup>
  </Step>
</Steps>

## Publishing and Unpublishing User Contexts

To publish (activate) or unpublish (deactivate) a user context, set the `isActive` field using the `setUserContext` mutation:

<CodeGroup>
  ```graphql GraphQL theme={null}
  mutation deactivateUserContext {
    setUserContext(
      uuid: "3bc5b83f-7d96-4b0c-b1e6-627a01d1ab77",
      isActive: false
    ) {
      errors
      response {
        uuid
        isActive
      }
    }
  }
  ```
</CodeGroup>

<Check>
  A user context is published when `isActive` is `true` and unpublished when `isActive` is `false`.
</Check>
