Keys and limits
Publishable and secret keys, allowed origins, rate limits and what happens at a plan limit.
On this page
Keys tell the API which app is calling, so it can apply that app’s plan and rate limits. There are two kinds, one for code that runs in front of people and one for servers.
Publishable and secret keys
| Key | Use in | Sent as | Checks |
|---|---|---|---|
Publishable pk_live_… | Browsers and extensions | ?key= in the URL | The Origin must be one of the key’s allowed origins |
Secret sk_live_… | Servers, bots, MCP, tenant management | Authorization: Bearer | Refused with an Origin header or in the URL |
fetch("https://api.emojisense.com/v1/search?q=ship%20it&key=pk_live_…");curl "https://api.emojisense.com/v1/search?q=ship%20it" \
-H "Authorization: Bearer sk_live_…"Create keys in the dashboard, per app. The full key is shown once. The dashboard stores only a hash of it. Call the API at https://api.emojisense.com over HTTPS: a plain http:// request gets 403, so a key never travels unencrypted.
Allowed origins
- Add every origin your app runs on, for example
https://your.appandhttp://localhost:5173. - An empty list allows any origin. Only apps in the
devenvironment may have such keys. - For a Chrome extension, add the extension origin shown on its options page.
Revoking
Revoke a key in the dashboard. The API caches key lookups for up to 60 seconds, so a revoked key stops working within a minute. An unknown or revoked key gets 401.
Rate limits
| Caller | Limit |
|---|---|
| A key | 120 requests a minute, per key and IP address |
| No key | 30 requests a minute, per IP address |
Over it, the API answers 429 with Retry-After: 60. The IP address is only an in-memory key for the limiter. It is never logged or stored. Static files and emoji images are not limited.
Without a key
Search, reaction suggestions and photo to emoji also work without a key, for demos and first tests. Such calls are never metered and never over a limit, but they get the stricter rate limit, no custom emoji and no analytics. Custom packs and the tenants API need a key.
Plan limits
Limits are monthly, in UTC, with no daily caps. Only Worker calls are metered: searches and reaction suggestions that reach the API, and photo classifications. On-device searches, packs and shards are free on every plan.
| Plan | Price | Worker calls | Photo to emoji | Custom emoji | Apps |
|---|---|---|---|---|---|
| Free | Free | 100k | 100 | — | 1 |
| Solo | $5 a month | 500k | 1k | 500 | 1 |
| Pro | $20 a month | 3M | 10k | 2k | 3 |
| Scale | $100 a month | 15M | 75k | 10k | Unlimited |
See Pricing for every feature of each plan. Paid plans are not on sale yet: the pricing page has a waitlist for each one. Limits belong to the account, so the calls of all its apps count together. The dashboard shows each app’s part of the month’s usage.
Over the limit
The API never fails because of a plan limit. A query that is in the shared edge cache is still answered, and is not counted. Any other query returns 200 with "overLimit": true:
{
"query": "…",
"results": [/* dictionary results only (hybrid), or none (semantic) */],
"cached": false,
"degraded": false,
"overLimit": true
}The SDKs handle this for you: search stays on the device and the shards, and people keep typing as before. Photo classification returns no results until the next month.