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

# Leaf Connect

> Share field boundaries and field operations between separate organizations using Leaf Connect's permission-based data sharing system.

Leaf Connect lets one API owner grant read access to their field boundaries and field operations to another API owner. Access is controlled per Leaf user, so you share exactly the data you choose.

## How it works

Sharing data between two API owners involves three steps:

**1. Create a sharing relation.** The data owner (sender) creates a relation naming the receiver API owner. This relation starts in `PENDING` status.

**2. Receiver accepts.** The receiver changes the relation status to `ALLOWED`. Either side can later change it to `BLOCKED`. If the sender blocks the relation, the receiver cannot reactivate it.

**3. Grant permissions per Leaf user.** The sender grants `READ` access on specific resources (`FIELDS`, `OPERATIONS`) for individual Leaf users. The receiver can then query the standard field and operations endpoints to see the shared data.

<Note>
  Permissions are `READ` only. The receiver cannot modify shared data. Company-level sharing is not supported, but you can grant or revoke permissions when adding or removing a Leaf user from a company.
</Note>

## Endpoints

Base URL: `https://api.withleaf.io/services/usermanagement/api`

### Sharing relations

| Action                       | Method | Path                                                                             |
| ---------------------------- | ------ | -------------------------------------------------------------------------------- |
| Get relations by role        | GET    | `/api-owners/sharing-relation/{RelationRole}`                                    |
| Get relation status          | GET    | `/api-owners/sharing-relation/{RelationRole}/{targetApiOwner}/status`            |
| Create relation              | POST   | `/api-owners/sharing-relation/receiver`                                          |
| Update relation status       | PATCH  | `/api-owners/sharing-relation/{RelationRole}/{targetApiOwner}`                   |
| Invalidate receiver's tokens | POST   | `/api-owners/sharing-relation/{RelationRole}/{targetApiOwner}/invalidate-tokens` |

`RelationRole` is either `SENDER` or `RECEIVER`, depending on which side is making the request.

Relation statuses: `PENDING`, `ALLOWED`, `BLOCKED`.

### Leaf user permissions

| Action             | Method | Path                                                                                                 |
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------- |
| Get permissions    | GET    | `/api-owners/sharing-relation/{RelationRole}/{TargetApiOwner}/users-permissions/{leafUserId}`        |
| Create permissions | POST   | `/api-owners/sharing-relation/receiver/{ReceiverApiOwner}/users-permissions/{leafUserId}`            |
| Update permissions | PATCH  | `/api-owners/sharing-relation/receiver/{ReceiverApiOwner}/users-permissions/{leafUserId}/{RESOURCE}` |
| Delete permissions | DELETE | `/api-owners/sharing-relation/{RelationRole}/{ReceiverApiOwner}/users-permissions/{leafUserId}`      |

### Available permission resources

| Resource     | Actions | Types                             |
| ------------ | ------- | --------------------------------- |
| `FIELDS`     | `READ`  | (none)                            |
| `OPERATIONS` | `READ`  | `APPLIED`, `HARVESTED`, `PLANTED` |

## Example: granting field and operation access

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    -d '{"permissions": {"FIELDS": {"actions": ["READ"]}, "OPERATIONS": {"actions": ["READ"], "types": ["PLANTED", "HARVESTED"]}}}' \
    'https://api.withleaf.io/services/usermanagement/api/api-owners/sharing-relation/receiver/{ReceiverApiOwner}/users-permissions/{leafUserId}'
  ```

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

  TOKEN = "YOUR_TOKEN"
  receiver = "receiver-api-owner"
  leaf_user = "leaf-user-id"
  endpoint = f"https://api.withleaf.io/services/usermanagement/api/api-owners/sharing-relation/receiver/{receiver}/users-permissions/{leaf_user}"
  headers = {"Authorization": f"Bearer {TOKEN}"}
  data = {
      "permissions": {
          "FIELDS": {"actions": ["READ"]},
          "OPERATIONS": {"actions": ["READ"], "types": ["PLANTED", "HARVESTED"]}
      }
  }

  response = requests.post(endpoint, headers=headers, json=data)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require("axios");

  const TOKEN = "YOUR_TOKEN";
  const receiver = "receiver-api-owner";
  const leafUser = "leaf-user-id";
  const endpoint = `https://api.withleaf.io/services/usermanagement/api/api-owners/sharing-relation/receiver/${receiver}/users-permissions/${leafUser}`;
  const headers = { Authorization: `Bearer ${TOKEN}` };
  const data = {
    permissions: {
      FIELDS: { actions: ["READ"] },
      OPERATIONS: { actions: ["READ"], types: ["PLANTED", "HARVESTED"] }
    }
  };

  axios.post(endpoint, data, { headers }).then(res => console.log(res.data));
  ```
</CodeGroup>

Response:

```json theme={null}
{
  "leafUserId": "leaf-user-id",
  "permissions": {
    "FIELDS": { "actions": ["READ"] },
    "OPERATIONS": { "actions": ["READ"], "types": ["PLANTED", "HARVESTED"] }
  }
}
```

## What to do next

* [Leaf Link](/components/leaf-link) for embedding provider connection and file upload widgets.
* [Magic Link](/components/magic-link) for generating shareable authentication URLs.
* [Provider Organizations](/providers/organizations) for controlling sync scope before sharing data.
