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

# API clients

> The typed clients in @gol/sdk/server and how to scope, authenticate, and read them.

`@gol/sdk/server` exposes two typed clients. `GolApiClient` authenticates with a project API key and covers the project routes. `GolManagementClient` authenticates with a developer session token and covers the console management and session routes. Both inherit the same read-only project methods, so a project listing looks identical from either.

Every method is a thin, typed wrapper over one documented route. There is no hidden behavior and no chain transaction behind a method: where a method changes authority, the authority is an owner signature you obtain separately. See [owner signing](/sdk/owner-signing).

## Create a client

```ts theme={null}
import { GolApiClient } from "@gol/sdk/server";

export const gol = new GolApiClient({
  baseUrl: "https://api.gol.network",
  apiKey: process.env.GOL_API_KEY!,
});

export const projectId = process.env.GOL_PROJECT_ID!;
```

The constructor validates its arguments before any request, so a malformed key or a plain-HTTP base URL fails at startup rather than on the first call. See [server entry point](/sdk/server#base-url-rules) for the exact rules.

## `GolApiClient` methods

Grouped by what they do. Scopes come from [create a project and API key](/get-started/test-project).

### Identity and configuration

| Method                                          | Scope            | Returns                                                                                                                                       |
| ----------------------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `whoami()`                                      | `project:read`   | The project, environment, and scopes this key carries                                                                                         |
| `getGasConfiguration(projectId)`                | `project:read`   | The deployed core and router, relayer modes, attester, asset, reviewed account configurations, EIP-7702 delegate, tree limits, and gas limits |
| `getAccountStatus(projectId, account)`          | `accounts:read`  | The detected family, account kind and delegation, nonces, and whether the core is installed                                                   |
| `prepareEip7702Setup(projectId, account)`       | `mandates:write` | The EIP-7702 authorization and initialization for an EOA to sign                                                                              |
| `submitEip7702Setup(projectId, account, input)` | `mandates:write` | A GOL-sponsored setup, within the daily limit                                                                                                 |
| `getEip7702Setup(projectId, account, setupId)`  | `accounts:read`  | One setup's state and transaction                                                                                                             |

`getAccountStatus` is the first call for any account. A `family` of `null` means the account is not one of the supported configurations, and the flow stops there.

### Owner gas policies

| Method                                                                  | Scope            | Returns                                                                     |
| ----------------------------------------------------------------------- | ---------------- | --------------------------------------------------------------------------- |
| `prepareGasPolicy(projectId, input)`                                    | `mandates:write` | A compiled approval for the owner to sign. Creates no authority             |
| `confirmGasPolicy(projectId, draftId, transactionHash)`                 | `mandates:write` | The policy once finalized, or an `observing` status to retry                |
| `prepareGasPolicySafetyAction(projectId, gasPolicyId, input)`           | `mandates:write` | A prepared owner pause, resume, or revoke of the root or any child mandate  |
| `confirmGasPolicySafetyAction(projectId, gasPolicyId, input)`           | `mandates:write` | The policy once confirmed, or an observation to retry                       |
| `prepareGasPolicyRevocation(projectId, gasPolicyId, deadline?)`         | `mandates:write` | Both owner revocation paths                                                 |
| `confirmGasPolicyRevocation(projectId, gasPolicyId, transactionHash)`   | `mandates:write` | The policy once confirmed, or an observation to retry                       |
| `getGasPolicy(projectId, gasPolicyId)`                                  | `mandates:read`  | Current on-chain policy state                                               |
| `listGasPolicies(projectId, options?)`                                  | `mandates:read`  | A page of policies                                                          |
| `prepareChildMandate(projectId, gasPolicyId, input)`                    | `mandates:write` | A compiled child mandate for the parent agent to sign. Creates no authority |
| `submitChildMandate(projectId, gasPolicyId, draftId, authorization)`    | `mandates:write` | A GOL-sponsored child creation, within the daily limit                      |
| `confirmChildMandate(projectId, gasPolicyId, draftId, transactionHash)` | `mandates:write` | A child you created yourself, once confirmed, or an observation to retry    |
| `listChildMandates(projectId, gasPolicyId)`                             | `mandates:read`  | Every recorded mandate of the policy's tree, with on-chain status           |

`prepareGasPolicy` returns a plain summary in `review`: recipients, caps, gas caps, which outcomes the owner pays gas for, expiry, and the GOL attester and reimbursement recipient. Show it to the owner as part of your own review screen before they sign.

The `confirm` methods answer with a discriminated union, so the retry case is explicit rather than a null check.

```ts theme={null}
import { GolApiClient } from "@gol/sdk/server";

declare const gol: GolApiClient;
declare const projectId: string;
declare const draftId: string;
declare const transactionHash: `0x${string}`;

const result = await gol.confirmGasPolicy(projectId, draftId, transactionHash);

if (result.status === "confirmed") {
  const { gasPolicyId, status } = result.policy;
} else {
  // result is a GasObservation: the approval is not at the selected head yet.
}
```

`getGasPolicy` reports `unavailable` when the on-chain state is unknown or conflicting, rather than guessing. Treat that as unresolved and retry later, not as revoked.

### Actions

| Method                                                                            | Scope            | Returns                                                                              |
| --------------------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------ |
| `prepareGasExecution(projectId, actionId, input)`                                 | `actions:submit` | The exact `GasActionAuthorization` payload and `maxChargeWei` for your agent to sign |
| `submitGasExecution(projectId, actionId, input)`                                  | `actions:submit` | The execution, including the original one on an exact retry                          |
| `getGasExecution(projectId, executionId)`                                         | `project:read`   | One execution with its receipt, settlement, any claim receipt, and ledger            |
| `submitDeveloperRelayerTransaction(projectId, executionId, rawSignedTransaction)` | `actions:submit` | Your developer relayer's signed transaction for an `external_pending` execution      |
| `listGasExecutions(projectId, options?)`                                          | `project:read`   | A page of executions, optionally filtered by state                                   |
| `openGasExecutionDispute(projectId, executionId, reason)`                         | `mandates:write` | A dispute that freezes new submissions under the policy                              |

See [execution and observation](/sdk/execution) for the action lifecycle and the idempotency rule.

### Webhooks

| Method                                                      | Scope             | Returns                                |
| ----------------------------------------------------------- | ----------------- | -------------------------------------- |
| `createWebhookEndpoint(projectId, input)`                   | `webhooks:manage` | The endpoint and its one-time `secret` |
| `listWebhookEndpoints(projectId)`                           | `webhooks:manage` | Every endpoint on the project          |
| `rotateWebhookSecret(projectId, endpointId)`                | `webhooks:manage` | A new one-time `secret`                |
| `setWebhookEndpointEnabled(projectId, endpointId, enabled)` | `webhooks:manage` | The updated endpoint                   |
| `deleteWebhookEndpoint(projectId, endpointId)`              | `webhooks:manage` | A deletion acknowledgement             |
| `sendWebhookTest(projectId, endpointId)`                    | `webhooks:manage` | The test event ID                      |
| `listWebhookDeliveries(projectId, endpointId, limit?)`      | `webhooks:manage` | Recent delivery attempts               |

See [webhooks](/sdk/webhooks).

## `GolManagementClient` methods

Use this client for developer sign-in and for the management routes a console needs. It is not on the agent action path.

| Method                                                                           | Returns                                                                  |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `startEmailChallenge(email)`                                                     | A challenge to deliver by your own channel                               |
| `verifyEmailChallenge(challengeId, code)`                                        | A session token                                                          |
| `createGoogleSession(input)`                                                     | A session for a Google ID token from your own server-side OAuth exchange |
| `renewSession()`                                                                 | A refreshed session                                                      |
| `revokeSession()`                                                                | Nothing; the session is gone                                             |
| `getIdentity()`                                                                  | The signed-in developer and their projects                               |
| `listProjects()` / `createProject(input)`                                        | The developer's projects                                                 |
| `listApiKeys(projectId)` / `createApiKey(projectId, input)`                      | The project's API keys                                                   |
| `rotateApiKey(projectId, apiKeyId, input)` / `revokeApiKey(projectId, apiKeyId)` | Key lifecycle                                                            |
| `listAuditEvents(projectId, limit?)`                                             | Recent audit events, limit clamped to 1 to 100                           |

Methods that need a session throw `GolTransportError` when the client has no `sessionToken`, so a misconfigured client fails before the request.

<Warning>
  Keep the session token in an HTTP-only cookie and out of client JavaScript. A token in browser storage is readable by any script on the page, and it identifies a developer account rather than one project.
</Warning>

## Read values, do not hard-code them

Addresses, limits, and asset identifiers belong in your configuration, read from the API. The values in [current availability](/availability) are a record of a deployment; `getGasConfiguration` is that deployment as it is now.

```ts theme={null}
import { GolApiClient } from "@gol/sdk/server";
import type { Address } from "viem";

declare const gol: GolApiClient;
declare const projectId: string;
declare const account: Address;

const config = await gol.getGasConfiguration(projectId);
const status = await gol.getAccountStatus(projectId, account);

if (status.family === null) {
  throw new Error("The account is not a supported configuration.");
}
if (!status.coreInstalled) {
  // Install the core through the owner path before preparing an approval.
}
```

## Pagination

List methods take `PageOptions` and return a `data` array with a cursor. `limit`, `cursor`, and `environment` are all optional.

```ts theme={null}
import { GolApiClient } from "@gol/sdk/server";

declare const gol: GolApiClient;
declare const projectId: string;

let cursor: string | undefined;
let total = 0;
do {
  const page = await gol.listGasExecutions(projectId, { limit: 100, cursor });
  total += page.data.length;
  cursor = page.nextCursor ?? undefined;
} while (cursor);
```

## Transport behavior

Each request sends `Accept: application/json`, `cache: no-store`, and `Authorization: Bearer <credential>` when a credential is present. A `204` response is treated as an empty body, which is what `revokeSession` returns.

Anything other than a 2xx becomes a `GolApiError` carrying the API's own `code`, the HTTP `status`, and a `correlationId`. A transport failure, a non-JSON body, or an invalid `baseUrl` becomes a `GolTransportError`. See [errors](/sdk/errors).
