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

# Terms of Service

> Users must accept HIFI's terms before you can create their account. You have two options for collecting this consent:

1. **Use HIFI's ToS Link** - Generate a ToS link and have users accept via HIFI-hosted pages (redirect or embedded)
2. **Reference HIFI's Terms in Your Privacy Policy** - Include HIFI's terms by reference in your own ToS/privacy policy and collect acceptance through your existing flow

Choose the approach that best fits your application architecture and user experience.

## Option 1: Reference Terms

If you already have a terms of service or privacy policy acceptance flow, you can reference HIFI's terms within it. This approach lets you keep users in your own onboarding flow while still generating the required signed agreement ID in the background.

### How It Works

1. **Include HIFI's terms by reference** in your privacy policy or terms of service
2. **Collect acceptance** through your existing flow (checkbox, button, etc.)
3. **Generate signed agreement ID in the background** when user accepts
4. **Create user account** with the generated `signedAgreementId`

### Implementation

Add a reference to HIFI's terms in your privacy policy:

```markdown theme={null}
## Third-Party Services

We use HIFI to process financial transactions. By using our service,
you also agree to HIFI's [Terms & Conditions](https://policy.hifi.com/terms-conditions)
and [Privacy Policy](https://policy.hifi.com/privacy-policy).
```

<Note>
  After updating your Terms of Service, please contact us with documentation or
  evidence of the update. Our team will conduct periodic reviews to ensure
  continued compliance.
</Note>

When the user accepts your privacy policy (which includes HIFI's terms by reference), generate a signed agreement ID in the background:

```javascript theme={null}
import { v4 as uuidv4 } from "uuid";

async function handlePrivacyPolicyAcceptance() {
  // Generate a UUID that will serve as the signedAgreementId
  const signedAgreementId = uuidv4();

  // Generate ToS link in the background to create the signed agreement
  const response = await fetch("https://sandbox.hifi.com/v2/tos-link", {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      idempotencyKey: signedAgreementId,
    }),
  });

  const { url, signedAgreementId: agreementId } = await response.json();

  // Extract session token from URL
  const urlParams = new URLSearchParams(new URL(url).search);
  const sessionToken = urlParams.get("sessionToken");

  // Accept ToS programmatically in the background
  await fetch(
    `https://sandbox.hifi.com/v2/tos-link/:signedAgreementId/accept`,
    {
      method: "POST",
      headers: {
        Authorization: "Bearer YOUR_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        sessionToken: sessionToken,
      }),
    },
  );

  // Store signedAgreementId for user creation
  return agreementId;
}
```

Then create the user account with the `signedAgreementId`:

```bash theme={null}
curl -X POST "https://sandbox.hifi.com/v2/users" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "signedAgreementId": "a4f8b3c2-1d5e-4a7b-9c8d-3e2f1a0b9c8d",
    "email": "user@example.com",
    "firstName": "Jane",
    "lastName": "Doe"
  }'
```

<Note>
  When using this approach, you still need to generate a signed agreement ID,
  but you can do it in the background without redirecting users to a HIFI-hosted
  ToS page. The user never sees the ToS link - you handle the acceptance
  programmatically.
</Note>

## Option 2: Use ToS Link

**Terms of Service (ToS) Links** enable you to collect user consent through HIFI-hosted pages. This approach provides explicit proof of consent and is useful when you want HIFI to handle the ToS presentation.

### How ToS Links Work

<Steps>
  <Step title="Generate ToS link">
    Create a unique ToS link with a UUID that will serve as the signed agreement
    ID.
  </Step>

  <Step title="Present to user">
    Display the ToS page to your user (via redirect or embedded flow).
  </Step>

  <Step title="User accepts">
    User reviews and accepts HIFI's terms and privacy policy.
  </Step>

  <Step title="Create user account">
    Use the same UUID (signedAgreementId) to create the user account.
  </Step>
</Steps>

### Implementation Options

When using HIFI's ToS Link System, you can implement it in two ways depending on your application flow:

### Redirect Flow (Recommended)

Redirect users to a HIFI-hosted ToS page. Best for onboarding flows where redirection is acceptable.

**Advantages:**

* HIFI handles the entire ToS presentation and acceptance
* Automatic styling and updates to terms
* Can be white-labeled with your branding (contact support)

**Use when:**

* Onboarding new users in a web application
* User can navigate away and return to your app
* You want HIFI to manage ToS updates automatically

### Embedded Flow

Display ToS acceptance inline within your application. Best for embedded experiences where redirection breaks the user experience.

**Advantages:**

* User stays within your application
* Complete control over UI/UX
* Works in mobile apps and embedded contexts

**Use when:**

* Building mobile applications
* Creating embedded financial widgets
* User cannot be redirected out of your application

## Redirect Flow Implementation

<Steps>
  <Step title="Generate ToS link">
    Create a ToS link using the [Generate ToS Link](https://docs.hifi.com/api-reference/tos-link/generate-tos-link) endpoint.

    **Request:**

    ```bash theme={null}
    curl -X POST "https://sandbox.hifi.com/v2/tos-link" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "idempotencyKey": "a4f8b3c2-1d5e-4a7b-9c8d-3e2f1a0b9c8d",
        "redirectUrl": "https://yourapp.com/onboarding/complete"
      }'
    ```

    **Request Fields:**

    * **idempotencyKey** (required): Unique UUID that will become the signedAgreementId. Generate a new UUID for each user.
    * **redirectUrl** (optional): URL to redirect user after accepting ToS. Include query parameters if needed.
    * **templateId** (optional): Custom ToS template ID from HIFI Dashboard. Omit to use HIFI's default template.

    **Response:**

    ```json theme={null}
    {
      "url": "TERMS_OF_SERVICE_URL",
      "signedAgreementId": "a4f8b3c2-1d5e-4a7b-9c8d-3e2f1a0b9c8d"
    }
    ```
  </Step>

  <Step title="Redirect user">
    Redirect the user to the returned `url`. They'll see HIFI's ToS page where they can review and accept the terms.

    ```javascript theme={null}
    // Redirect user to ToS page
    window.location.href = response.url;
    ```
  </Step>

  <Step title="Handle redirect back">
    After the user accepts, they're redirected to your `redirectUrl`. The `signedAgreementId` matches your original `idempotencyKey`.

    ```javascript theme={null}
    // On your redirect page
    const signedAgreementId = 'a4f8b3c2-1d5e-4a7b-9c8d-3e2f1a0b9c8d'; // Your original UUID

    // Proceed to create user
    createUser(signedAgreementId);
    ```
  </Step>

  <Step title="Create user">
    Use the `signedAgreementId` when creating the user account:

    ```bash theme={null}
    curl -X POST "https://sandbox.hifi.com/v2/users" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "signedAgreementId": "a4f8b3c2-1d5e-4a7b-9c8d-3e2f1a0b9c8d",
        "email": "user@example.com",
        "firstName": "Jane",
        "lastName": "Doe"
      }'
    ```
  </Step>
</Steps>

## Embedded Flow Implementation

For applications where redirection isn't possible, display ToS acceptance inline.

<Steps>
  <Step title="Display terms inline">
    Show users HIFI's terms and privacy policy links within your application:

    ```jsx theme={null}
    <div className="tos-acceptance">
      <input
        type="checkbox"
        id="accept-tos"
        onChange={handleTosAcceptance}
      />
      <label htmlFor="accept-tos">
        I agree to HIFI's{' '}
        <a
          href="https://policy.hifi.com/terms-conditions"
          target="_blank"
          rel="noopener noreferrer"
        >
          Terms & Conditions
        </a>
        {' '}and{' '}
        <a
          href="https://policy.hifi.com/privacy-policy"
          target="_blank"
          rel="noopener noreferrer"
        >
          Privacy Policy
        </a>
      </label>
    </div>
    ```
  </Step>

  <Step title="Generate ToS link">
    When the user checks the box, generate a ToS link to get the session token:

    ```javascript theme={null}
    import { v4 as uuidv4 } from 'uuid';

    async function handleTosAcceptance(accepted) {
      if (accepted) {
        const idempotencyKey = uuidv4();

        // Generate ToS link to get session token
        const response = await fetch('https://sandbox.hifi.com/v2/tos-link', {
          method: 'POST',
          headers: {
            'Authorization': 'Bearer YOUR_API_KEY',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            idempotencyKey: idempotencyKey
          })
        });

        const { url, signedAgreementId } = await response.json();

        // Extract session token from URL
        const urlParams = new URLSearchParams(new URL(url).search);
        const sessionToken = urlParams.get('sessionToken');

        // Store for next step
        setSessionToken(sessionToken);
        setSignedAgreementId(signedAgreementId);
      }
    }
    ```
  </Step>

  <Step title="Accept ToS programmatically">
    Call the accept endpoint to record the user's consent:

    ```javascript theme={null}
    async function acceptTos(sessionToken) {
      const response = await fetch(`https://sandbox.hifi.com/v2/tos/${sessionToken}`, {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          sessionToken: sessionToken
        })
      });

      if (response.ok) {
        console.log('ToS accepted successfully');
        return true;
      } else {
        console.error('Failed to accept ToS');
        return false;
      }
    }
    ```
  </Step>

  <Step title="Create user">
    After successful ToS acceptance, create the user with the `signedAgreementId`:

    ```javascript theme={null}
    async function createUserWithTos(signedAgreementId) {
      const response = await fetch('https://sandbox.hifi.com/v2/users', {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          signedAgreementId: signedAgreementId,
          email: 'user@example.com',
          firstName: 'Jane',
          lastName: 'Doe'
        })
      });

      return response.json();
    }
    ```
  </Step>
</Steps>

## Custom Templates

White-label the ToS page with your branding:

1. **Contact Support:** Request custom template creation
2. **Provide Branding:** Share your logo, colors, and any custom terms
3. **Receive Template ID:** HIFI creates a template and provides the ID
4. **Use Template ID:** Include `templateId` when generating links

```bash theme={null}
curl -X POST "https://sandbox.hifi.com/v2/tos-link" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotencyKey": "a4f8b3c2-1d5e-4a7b-9c8d-3e2f1a0b9c8d",
    "redirectUrl": "https://yourapp.com/onboarding/complete",
    "templateId": "tmpl_abc123"
  }'
```

## Key Concepts

<AccordionGroup>
  <Accordion title="Signed Agreement ID">
    The `signedAgreementId` serves two purposes:

    1. **Idempotency key** when generating the ToS link
    2. **Proof of consent** when creating the user account

    Always use the same UUID for both operations. This links the user's ToS acceptance to their account creation.
  </Accordion>

  {" "}

  <Accordion title="Why ToS Is Required">
    HIFI must collect explicit user consent in order to process personal and
    financial data, comply with privacy regulations such as GDPR and CCPA, and to
    establish terms of service for financial operations. Users cannot be created
    without accepting these terms.
  </Accordion>

  {" "}

  <Accordion title="ToS Link Expiration">
    ToS links do not expire. However, the acceptance is only valid when the user
    completes the flow. If a user doesn't accept within your onboarding session,
    generate a new link with a new UUID.
  </Accordion>

  <Accordion title="Testing ToS Flow">
    In sandbox environment:

    * ToS links work identically to production
    * Use test signedAgreementIds for testing
    * Verify the entire flow before going live

    Always test both redirect and embedded flows if you support multiple platforms.
  </Accordion>
</AccordionGroup>

## Getting Help

* 📧 **Email:** [support@hifi.com](mailto:support@hifi.com)
* 💬 **Slack:** Message us in our shared Slack channel

## Related Resources

* [Users](/docs/users) - Create user accounts after ToS acceptance
* [HIFI Terms & Conditions](https://policy.hifi.com/terms-conditions) - View the terms users accept
* [HIFI Privacy Policy](https://policy.hifi.com/privacy-policy) - View the privacy policy users accept
* [API Reference](https://docs.hifi.com/api-reference/tos-link/generate-tos-link) - Complete endpoint documentation
