# Dewemoji API — Reference and Smoke Test

This is the single API documentation source for the current Laravel rebuild.

## Base URLs

- Local: `http://127.0.0.1:8000/v1`
- Staging: `https://dewemoji.backoffice.biz.id/v1`

Convenience:

```bash
BASE=http://127.0.0.1:8000/v1
# BASE=https://dewemoji.backoffice.biz.id/v1
```

## Auth and request headers

License-style auth (legacy-compatible):

- `Authorization: Bearer YOUR_LICENSE_KEY` (preferred)
- `X-License-Key: YOUR_LICENSE_KEY` (supported)

Optional headers:

- `X-Account-Id`
- `X-Dewemoji-Frontend`

Common response headers:

- `X-Dewemoji-Tier`: `free` or `pro`
- `X-Dewemoji-Plan`: `free` or `pro`
- `ETag`
- `Cache-Control`
- Rate-limit headers on free tier page 1 requests:
  - `X-RateLimit-Limit`
  - `X-RateLimit-Remaining`
  - `X-RateLimit-Reset`

## Endpoint map

Public/search:

- `GET /emojis`
- `GET /emoji/{slug}` or `GET /emoji?slug=...`
- `GET /categories`
- `GET /health`

License and access lifecycle:

- `POST /license/verify`
- `POST /license/activate`
- `POST /license/deactivate`

Extension verification:

- `POST /extension/verify`
- `GET /extension/search`

Metrics/internal:

- `GET /metrics-lite`
- `GET /metrics`

Admin token endpoints (`X-Admin-Token` required):

- `GET /admin/settings`
- `POST /admin/settings`
- `GET /admin/subscriptions`
- `POST /admin/subscription/grant`
- `POST /admin/subscription/revoke`
- `GET /admin/webhooks`
- `GET /admin/webhooks/{id}`
- `POST /admin/webhooks/{id}/replay`
- `GET /admin/analytics`

## Endpoint details

### `GET /emojis`

Query params:

- `q` or `query`
- `category`
- `subcategory`
- `page` (default `1`)
- `limit` (free max `20`, pro max `50`)

Example:

```bash
curl -s "$BASE/emojis?q=love&limit=5" | jq .
```

### `GET /emoji/{slug}` or `GET /emoji?slug=...`

Example:

```bash
curl -s "$BASE/emoji/grinning-face" | jq .
```

Errors:

- `400` `missing_slug`
- `404` `not_found`

### `GET /categories`

Returns `category -> subcategories[]` mapping.

```bash
curl -s "$BASE/categories" | jq .
```

### `POST /license/verify`

```bash
KEY=YOUR_LICENSE_KEY
curl -s -X POST "$BASE/license/verify" \
  -H "Authorization: Bearer $KEY" | jq .
```

Success shape (example):

```json
{
  "ok": true,
  "tier": "pro",
  "source": "gumroad|mayar|sandbox|...",
  "plan": "pro",
  "product_id": "...",
  "expires_at": null,
  "error": null
}
```

### `POST /license/activate`

```bash
KEY=YOUR_LICENSE_KEY
curl -s -X POST "$BASE/license/activate" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","product":"extension","device_id":"local-dev"}' | jq .
```

Notes:

- `product=site` can omit `device_id`.

### `POST /license/deactivate`

```bash
KEY=YOUR_LICENSE_KEY
curl -s -X POST "$BASE/license/deactivate" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"product":"extension","device_id":"local-dev"}' | jq .
```

### `GET /health`

```bash
curl -s "$BASE/health" | jq .
```

## Public access guard

Public endpoints use whitelist + throttle behavior:

- If request is whitelisted: pass.
- If not whitelisted and `DEWEMOJI_PUBLIC_ENFORCE=true`: `403 public_access_denied`.
- Otherwise: soft throttle with `DEWEMOJI_PUBLIC_HOURLY_LIMIT` and `429 public_rate_limited`.

Key env:

```env
DEWEMOJI_PUBLIC_ENFORCE=true|false
DEWEMOJI_PUBLIC_ORIGINS=https://dewemoji.com,https://www.dewemoji.com
DEWEMOJI_PUBLIC_HOURLY_LIMIT=5000
DEWEMOJI_EXTENSION_IDS=chrome-extension://...
```

Security note:

- `Origin`/`Referer` are not strong security controls. Use edge/WAF/API keys for stronger protection.

## Caching behavior

ETag is supported. `If-None-Match` can return `304 Not Modified`.

```bash
ETAG=$(curl -i "$BASE/emojis?q=love&limit=5" | awk -F': ' '/^ETag:/ {print $2}' | tr -d '\r')
curl -i -H "If-None-Match: $ETAG" "$BASE/emojis?q=love&limit=5" | head -n 1
```

## Smoke test checklist

### Health

```bash
curl -s "$BASE/health" | jq .
```

Expected: `{ "ok": true, ... }`

### Categories

```bash
curl -s "$BASE/categories" | jq 'keys | length'
```

Expected: count > 0.

### Search

```bash
curl -s "$BASE/emojis?q=love&limit=5" | jq '.items | length'
```

Expected: count > 0.

### Detail

```bash
curl -s "$BASE/emoji/grinning-face" | jq '.slug,.name'
```

### Free-tier rate-limit headers

```bash
curl -i "$BASE/emojis?limit=1&page=1" | grep -E "HTTP|X-RateLimit"
```

### Verify / activate / deactivate

Use the commands in endpoint details above.

### Error response check

```bash
curl -s "$BASE/emoji/this-does-not-exist" | jq .
```

Expected `error: not_found`.

## Legacy compatibility notes

Kept for extension/backward compatibility:

- accepts both `q` and `query`
- supports `Authorization` and `X-License-Key`
- includes `X-Dewemoji-Tier`

Legacy contract references (`/api/*` in old stack) were consolidated here. No separate legacy API spec file is needed now.
