# Dashboard & API keys

> Sign in to dashboard.layerhop.com with an EVM or Solana wallet, create lh_live_ API keys, send them as x-api-key, understand rate limits, and read usage, logs, orders, webhooks and partner earnings.

Source: https://docs.layerhop.com/guides/dashboard-and-api-keys

The LayerHop developer dashboard at [dashboard.layerhop.com](https://dashboard.layerhop.com) is where you sign in with a wallet (no email or password), create `lh_live_…` API keys, and see usage, request logs, orders, webhooks and partner earnings. API keys are optional: the public API works without one at a lower per-IP rate limit, and a key adds a higher limit, attribution of orders to your account, [webhooks](/guides/webhooks) and [partner fees](/guides/partner-fees).

## Do I need an API key?

| | Without a key | With a key |
|---|---|---|
| Quotes, orders, chains, tokens, prices, balances | Yes | Yes |
| Rate limit | 60 requests/minute per IP | 120 requests/minute per key by default |
| Orders attributed to your account | No | Yes, listed in the dashboard |
| Webhooks | No | Yes |
| Partner fee via `x-api-key` and per-request `integratorFeeBps` | No | Yes, when your account is an active partner |
| Fee channel | Whatever `channel` you send (the SDK sends `api`, 0.20%) | Same |

## 1. Sign in with your wallet

Open [dashboard.layerhop.com](https://dashboard.layerhop.com) and connect an EVM or Solana wallet. The dashboard asks the wallet to sign a short message; signing is free, sends no transaction and grants no spending rights. The first sign-in creates your account.

Under the hood this is Sign-In with Ethereum (EIP-4361) for EVM wallets, and the same text format for Solana:

| Step | Endpoint | What happens |
|---|---|---|
| Get a message | [`POST /v1/auth/nonce`](/api-reference#get-a-sign-in-message) with `{ vm, address }` | Returns `{ nonce, message, expiresAt }`. The message names `dashboard.layerhop.com`, a single-use nonce and a 10-minute expiry. |
| Sign and verify | [`POST /v1/auth/verify`](/api-reference#verify-the-signature-and-sign-in) with `{ vm, message, signature }` | Checks the signature against the exact message issued, then sets the session cookie. |
| Who am I | [`GET /v1/auth/me`](/api-reference#current-account) | Your account, linked wallets and partner profile, or `401`. |
| Sign out | [`POST /v1/auth/logout`](/api-reference#sign-out) | Clears the cookie. |

- The session is an HttpOnly, Secure `lh_session` cookie valid for 7 days. It only works for the dashboard; public API calls use API keys.
- EVM sign-in supports regular wallets (EOAs). Smart-contract wallets that sign through ERC-1271 or ERC-6492 are not supported yet.
- Solana signatures are ed25519, accepted as base58 or base64.
- Link more wallets to the same account under **Settings → Link another wallet**.

## 2. Create an API key

Open **API keys**, choose **Create API key** and give it a name (for example `production`). The secret is shown **once**; copy it into your server's secret store.

| Property | Value |
|---|---|
| Format | `lh_live_` followed by 32 letters and digits |
| Stored by LayerHop | Only a SHA-256 hash and the first 12 characters (the prefix shown in the list) |
| Active keys per account | Up to 20 |
| Default rate limit | 120 requests/minute per key |
| Rename | Any time |
| Revoke | **Revoke** in the list, or [`DELETE /v1/dashboard/keys/{id}`](/api-reference#revoke-an-api-key). Requests with a revoked key get `401 UNAUTHORIZED`. |

> [!WARNING]
> An API key identifies your account and can carry your partner fee. Keep it on your server; never ship it in browser or mobile code. If a key leaks, revoke it and create a new one.

## 3. Send the key

Send the key in the `x-api-key` header on any public `/v1` route:

```bash
curl -H "x-api-key: $LAYERHOP_API_KEY" \
  "https://api.layerhop.com/v1/quote?srcChain=base&srcToken=USDC&amount=100000000&dstChain=solana&dstToken=SOL&sender=0x…&recipient=…"
```

```ts
const lh = new LayerHop({ apiKey: process.env.LAYERHOP_API_KEY });
```

Keys apply to the public routes: chains, tokens, prices, balances, quotes, orders, simulate and order status. They are not used for `/v1/health`, sign-in or dashboard routes. An unknown or revoked key is an error (`401`), not a fallback to anonymous access.

## What are the rate limits?

| Caller | Limit | Counted per |
|---|---|---|
| No `x-api-key` | 60 requests/minute | Client IP |
| API key | 120 requests/minute by default | Key |

Limits are token buckets that refill continuously, so short bursts up to the limit are fine. `/v1/health` is not limited. Every limited response carries:

| Header | Meaning |
|---|---|
| `x-ratelimit-limit` | Your limit in requests per minute |
| `x-ratelimit-remaining` | Requests left right now |
| `retry-after` | Only on `429`: seconds to wait |

Over the limit you get `429` with [`RATE_LIMITED`](/errors/RATE_LIMITED). Wait `retry-after` seconds before retrying. Need a higher limit? Email dev@layerhop.com with your account id and expected volume.

## What does the dashboard show?

| Page | What you see |
|---|---|
| **Overview** | 30-day totals: requests, quotes, orders built and filled, volume by token, errors, partner earnings summary, recent orders |
| **API keys** | Your keys with prefix, rate limit, created and last-used times; create, rename, revoke |
| **Usage & logs** | Requests, errors, quotes and orders per hour or day, per key; a request log with method, path, status, latency, provider, error code and `requestId` |
| **Orders** | Orders attributed to your account, filterable by status |
| **Webhooks** | Endpoints, event selection, signing secret, delivery history, **Send test** and **Replay** ([guide](/guides/webhooks)) |
| **Partner program** | Apply, set your fee and payout addresses, see estimated earnings ([guide](/guides/partner-fees)) |
| **Settings** | Account name, linked wallets, session |

Usage and logs count public API traffic only, not dashboard or sign-in requests. Use the `requestId` from a log row (or the `x-request-id` response header) when you contact support.

## Can I use the dashboard API directly?

Yes. Every dashboard page is backed by `/v1/dashboard/*` endpoints in the [API reference](/api-reference). They need the `lh_session` cookie, so they are meant for the dashboard origin: state-changing requests from any other browser origin are rejected with [`FORBIDDEN`](/errors/FORBIDDEN).
