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

# Widget credentials

> Publishable keys, secret keys, and client IDs for EthioReview API clients.

EthioReview issues **one API client** per integration. Each client generates three linked credentials. Use the right credential for where your code runs.

## Credential types

| Credential          | Format                    | Where to use                                   |
| ------------------- | ------------------------- | ---------------------------------------------- |
| **Publishable key** | `pk_live_*` / `pk_test_*` | Browser embeds — React, Web Component, iframe  |
| **Secret key**      | `sk_live_*` / `sk_test_*` | Server-only partner API — never in client code |
| **Client ID**       | `cli_*`                   | Internal identifier — not sent by integrators  |

### Publishable key (widget embeds)

Copy from **Integrations → API Clients** in the dashboard. Pass it to the SDK as `publicKey` or `publishableKey`:

```tsx theme={null}
<ReviewWidget
  baseUrl="https://api.ethioreview.com"
  publicKey="pk_live_YOUR_KEY"
  widgetId="YOUR_WIDGET_ID"
/>
```

The SDK sends it as the `X-Widget-Key` header on every public widget request.

### Secret key (server integrations)

Use `Authorization: Bearer sk_live_*` for partner API routes such as `POST /partner/reviews`. Keep secrets in environment variables on your server only.

### Client ID

Derived from the secret key prefix. The backend uses it for internal lookups. You do not pass `cli_*` in widget embeds.

## Origin allowlist

Every API client has an **allowedOrigins** list. Browser requests must come from a matching domain (checked via `Origin` or `Referer`).

* Add every production, staging, and preview domain before go-live
* An empty allowlist blocks all widget traffic
* Local dev: include `http://localhost:3000` (or your dev port)

## Environment matching

| Dashboard environment | Publishable key prefix | Widget environment |
| --------------------- | ---------------------- | ------------------ |
| Production            | `pk_live_*`            | `PRODUCTION`       |
| Sandbox               | `pk_test_*`            | `SANDBOX`          |

A sandbox key cannot resolve a production widget, and vice versa.

## Key rotation

Rotating an API client secret also rotates the publishable key and client ID together. Update every embed after rotation.

## Security checklist

* Never commit `pk_*` or `sk_*` to public repositories — use environment variables
* Never embed `sk_*` in React, HTML, or mobile app bundles
* Prefer React or Web Component over iframe unless CSP requires isolation
* Restrict `allowedOrigins` to domains you control

[Widget registry →](/integrations/widget/registry) · [Sandbox testing →](/integrations/widget/sandbox)
