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

# Connect to CNHi API (AFS Connect)

> Connect CNHi (Case IH, New Holland) data to Leaf. Create a developer application, complete the OAuth flow, and attach credentials to a Leaf user.

<Tip>
  This tutorial covers the **legacy CNHi (AFS Connect)** integration. For CNH Industrial's newer FieldOps API, see [Connect CNHI FieldOps](/guides/tutorials/connect-cnhi-fieldops).
</Tip>

This tutorial walks through connecting CNHi to Leaf so you can sync field boundaries, machine files, and field operations from Case IH and New Holland equipment. You'll create a developer application, run the OAuth flow to get user tokens, and attach provider credentials to a Leaf user.

<Tip>
  [Magic Link](/components/magic-link) and [Leaf Link](/components/leaf-link) handle the OAuth UI for you. This tutorial covers the manual flow for developers building it into their own application.
</Tip>

## Before you start

* A Leaf account with a valid API token.
* A Leaf user created.
* A CNHi developer account. Register at [develop.cnh.com](https://develop.cnh.com/).

## Step 1: Create a CNHi application

Sign in to the [CNHi developer portal](https://develop.cnh.com/), go to **Account Dashboard**, and click **Add Application**.

After creating the application, go to **App Registrations**, click your application name, then **API Information** to find your:

* **Client ID**
* **Client Secret**
* **Subscription Key**

## Step 2: Get the authorization URL

Leaf provides a helper that constructs the CNHi authorization URL:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://cnhi-oauth2-helper.withleaf.io/get_url" \
    -H "Content-Type: application/json" \
    -d '{
      "client_id": "your-cnhi-client-id",
      "client_secret": "your-cnhi-client-secret",
      "subscription_key": "your-cnhi-subscription-key",
      "client_redirect_url": "https://your-app.com/callback",
      "production": false
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://cnhi-oauth2-helper.withleaf.io/get_url",
      json={
          "client_id": "your-cnhi-client-id",
          "client_secret": "your-cnhi-client-secret",
          "subscription_key": "your-cnhi-subscription-key",
          "client_redirect_url": "https://your-app.com/callback",
          "production": False
      }
  )
  auth_url = response.json()["url"]
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://cnhi-oauth2-helper.withleaf.io/get_url", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      client_id: "your-cnhi-client-id",
      client_secret: "your-cnhi-client-secret",
      subscription_key: "your-cnhi-subscription-key",
      client_redirect_url: "https://your-app.com/callback",
      production: false,
    }),
  });
  const { url } = await res.json();
  ```
</CodeGroup>

Set `production` to `false` for the CNHi staging environment (the default for new apps). Set it to `true` once your app is promoted to production.

<Warning>
  While in the CNHi staging environment, only staging test accounts work. Production customer accounts won't authenticate. The reverse is true in production.
</Warning>

Redirect the grower to the returned URL. After authorization, CNHi redirects to your `client_redirect_url` with a `code` in the URL.

## Step 3: Exchange the code for a refresh token

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://cnhi-oauth2-helper.withleaf.io/get_token" \
    -H "Content-Type: application/json" \
    -d '{
      "client_id": "your-cnhi-client-id",
      "client_secret": "your-cnhi-client-secret",
      "subscription_key": "your-cnhi-subscription-key",
      "response_url": "https://your-app.com/callback?code=abc123",
      "client_redirect_url": "https://your-app.com/callback"
    }'
  ```

  ```python Python theme={null}
  tokens = requests.post(
      "https://cnhi-oauth2-helper.withleaf.io/get_token",
      json={
          "client_id": "your-cnhi-client-id",
          "client_secret": "your-cnhi-client-secret",
          "subscription_key": "your-cnhi-subscription-key",
          "response_url": "https://your-app.com/callback?code=abc123",
          "client_redirect_url": "https://your-app.com/callback"
      }
  ).json()
  refresh_token = tokens["refresh_token"]
  ```

  ```javascript JavaScript theme={null}
  const tokenRes = await fetch(
    "https://cnhi-oauth2-helper.withleaf.io/get_token",
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        client_id: "your-cnhi-client-id",
        client_secret: "your-cnhi-client-secret",
        subscription_key: "your-cnhi-subscription-key",
        response_url: "https://your-app.com/callback?code=abc123",
        client_redirect_url: "https://your-app.com/callback",
      }),
    }
  );
  const { refresh_token } = await tokenRes.json();
  ```
</CodeGroup>

The `response_url` is the full URL the grower was redirected to, including the `code` parameter that CNHi appended.

## Step 4: Attach credentials to the Leaf user

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.withleaf.io/services/usermanagement/api/users/{leafUserId}/cnhi-credentials" \
    -H "Authorization: Bearer YOUR_LEAF_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "clientId": "your-cnhi-client-id",
      "clientSecret": "your-cnhi-client-secret",
      "subscriptionKey": "your-cnhi-subscription-key",
      "refreshToken": "the-refresh-token-from-step-3",
      "clientEnvironment": "STAGE"
    }'
  ```

  ```python Python theme={null}
  response = requests.post(
      f"https://api.withleaf.io/services/usermanagement/api/users/{leaf_user_id}/cnhi-credentials",
      headers={"Authorization": f"Bearer {leaf_token}"},
      json={
          "clientId": "your-cnhi-client-id",
          "clientSecret": "your-cnhi-client-secret",
          "subscriptionKey": "your-cnhi-subscription-key",
          "refreshToken": refresh_token,
          "clientEnvironment": "STAGE"
      }
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    `https://api.withleaf.io/services/usermanagement/api/users/${leafUserId}/cnhi-credentials`,
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${leafToken}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        clientId: "your-cnhi-client-id",
        clientSecret: "your-cnhi-client-secret",
        subscriptionKey: "your-cnhi-subscription-key",
        refreshToken: refresh_token,
        clientEnvironment: "STAGE",
      }),
    }
  );
  console.log(await res.json());
  ```
</CodeGroup>

Set `clientEnvironment` to `PRODUCTION` once your CNHi application is promoted to production. Leaf handles token refresh automatically.

## Step 5: Confirm the credentials are attached

```bash theme={null}
curl "https://api.withleaf.io/services/usermanagement/api/users/{leafUserId}/cnhi-credentials" \
  -H "Authorization: Bearer YOUR_LEAF_TOKEN"
```

If this worked, Leaf returns the CNHi credential object for the Leaf user.

## What you built

You connected CNHi to a Leaf user. Leaf now syncs field boundaries, machine files, and field operations from Case IH and New Holland equipment. Query the data through the [field operations](/guides/tutorials/field-operations-quickstart) endpoints.

For the credentials schema and management endpoints, see the [CNHi provider guide](/providers/cnhi) and the [provider credentials API reference](/api-reference/providers).
