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

# Mint an Ephemeral Key

> Mint a short-lived, safe-to-embed Ephemeral Key (gr_ek_ RS256 JWT) from a parent API key, for use in browsers, mobile apps, and WebSocket clients.

<CardGroup cols={2}>
  <Card title="Credential"> Parent API key (`cqt_…` / `ckey_…`)</Card>
  <Card title="Processing"> Realtime</Card>
</CardGroup>

Mints a short-lived **Ephemeral Key** - a signed RS256 JWT, prefixed `gr_ek_`, that you can safely hand to an untrusted client (browser, mobile app, WebSocket). The token carries no secret and expires on its own, so a stolen token is only useful until its `exp`. See the [Ephemeral Keys guide](/docs/ephemeral-keys) for the full security model and recipes.

Authenticate **with your parent API key**, not with an Ephemeral Key. An Ephemeral Key cannot mint another Ephemeral Key, and a `gr_sk_…` service key cannot mint either.

<Note>
  Platform endpoints on `api.covalenthq.com` require a **trailing slash** - call `/platform/ephemeral_keys/`, not `/platform/ephemeral_keys`.
</Note>

## Endpoint

```
POST https://api.covalenthq.com/platform/ephemeral_keys/
Authorization: Bearer <GOLDRUSH_API_KEY>
```

## Request

The request body is optional JSON. In this release the only accepted field is `ttl_seconds`; any other fields are ignored, and an Ephemeral Key always inherits the parent's full access.

<ParamField body="ttl_seconds" type="integer" default="1800">
  Requested lifetime in seconds. Defaults to **1800** (30 min). Clamped to `[1, 3600]` - the server maximum is **3600** (60 min), so larger requests are silently reduced to the cap. A non-integer value returns `400`.
</ParamField>

### Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.covalenthq.com/platform/ephemeral_keys/" \
    -H "Authorization: Bearer $GOLDRUSH_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"ttl_seconds": 1800}'
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(
    "https://api.covalenthq.com/platform/ephemeral_keys/",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.GOLDRUSH_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ ttl_seconds: 1800 }),
    },
  );

  const { ephemeral_key, expires_at } = await response.json();
  ```

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

  response = requests.post(
      "https://api.covalenthq.com/platform/ephemeral_keys/",
      json={"ttl_seconds": 1800},
      headers={"Authorization": f"Bearer {os.environ['GOLDRUSH_API_KEY']}"},
  )
  response.raise_for_status()

  body = response.json()
  ```
</CodeGroup>

## Response

`200 OK`

```json theme={null}
{
  "ephemeral_key": "gr_ek_eyJhbGciOiJSUzI1NiIsImtpZCI6…",
  "expires_at": "2026-08-03T18:30:00+00:00"
}
```

### Field descriptions

<ResponseField name="ephemeral_key" type="string">
  The signed RS256 JWT, prefixed `gr_ek_`. This is what you hand to the client. It carries no secret - it is trusted only because of its signature.
</ResponseField>

<ResponseField name="expires_at" type="string">
  ISO-8601 UTC timestamp at which the token's `exp` claim falls due. Refresh before this time.
</ResponseField>

## Token claims

An Ephemeral Key is a standard RS256 JWT. Any verifier can decode it (no private key needed) and validate its signature against the [Ephemeral JWKS endpoint](/docs/api-reference/ephemeral-keys/get-the-ephemeral-jwks).

| Claim           | Meaning                                                                                                                                                       |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `iss`           | Always `goldrush`.                                                                                                                                            |
| `sub`           | Unique id of this Ephemeral Key (a per-mint session id, e.g. `ek_…`).                                                                                         |
| `parent_key_id` | The minting API key's **non-secret public id** (a UUID) - usage, quota, and billing attribute here. The raw `cqt_`/`ckey_` secret never appears in the token. |
| `iat`           | Issued-at (UNIX seconds).                                                                                                                                     |
| `exp`           | Expiry (UNIX seconds). Verifiers reject the token after this.                                                                                                 |

The signing key id (`kid`) travels in the **JWT header**, not the claims. There is no `scopes` claim in this release.

## Use the Ephemeral Key

Hand the returned `gr_ek_…` token to your client and use it exactly where you would use an API key - as a Bearer token, Basic Auth username, or `key` query parameter - against the data APIs. It authenticates on behalf of the parent API key.

<CodeGroup>
  ```bash cURL theme={null}
  # Bearer token
  curl -X GET "https://api.covalenthq.com/v1/eth-mainnet/address/demo.eth/balances_v2/" \
    -H "Authorization: Bearer $GOLDRUSH_EPHEMERAL_KEY"

  # or as a query parameter
  curl -X GET "https://api.covalenthq.com/v1/eth-mainnet/address/demo.eth/balances_v2/?key=$GOLDRUSH_EPHEMERAL_KEY"
  ```

  ```bash WebSocket theme={null}
  # Hyperliquid WebSocket takes the credential as a query parameter at connect time
  wscat -c "wss://hypercore.goldrushdata.com/ws?key=$GOLDRUSH_EPHEMERAL_KEY"
  ```
</CodeGroup>

See the [Ephemeral Keys quick start](/docs/ephemeral-keys#quick-start-curl) for the full mint-then-use flow.

## Common uses

* **Browser / mobile embedding** - mint on your backend, hand the `gr_ek_…` token to the client so it can call the data APIs directly without exposing your `cqt_…` key.
* **WebSocket auth** - web-locked keys don't cover WebSockets; an Ephemeral Key does. See [Recipe B](/docs/ephemeral-keys#recipe-b-browser-websocket-with-auto-refresh).
* **Per-session isolation** - one token per client session, refreshed on a timer, so any single stolen token is short-lived.

## Common errors

Errors are returned in the standard GoldRush envelope (`{ "error": true, "error_message": …, "error_code": … }`).

| Status                  | Cause                                                                                                                                          | Fix                                                                    |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `400 Bad Request`       | Body isn't valid JSON, or `ttl_seconds` isn't an integer.                                                                                      | Send valid JSON with an integer `ttl_seconds` (or omit the body).      |
| `401 Unauthorized`      | Missing/malformed `Authorization` header, or the bearer isn't a valid parent API key.                                                          | Confirm `Authorization: Bearer <cqt_…>` with an active API key.        |
| `403 Forbidden`         | The bearer is a `gr_ek_…` Ephemeral Key or a `gr_sk_…` service key (neither may mint), or the parent API key isn't enabled for Ephemeral Keys. | Authenticate with a parent API key enabled for Ephemeral Keys.         |
| `404 Not Found`         | Ephemeral Keys aren't enabled on this deployment.                                                                                              | Contact support to enable the feature.                                 |
| `429 Too Many Requests` | The parent API key exceeded its mint rate (default 60/min).                                                                                    | Mint one token per session and refresh on a timer; back off and retry. |

<Warning>
  This endpoint is **rate-limited per parent API key** (default **60 mints/minute**). Mint one Ephemeral Key per client session and refresh on a timer - do **not** mint a fresh token on every request.
</Warning>
