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

# Onboard an organization

> Provision the authority and account record required to create MicroVaults.

Onboarding provisions your organization-owned Turnkey authority, registers its MicroVault account on Ethereum Sepolia, and activates that account. Run it once before creating a vault. Repeating the request resumes the same onboarding workflow.

## Prerequisites

* A Ground sandbox API key for an organization with MicroVaults enabled

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
export GROUND_API="https://sandbox.groundtech.co"
export GROUND_API_KEY="..."
export AUTH="Authorization: Bearer $GROUND_API_KEY"
```

## 1. Start onboarding

Send an empty JSON object. Do not supply an authority address or other configuration.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sS -X POST "$GROUND_API/v2/microvaults/onboarding" \
  -H "$AUTH" \
  -H 'Content-Type: application/json' \
  -d '{}'
```

The response reports the current stage. `provisioning`, `registering`, and `activating` mean onboarding is still progressing. `active` means the organization is ready.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "status": "active",
  "authorityAddress": "0x1111111111111111111111111111111111111111",
  "customerId": "136035462521275697257736478300548146932"
}
```

## 2. Wait for the managed authority

Poll the authority endpoint until it returns `status: "ready"` and a non-null address.

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
async function waitForAuthority() {
  for (;;) {
    const response = await fetch(`${process.env.GROUND_API}/v2/microvaults/managed-authority`, {
      headers: { Authorization: `Bearer ${process.env.GROUND_API_KEY}` },
    });
    if (!response.ok) throw new Error(await response.text());
    const authority = await response.json();
    if (authority.status === "ready" && authority.authorityAddress) return authority;
    await new Promise((resolve) => setTimeout(resolve, 1500));
  }
}
```

## 3. Save the MicroVault account ID

List the organization's account records and select the Ethereum Sepolia record with `status: "accepted"`.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sS "$GROUND_API/v2/microvaults/customers" -H "$AUTH"
```

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "customers": [
    {
      "id": "8ef3d494-7b6f-4df4-9d45-09f31196368f",
      "chainId": 11155111,
      "onchainCustomerId": "136035462521275697257736478300548146932",
      "status": "accepted",
      "authorityAddress": "0x1111111111111111111111111111111111111111",
      "authorityEpoch": "0"
    }
  ]
}
```

Save `customers[0].id` as `CUSTOMER_ID`. You will use it when preparing vault authorizations.

## Confirm onboarding

Onboarding is complete when all three conditions are true:

* `POST /onboarding` returns `status: "active"`.
* `GET /managed-authority` returns `status: "ready"` with an authority address.
* `GET /customers` contains an Ethereum Sepolia record with `status: "accepted"`.

If onboarding remains in an intermediate state, call `POST /onboarding` again with `{}` and continue polling. A `503` means provisioning is temporarily unavailable; retry the same request rather than creating a second authority.
