Tiers & Limits
Choose the tier that fits your usage.
Table of contents
Feature matrix
| Feature | FREE | STARTER | DEVELOPER | BUSINESS |
|---|---|---|---|---|
| Max characters | 3 | 5 | 30 | 100 |
| AI ops / month | 0 | 1,000 | 50,000 | 500,000 |
| Min sync interval | 60s | 30s | 15s | 5s |
| Max API keys | 1 | 1 | 3 | 10 |
| Max members | 1 | 1 | 3 | 10 |
| File sync | ✅ | ✅ | ✅ | ✅ |
| AI extraction | ❌ | ✅ | ✅ | ✅ |
| Direct memory write | ❌ | ✅ | ✅ | ✅ |
| Import pipeline | ❌ | ✅ | ✅ | ✅ |
| Auto-capture / Auto-recall | ❌ | ✅ | ✅ | ✅ |
| Team sharing | ❌ | ❌ | ✅ | ✅ |
| Smart retrieval | ❌ | ❌ | ✅ | ✅ |
| Webhooks & audit trail | ❌ | ❌ | ❌ | ✅ |
BYOK users: Providing your own AI provider key removes the AI ops / month cap. You are billed directly by your AI provider. Infrastructure rate limits (see below) still apply.
Rate limit buckets
HippoDid uses per-operation buckets for fine-grained rate limiting. Each bucket has its own limit — a burst of search requests won’t affect your write quota.
Rates (requests per minute, sustained)
| Bucket | What it covers | FREE | STARTER | DEVELOPER | BUSINESS |
|---|---|---|---|---|---|
SEARCH | GET /characters, /memories, /memories/search | 2 | 30 | 60 | 200 |
WRITE | POST /characters (create), PUT /memories | 2 | 30 | 60 | 200 |
SYNC | Paths containing /sync or /v1/files/ | 1 | 4 | 8 | 20 |
MANAGEMENT | DELETE, GET /tier, PUT profile/aliases | 5 | 30 | 120 | 600 |
AI_PROXY | Reserved for future AI proxy endpoints | 0 | 30 | 60 | 200 |
Burst allowance
For the first 10 seconds of a rate limit window, the effective limit is 2× the sustained rate. This accommodates startup bursts (e.g., loading all character data on app boot) without eating into your sustained quota.
Request → bucket mapping
| Request | Bucket |
|---|---|
GET /v1/characters/** | SEARCH |
POST /v1/characters/{id}/memories/search | SEARCH |
POST /v1/characters (create) | WRITE |
PUT /v1/characters/{id}/memories/{id} | WRITE |
Anything with /sync in the path | SYNC |
Anything under /v1/files/ | SYNC |
POST /v1/characters/{id}/import | SYNC |
| DELETE requests | MANAGEMENT |
GET /v1/tier | MANAGEMENT |
PUT /v1/characters/{id}/profile | MANAGEMENT |
PUT /v1/characters/{id}/aliases | MANAGEMENT |
Rate limit headers
Every response includes:
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 27
X-RateLimit-Reset: 1705312260
X-RateLimit-Bucket: WRITE
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests for this bucket in the current 1-minute window |
X-RateLimit-Remaining | Requests remaining before the limit is hit |
X-RateLimit-Reset | Unix timestamp (seconds) when the window resets |
X-RateLimit-Bucket | Which bucket this request was counted against |
429 Too Many Requests
When you exceed a rate limit:
{
"error": {
"type": "TierLimitExceeded",
"message": "Rate limit exceeded for bucket WRITE on tier STARTER",
"status": 429
}
}
Use the X-RateLimit-Reset header to determine when to retry:
import time
response = requests.post(url, headers=headers, json=body)
if response.status_code == 429:
reset_at = int(response.headers.get("X-RateLimit-Reset", 0))
wait_secs = max(0, reset_at - int(time.time())) + 1
time.sleep(wait_secs)
# retry
Character limit (429)
Attempting to create a character beyond your tier’s maxCharacters returns:
{
"error": {
"type": "CharacterLimitExceeded",
"message": "Character limit reached for tier STARTER (max: 5)",
"status": 429
}
}
Archive unused characters to free up slots, or upgrade your tier.
Upgrade path
FREE → STARTER → DEVELOPER → BUSINESS
Upgrades take effect immediately. Downgrades take effect at the end of the billing period. Existing characters and memories are preserved on downgrade — you’ll just be unable to create new ones beyond the lower tier’s limit until you’re within bounds.
Contact support@hippodid.com for Enterprise pricing (custom limits, SLA, dedicated support).