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

# Open a Fund

> Create a donor-advised fund for an authenticated user.

## Outcome

An authenticated user has a new Endaoment fund. Your app stores the fund `id` for donations and grants.

## When

After [Authenticate](./login-user). Trigger when the user opens their first fund or creates an additional one.

The authenticated user becomes the fund **manager**. See the [glossary](/developers/getting-started/glossary) for DAF terminology.

## Choose your route

Fund creation depends on how the caller authenticated:

| Caller                                                                      | Route                    | When to use                                                                              |
| --------------------------------------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------------------- |
| OAuth access token from a **registered client** (token includes `clientId`) | `POST /v1/funds/partner` | Typical external OAuth integrators — `POST /v1/funds` returns `400` by design (IS-29676) |
| Access token **without** `clientId` (first-party / direct session)          | `POST /v1/funds`         | Internal or first-party flows only                                                       |

Check [`GET /v1/auth/whoami`](/developers/api/authentication/get-authenticated-caller) if unsure: OIDC callers include `clientId` when issued through a registered OAuth client.

Proxy all calls from your backend. See [Integration Patterns](./integration-patterns).

***

## Option A: Registered OAuth client → `POST /v1/funds/partner`

Use this path for standard OAuth quickstart integrators.

**Prerequisite:** The acting user must have saved identity (PII) on Endaoment before this call. The partner route builds the fund advisor from stored identity — if none exists, the API returns `400`: *"User must be provisioned with PII before creating a partner fund."* Complete [Authenticate](./login-user) with profile/address data, or [Provision user](/developers/api/partner-endpoints/provision-user) on the partner track first.

### Auth

Pick one acting-user path (see [Partner auth options](./integration-patterns#partner-auth-options)):

| Path                            | Headers                                       |
| ------------------------------- | --------------------------------------------- |
| **Registered OAuth user token** | `Authorization: Bearer <access_token>` only   |
| API key + body user id          | `x-api-key` + `partnerUserIdentifier` in body |
| API key + impersonation header  | `x-api-key` + `x-endaoment-user-id`           |
| Partner OIDC bearer             | `Authorization: Bearer <partner_oidc_token>`  |

The **registered OAuth user token** path is the standard quickstart flow after [Authenticate](./login-user). Server-to-server partner flows use `x-api-key` (see [Partner Journey](./partner-journey)).

### Required inputs

Flat body (`PartnerCreateFundInputDto`) — no `fundInput` wrapper:

| Field                      | Description                                                                           |
| -------------------------- | ------------------------------------------------------------------------------------- |
| `name`                     | Fund display name                                                                     |
| `partnerAccountIdentifier` | Partner-scoped idempotency key (16–64 printable ASCII characters)                     |
| `description`              | Optional fund description                                                             |
| `partnerUserIdentifier`    | Required when using API key + body user resolution (16–64 printable ASCII characters) |

API reference: [Create fund](/developers/api/partner-endpoints/create-fund)

### Example request (registered OAuth user token)

```bash theme={null}
curl -X POST "https://api.dev.endaoment.org/v1/funds/partner" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Giving Fund",
    "description": "Personal charitable giving account",
    "partnerAccountIdentifier": "550e8400-e29b-41d4-a716-446655440001"
  }'
```

### Example request (API key + impersonation header)

```bash theme={null}
curl -X POST "https://api.dev.endaoment.org/v1/funds/partner" \
  -H "x-api-key: $PARTNER_API_KEY" \
  -H "x-endaoment-user-id: $ENDAOMENT_USER_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Giving Fund",
    "description": "Personal charitable giving account",
    "partnerAccountIdentifier": "550e8400-e29b-41d4-a716-446655440001",
    "partnerUserIdentifier": "550e8400-e29b-41d4-a716-446655440002"
  }'
```

***

## Option B: First-party token → `POST /v1/funds`

Use only when the access token has **no** `clientId` (not a registered OAuth client token).

### Auth

| Header          | Value                   |
| --------------- | ----------------------- |
| `Authorization` | `Bearer <access_token>` |

API reference: [Create fund](/developers/api/funds/create-fund)

### Required inputs

Minimum `fundInput` fields:

| Field                   | Description                |
| ----------------------- | -------------------------- |
| `name`                  | Fund display name          |
| `description`           | Fund description           |
| `advisor.firstName`     | Primary advisor first name |
| `advisor.lastName`      | Primary advisor last name  |
| `advisor.email`         | Primary advisor email      |
| `advisor.address.line1` | Street address             |
| `advisor.address.city`  | City                       |
| `advisor.address.state` | State                      |
| `advisor.address.zip`   | ZIP code                   |

### Example request

```bash theme={null}
curl -X POST "https://api.dev.endaoment.org/v1/funds" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fundInput": {
      "name": "My Giving Fund",
      "description": "Personal charitable giving account",
      "advisor": {
        "firstName": "Alex",
        "lastName": "Donor",
        "email": "alex@example.com",
        "address": {
          "line1": "123 Main St",
          "city": "San Francisco",
          "state": "CA",
          "zip": "94105"
        }
      }
    }
  }'
```

***

## Response you need

| Field         | Use                              |
| ------------- | -------------------------------- |
| `id`          | Fund ID for donations and grants |
| `usdcBalance` | Current balance (microdollars)   |

## Common mistakes

* Calling `POST /v1/funds` with a registered OAuth client token (returns `400` — use `/v1/funds/partner`)
* Creating a partner fund before the acting user has saved PII/identity on Endaoment
* Using `fundInput` / `advisor.*` schema on the partner route (partner route expects a flat body)
* Using partner identifiers shorter than 16 characters (validation rejects them)
* Omitting `partnerAccountIdentifier` on the partner route
* Calling the API from the browser with a Bearer token

## Full sample

Reference implementation: [GitHub quickstart — create DAF](https://github.com/endaoment/endaoment-integration-docs/tree/main/quickstart/backend).

Optional next step: [Manage Collaborators](/advisors/collaboration/manage-collaborators).

**Next:** [Fund a DAF](./donate-to-daf)
