> ## 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 AgLeader AgFiniti API

> Connect AgLeader AgFiniti to Leaf: get developer credentials, complete the OAuth flow, and attach credentials to a Leaf user.

This tutorial walks through connecting AgLeader's AgFiniti platform to Leaf to sync machine files. You'll get developer credentials, run the OAuth flow to obtain 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.
* An AgLeader developer account. Complete the [developer registration form](https://www.agleader.com/developers/).

<Note>
  AgLeader requires proof of liability insurance and a one-time fee before providing developer credentials.
</Note>

## Step 1: Get your AgLeader credentials

Log in to [AgFiniti](https://www.agfiniti.com), navigate to the **Consumer Keys** tab, and note your:

* **Public Key**
* **Private Key**

Configure the **Redirection URL(s)** on the application page to include the callback URL that will receive the authorization code.

## Step 2: Get the authorization code

Redirect the grower to the AgFiniti authorization URL. Replace `{your_public_key}` and `{redirect_uri}` with your values:

```
https://www.agfiniti.com/Account/Authorize?response_type=code&client_id={your_public_key}&redirect_uri={redirect_uri}&scope=read%20readwrite
```

This URL includes the `read` and `readwrite` scopes required for Leaf integration. If you plan to upload prescriptions, add the `fileupload` scope.

After the grower authenticates, AgFiniti redirects to your `redirect_uri` with a `code` parameter.

## Step 3: Exchange the code for tokens

POST the code to AgFiniti's token endpoint. The `Authorization` header requires Base64-encoded `publicKey:privateKey`:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://www.agfiniti.com/api/token" \
    -H "Authorization: Basic $(echo -n 'yourPublicKey:yourPrivateKey' | base64)" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=authorization_code&code=THE_CODE_FROM_REDIRECT&redirect_uri=https://your-app.com/callback"
  ```

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

  auth_string = base64.b64encode(
      f"{public_key}:{private_key}".encode()
  ).decode()

  token_response = requests.post(
      "https://www.agfiniti.com/api/token",
      headers={"Authorization": f"Basic {auth_string}"},
      data={
          "grant_type": "authorization_code",
          "code": "THE_CODE_FROM_REDIRECT",
          "redirect_uri": "https://your-app.com/callback"
      }
  )
  refresh_token = token_response.json()["refresh_token"]
  ```

  ```javascript JavaScript theme={null}
  const authString = btoa(`${publicKey}:${privateKey}`);

  const tokenRes = await fetch("https://www.agfiniti.com/api/token", {
    method: "POST",
    headers: {
      Authorization: `Basic ${authString}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: new URLSearchParams({
      grant_type: "authorization_code",
      code: "THE_CODE_FROM_REDIRECT",
      redirect_uri: "https://your-app.com/callback",
    }),
  });
  const { refresh_token } = await tokenRes.json();
  ```
</CodeGroup>

Save the `refresh_token`.

## 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}/ag-leader-credentials" \
    -H "Authorization: Bearer YOUR_LEAF_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "publicKey": "your-agleader-public-key",
      "privateKey": "your-agleader-private-key",
      "refreshToken": "the-refresh-token-from-step-3"
    }'
  ```

  ```python Python theme={null}
  response = requests.post(
      f"https://api.withleaf.io/services/usermanagement/api/users/{leaf_user_id}/ag-leader-credentials",
      headers={"Authorization": f"Bearer {leaf_token}"},
      json={
          "publicKey": public_key,
          "privateKey": private_key,
          "refreshToken": refresh_token
      }
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    `https://api.withleaf.io/services/usermanagement/api/users/${leafUserId}/ag-leader-credentials`,
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${leafToken}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        publicKey: publicKey,
        privateKey: privateKey,
        refreshToken: refresh_token,
      }),
    }
  );
  console.log(await res.json());
  ```
</CodeGroup>

Leaf manages token refresh and begins syncing machine files. AgLeader currently supports machine file data only (no direct field boundary sync).

## Step 5: Confirm the credentials are attached

Check the stored credentials for the Leaf user:

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

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

## What you built

You connected AgLeader AgFiniti to a Leaf user. Leaf now fetches and standardizes machine files from AgFiniti. Query the data through the [machine files API](/api-reference/files) and [field operations quickstart](/guides/tutorials/field-operations-quickstart).

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