> ## 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.

# Migrate from Trimble to FarmEngage

> Move your existing Trimble Agriculture integration to FarmEngage. Covers what changed, new AGCO credentials, organization grants, and running both providers in parallel.

This guide covers how to migrate an existing Trimble Agriculture integration to FarmEngage. You can migrate growers one at a time. Both providers run in parallel, and growers you have not switched yet keep working on Trimble until PTx disables that API.

> [!WARNING]
>
> PTx/AGCO is retiring Trimble Agriculture connections. Confirm the cutoff date with PTx. Leaf does not control that timeline. After PTx disables the legacy API, existing `trimble-credentials` will stop receiving new data.

## What changed

FarmEngage is PTx's API and identity system. The data you receive through Leaf — field operations, machine files, boundaries — is the same class of data. What changes is how the connection is established. FarmEngage is a new sync, not a replay of already-processed Trimble files. File ingest is subject to your operations processing lookback. Already-processed Trimble files stay on the Leaf user as `"provider": "Trimble"`. Do not use one expected historical file as the cutover gate unless it is inside that lookback and present in FarmEngage.

| Aspect | Trimble (legacy) | FarmEngage |
| - | - | - |
| Leaf credential path | `trimble-credentials` | `farm-engage-credentials` |
| Leaf provider name | `Trimble` | `FarmEngage` |
| Identity provider | Trimble Identity (`id.trimble.com`) | AGCO ID (`onelogin.agcocorp.com`) |
| Data host | `cloud.api.trimble.com` | `api.farmengage.com` |
| App keys path | `/app-keys/Trimble/{appName}` | `/app-keys/FarmEngage/{appName}` |
| App key body | `applicationName`, `clientId`, `clientSecret` | `clientId`, `clientSecret` |
| OAuth helper | `/get_url`, `/get_token` | `/farmengage/get_url`, `/farmengage/get_token` |
| `get_url` body | `application_name`, `client_id`, and `client_redirect_url` | `client_id` and `client_redirect_url` only |
| Magic Link / Leaf Link provider name | `Trimble` | `FarmEngage` |
| Organization list | `/organizations/Trimble` | `/organizations/FarmEngage` |
| Organization IDs | Trimble UUIDs | Different UUIDs from PTx's account system — they do not match Trimble IDs |
| Organization management URI query | `clientId` | `clientid` plus `IsAgcoId=true` |
| Refresh tokens | Long-lived | Leaf persists the new access and refresh tokens from each successful refresh |
| Change detection | Polling | Polling (no FarmEngage webhooks) |

FarmEngage tokens are not accepted by the legacy Trimble data host, and Trimble tokens are not accepted by FarmEngage. There is no server-side token conversion. Every grower must complete a new OAuth consent.

## What you need before migrating

* FarmEngage API access from PTx, with a new AGCO `clientId` and `clientSecret`. Request access at [PTx's API request form](https://www.ptxag.com/us/en/partners/developers/resources/request-apis.html). Legacy Trimble developer credentials do not work.
* Your FarmEngage application's redirect URL registered with PTx. For Magic Link or Leaf Link, that URL is `https://widget.withleaf.io`.
* Each grower must re-authorize through the AGCO ID OAuth flow. Existing Trimble refresh tokens do not carry over.
* Each grower must grant your application access to their FarmEngage organizations. Authentication alone is not enough.

## Migration approach: run both in parallel

Leaf treats Trimble and FarmEngage as separate providers. A single Leaf user can hold both `trimble-credentials` and `farm-engage-credentials` at the same time. Migrate growers one at a time without disrupting anyone still on Trimble.

Follow the recommended approach:

1. Register your FarmEngage app keys with Leaf:

```bash theme={null}
curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"clientId": "your-agco-client-id", "clientSecret": "your-agco-client-secret"}' \
  "https://api.withleaf.io/services/usermanagement/api/app-keys/FarmEngage/your-app-name"
```

There is no `/PRODUCTION` path segment on FarmEngage app keys.

2. For each grower you want to migrate:
   * Run the FarmEngage OAuth flow (through the [Leaf helper](https://docs.withleaf.io/guides/tutorials/connect-farmengage.md), [Magic Link](https://docs.withleaf.io/components/magic-link.md), or [Leaf Link](https://docs.withleaf.io/components/leaf-link.md)). If you use a widget, create the link for the existing Leaf user (`POST /magic-link/users/{leafUserId}/provider` or the widget bound to that `leafUserId`). Do not use the create-new-user Magic Link path for cutover.
   * Attach `farm-engage-credentials` to the same Leaf user that already has `trimble-credentials`.
   * Call `GET /users/{leafUserId}/organizations/FarmEngage`. If `connectedOrganizations` is empty, send the grower the `managementUri`. An empty list can mean a skipped organization grant or a FarmEngage account with no organizations.
   * Verify fields and files appear with `"provider": "FarmEngage"`. Field and file verification requires `fieldsAutoSync` and `operationsAutoSync` enabled for that API owner or Leaf user.
   * After you confirm, delete the old `trimble-credentials` from the Leaf user. That stops new Trimble syncs. Already-synced Trimble fields, files, and operations remain with `"provider": "Trimble"` and stay queryable.

3. Growers you have not migrated yet continue working on the legacy Trimble provider until you switch them — or until PTx disables that API.

> [!WARNING]
>
> While both credentials are attached, Leaf syncs from both providers and might create a second field, file, and operations graph. Deleting `trimble-credentials` stops new Trimble syncs; it does not delete already-synced Trimble-provider records. Verify the FarmEngage connection, then promptly delete the legacy Trimble credential and filter historical Trimble objects in your app.

### Suggested cutover order

1. A test or QA Leaf user you control.
2. One production grower who already uses FarmEngage and can complete organization authorization with you on the call.
3. Remaining production growers, before PTx's cutoff.

Do not delete a working Trimble credential until FarmEngage has returned organizations and at least one expected field or file. If `fieldsAutoSync` or `operationsAutoSync` is off, those endpoints will not populate after connect.

### FarmEngage data in the API

Data from FarmEngage appears in the same Leaf endpoints (fields, files, operations) as legacy Trimble data. The `provider` field distinguishes the source:

* Legacy Trimble: `"provider": "Trimble"`
* FarmEngage: `"provider": "FarmEngage"`

You can filter queries by provider (for example `?provider=FarmEngage`) to see only FarmEngage data. During the parallel-run period, the same physical field might appear twice with different `provider` values and different `providerFieldId`s. FarmEngage organization, grower, farm, and field IDs do not match the IDs on the same grower's Trimble data. Do not join across providers.

Check resource counts after connecting:

```bash theme={null}
curl "https://api.withleaf.io/services/integrations/api/resources?leafUserId={leafUserId}&provider=FarmEngage" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

## Abbreviated setup steps

For the full walkthrough with code examples in cURL, Python, and JavaScript, see [Connect FarmEngage](https://docs.withleaf.io/guides/tutorials/connect-farmengage.md). Follow these key steps:

1. **Get the authorization URL** — `POST https://trimble-oauth2-helper.withleaf.io/farmengage/get_url` with `client_id` and `client_redirect_url`.
2. **Redirect the grower** — they sign in with AGCO ID and consent.
3. **Exchange the code for tokens** — `POST https://trimble-oauth2-helper.withleaf.io/farmengage/get_token` with `client_id`, `client_secret`, `redirect_url`, and `code`. The token field name is `redirect_url`, not `client_redirect_url`.
4. **Attach credentials to the Leaf user** — `POST /users/{leafUserId}/farm-engage-credentials` with `clientId`, `clientSecret`, and `refreshToken`.
5. **Confirm organizations** — `GET /users/{leafUserId}/organizations/FarmEngage`. If `connectedOrganizations` is empty, Leaf detects no authorized FarmEngage organizations. That can be a skipped organization grant or a FarmEngage account with no organizations. Send the grower the `managementUri` for the grant path.
6. **Confirm data** — `GET /users/{leafUserId}/farm-engage-credentials`, then fields and files with `?provider=FarmEngage`.

## Update Magic Link and Leaf Link

If you use Magic Link or Leaf Link widgets to onboard growers:

1. Register your FarmEngage app keys with Leaf (see the preceding curl example).

2. Add `https://widget.withleaf.io` as a callback/redirect URL on your FarmEngage application with PTx.

3. Update your `allowedProviders` to include `"FarmEngage"`. During the transition, you can include both `"Trimble"` and `"FarmEngage"` so growers can connect through either provider.

```json theme={null}
{
  "allowedProviders": ["Trimble", "FarmEngage"]
}
```

After PTx disables Trimble connections, remove `"Trimble"` so growers are not offered a dead path.

For cutover, create Magic Link or Leaf Link sessions for the existing Leaf user (`POST /magic-link/users/{leafUserId}/provider` or the widget bound to that `leafUserId`). A provider Magic Link created without that `leafUserId` creates or reuses a Leaf user by external ID. It can attach FarmEngage to a different user than the one holding `trimble-credentials`.

The widget provider key is `FarmEngage`. After OAuth, Leaf Link always offers the FarmEngage organization-grant button, even when organizations already appear connected. Growers often still need to add organizations on the FarmEngage side.

## Common mistakes

* **Posting Trimble tokens to `/farm-engage-credentials`.** Leaf confirms by refreshing against AGCO ID, then calling FarmEngage `GET /config/organizations`. Trimble tokens fail that confirm step. Leaf returns `HTTP 400` and does not persist the credential.
* **Calling `/get_url` instead of `/farmengage/get_url`.** That helper still talks to Trimble Identity.
* **Sending `client_redirect_url` on `get_token`.** The FarmEngage token helper requires `redirect_url`.
* **Mixing helper and Leaf field names.** The FarmEngage helper returns `refresh_token`. The Leaf credentials API expects `refreshToken`.
* **Skipping organization authorization.** A valid credential with zero organizations looks like a successful connect and an empty sync.
* **Joining FarmEngage UUIDs to stored Trimble organization and field IDs.** Remap using name or geometry, or treat FarmEngage as a new provider graph.
* **Leaving both credentials attached.** Expect a second field, file, and operations graph until you delete `trimble-credentials`. Deleting the credential does not remove already-synced Trimble-provider records.

## What to do next

* [FarmEngage provider guide](https://docs.withleaf.io/providers/farmengage.md) — Credentials schema, endpoints, and troubleshooting.
* [Connect FarmEngage tutorial](https://docs.withleaf.io/guides/tutorials/connect-farmengage.md) — Full step-by-step with code examples.
* [Provider credentials API reference](https://docs.withleaf.io/api-reference/providers.md) — Endpoint reference for all providers.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.