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

# Quickstart

> Make your first authenticated Grain API call.

Get a list of donors from your church organization in a few steps.

## Prerequisites

* API access approved for your organization ([request access](https://grainledger.com/demo))
* An OAuth client registered with Grain (client ID and redirect URI)
* Your church **organization ID** (see [Organizations](/organizations))

## 1. Authorize the user

Redirect the user to the authorization endpoint with PKCE parameters:

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
https://app.grainledger.com/oauth/authorize
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=YOUR_REDIRECT_URI
  &scope=openid%20email%20profile
  &code_challenge=YOUR_CODE_CHALLENGE
  &code_challenge_method=S256
  &state=RANDOM_STATE
```

The user signs in and approves access at `https://app.grainledger.com/oauth/consent`.

## 2. Exchange the authorization code

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST "https://api.grainledger.com/oauth/token" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=authorization_code" \
    -d "code=AUTHORIZATION_CODE" \
    -d "redirect_uri=YOUR_REDIRECT_URI" \
    -d "client_id=YOUR_CLIENT_ID" \
    -d "code_verifier=YOUR_CODE_VERIFIER"
  ```

  ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const response = await fetch("https://api.grainledger.com/oauth/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "authorization_code",
      code: authorizationCode,
      redirect_uri: redirectUri,
      client_id: clientId,
      code_verifier: codeVerifier,
    }),
  });

  const { access_token, refresh_token } = await response.json();
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests

  response = requests.post(
      "https://api.grainledger.com/oauth/token",
      data={
          "grant_type": "authorization_code",
          "code": authorization_code,
          "redirect_uri": redirect_uri,
          "client_id": client_id,
          "code_verifier": code_verifier,
      },
  )
  tokens = response.json()
  access_token = tokens["access_token"]
  ```
</CodeGroup>

Save the `access_token` and `refresh_token` from the response.

## 3. List donors

Replace the placeholders with your access token and organization ID:

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X GET "https://api.grainledger.com/api/v1/donors?page=1&limit=20" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "X-Organization-Id: YOUR_ORGANIZATION_ID" \
    -H "Content-Type: application/json"
  ```

  ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const response = await fetch(
    "https://api.grainledger.com/api/v1/donors?page=1&limit=20",
    {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "X-Organization-Id": organizationId,
        "Content-Type": "application/json",
      },
    }
  );

  const data = await response.json();
  console.log(data.donors);
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  response = requests.get(
      "https://api.grainledger.com/api/v1/donors",
      params={"page": 1, "limit": 20},
      headers={
          "Authorization": f"Bearer {access_token}",
          "X-Organization-Id": organization_id,
      },
  )
  data = response.json()
  print(data["donors"])
  ```
</CodeGroup>

<Check>
  A `200` response with a `donors` array and `pagination` object means your integration is working.
</Check>

## Example response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "donors": [
    {
      "id": "cm123abc456def",
      "firstName": "Sarah",
      "lastName": "Johnson",
      "email": "sarah@gracechurch.org"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 142,
    "totalPages": 8
  }
}
```

## Try it in the browser

Open [List donors](/api-reference/donors/list-donors) in the API reference and use the **Try it** playground after authorizing with your OAuth token.

## Next steps

* [Authentication](/authentication) for token refresh and scope details
* [Pagination](/pagination) for iterating through large result sets
* [Errors](/errors) for handling failed requests
