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

# Add custom claims

> Encode additional information into your session JWTs using custom claims.

## Use case

* **Store or pass member information:** Pass temporary session state or member metadata to your application.
* **Integrate with 3rd-party services:** Integrate with providers that support JWT-based authentication.
* **Implement custom authorization logic:** Use custom claim templates to pass RBAC information to sessions.

***

## Add custom claims to a session

Include the `session_custom_claims` argument on any authenticate method to add custom claims to a session. This argument takes in an arbitrary JSON object—which may be represented as a `map`, `dictionary`, or object:

```python theme={null}
# initial claims object {}

stytch.session.authenticate(token, session_custom_claims={"key_1": 1, "key_2": 2})
# current claims object {"key_1": 1, "key_2": 2}

stytch.session.authenticate(token, session_custom_claims={"key_1": 9})
# resulting claims object {"key_1": 9, "key_2": 2}
```

### Remove claims

Supply a `null` value to delete a key:

```python theme={null}
# current claims object {"key_1": 1, "key_2": 2}

stytch.session.authenticate(token, session_custom_claims={"key_1": null})
# resulting claims object {"key_2": 2}
```

<Accordion title="Using nested claim objects">
  If the value of a custom claim is a JSON object, the nested values can be updated or deleted using the same methods as above:

  ```python theme={null}
  sessions.authenticate(token, session_custom_claims={
      "b": null,
      "c": 3.5,
      "e": {
          "nested1": "val1",
          "nested2": "val2"
      }
  })
  # resulting claims object
  # {
  #    "c": 3.5,
  #    "d": 4,
  #    "e": {
  #        "nested1": "val1",
  #        "nested2": "val2"
  #    }
  # }

  stytch.session.authenticate(token, session_custom_claims={
      "e": {
          "nested1": nil,
          "nested3": "val3"
      }
  )
  # resulting claims object
  # {
  #     "c": 3.5,
  #     "d": 4,
  #     "e": {
  #         "nested2": "val2",
  #         "nested3": "val3"
  #     }
  # }
  ```
</Accordion>

***

## Custom claim templates

Use [custom claim templates](https://stytch.com/dashboard/custom-claim-templates) to add the same set of claims to **every** session.

* The JSON object output for a particular member will be used as the initial set of custom claims for all of that member's sessions.
* Claims from templates can still be added, updated, or deleted by passing in a `session_custom_claims` argument in an API request.
* Updates to the custom claim template or member metadata propagate to existing sessions the next time a JWT is minted.
* Previously minted JWTs are immutable and cannot be updated.

### Markup syntax

Custom claim template markup language uses `{{ variable }}` syntax to denote information that should be passed in at runtime.

### Member or Organization metadata

Use dot notation to access nested fields when handling Member or Organization metadata. For example, `{{ member.trusted_metadata.subscription.level }}` accesses the `level` field of the `subscription` object in the `trusted_metadata` on a Member object.

### Member RBAC values

The variable `{{  member.rbac.roles }}` is evaluated as an array of all role IDs assigned to the member, e.g. `["stytch_member", "editor", "support_admin"]`.

The variable `{{ member.rbac.$RESOURCE_ID.actions }}` is evaluated as an array of all actions the member can perform on the specific resources. For example, `{{ member.rbac.documents.actions }}` might be evaluated as `["create", "read", "delete"]`.

### List of supported template variables

* `{{ member.external_id }}`
* `{{ member.member_id }}`
* `{{ member.name }}`
* `{{ member.email_address }}`
* `{{ member.rbac.roles }}`
* `{{ member.rbac.$RESOURCE_ID.actions }}`
* `{{ member.trusted_metadata.$PATH }}`
* `{{ organization.external_id }}`
* `{{ organization.organization_id }}`
* `{{ organization.organization_name }}`
* `{{ organization.trusted_metadata.$PATH }}`

<Accordion title="Example">
  The template:

  ```json theme={null}
  {
    "https://hasura.io/jwt/claims": {
      "x-hasura-default-role": "reader",
      "x-hasura-allowed-roles": {{ member.rbac.roles }},
      "x-hasura-user-id": {{ member.member_id }},
      "x-hasura-custom-key": {{ member.trusted_metadata.custom_key }},
      "x-hasura-organization-id": {{ organization.organization_id }}
    }
  }
  ```

  could be combined with the member's information:

  ```json theme={null}
  {
    "member_id": "member-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
    "trusted_metadata": {
      "custom_key": "custom-value"
    }
  }
  ```

  to produce the final set of custom claims:

  ```json theme={null}
  {
    "https://hasura.io/jwt/claims": {
      "x-hasura-default-role": "reader",
      "x-hasura-allowed-roles": ["admin", "reader"],
      "x-hasura-user-id": "member-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
      "x-hasura-custom-key": "custom-value",
      "x-hasura-organization-id": "org-test-12345"
    }
  }
  ```
</Accordion>

***

## Restrictions

Both API-driven custom claims and custom claim templates share these restrictions:

* These claims are reserved and result in an error if set:<br />
  `iss` `sub` `aud` `exp` `nbf` `iat` `jti` `https://stytch.com/*`
* Total claims size cannot exceed 4kb.
* A JWT cannot be modified once it is minted. You must authenticate again to update claims.
