API Key Reference
Complete reference for API key format, permissions, rate limits, and technical specifications.
Key Format
Section titled “Key Format”All API keys use a consistent format for easy identification:
idx_{role_prefix}{random_string}Format Components
Section titled “Format Components”| Component | Description | Example |
|---|---|---|
| Prefix | Always idx_ |
idx_ |
| Role Indicator | Optional single character | a (admin), b (broker), g (agent) |
| Random String | Cryptographically secure random characters | a1b2c3d4e5f6g7h8i9j0 |
Example Keys
Section titled “Example Keys”idx_live_SAgFqBpAMP_znpf3GffgCI (Admin key)idx_broker_Kp9mNq2rSt3vWx4yZ5 (Broker key)idx_agent_Ab7cDe8fGh9iJk0lMn1 (Agent key)Role-Based Permissions
Section titled “Role-Based Permissions”Admin Role
Section titled “Admin Role”| Permission Category | Capabilities |
|---|---|
| Properties | Read, create, update, delete all properties |
| Users | Create, update, deactivate all users (admins, brokers, agents) |
| Brokerages | Create, update, delete all brokerages |
| API Keys | Create, view, revoke all API keys |
| System Config | Modify platform settings, feature flags |
| Data Management | Export, import, clear database tables |
| Analytics | Access all usage metrics and reports |
Broker Role
Section titled “Broker Role”| Permission Category | Capabilities |
|---|---|
| Properties | Read all properties, update listings for assigned brokerage |
| Agents | Create, update, deactivate agents within assigned brokerage |
| Leads | View and manage leads for assigned brokerage |
| Brokerage Settings | Update settings for assigned brokerage only |
| Reports | Access brokerage-specific analytics |
| API Keys | Create and revoke keys for own brokerage (agent-level only) |
Agent Role
Section titled “Agent Role”| Permission Category | Capabilities |
|---|---|
| Properties | Read-only access to all properties |
| Own Profile | Update own agent profile and preferences |
| Leads | View leads assigned to self only |
| Tours | Create and manage tour requests |
| Suggestions | Submit property update suggestions |
| Favorites | Manage own saved properties |
Rate Limits
Section titled “Rate Limits”Public listing endpoints
Section titled “Public listing endpoints”These are the limits the server actually enforces today, and they work differently from the per-key table below.
/api/listings, /api/search, /api/suggestions and /api/embed are
public: the tenant sites call them from the browser, so no credential can
gate them. What a key buys on these paths is not access, it is identity.
| Caller | Bucket | Default ceiling |
|---|---|---|
| No key | Per client IP | 120 requests / 60s |
Valid idx_ key |
Per key | 600 requests / 60s |
Revoked or expired idx_ key |
None | 403 |
Send the key as Authorization: Bearer idx_.... A server-side integration
that does so becomes countable and throttleable on its own, and can be
switched off by revoking the key without changing anything for the public.
Two things to know before depending on the numbers:
- The window is in-process, per worker. The real ceiling is the number above multiplied by the worker count, and a restart forgets every window. It is a speed bump for scrapers, not a quota system.
- Internal callers are exempt. Our own server-side rendering reaches the API from inside the Docker network; limiting private addresses would throttle the site while leaving a direct-to-API scraper untouched.
Both ceilings are environment variables: RATE_LIMIT_REQUESTS,
RATE_LIMIT_KEYED_REQUESTS and RATE_LIMIT_WINDOW_SECONDS.
Intended per-key limits
Section titled “Intended per-key limits”The tables below describe the intended shape of per-key limiting for authenticated admin endpoints. They are not all enforced yet; where they differ from the section above, the section above is what runs.
Default limits per API key (adjustable by administrators):
Standard Rate Limits
Section titled “Standard Rate Limits”| Time Window | Limit | Applies To |
|---|---|---|
| Per Minute | 100 requests | All roles |
| Per Hour | 1,000 requests | All roles |
| Per Day | 10,000 requests | All roles |
Rate Limit by Endpoint Type
Section titled “Rate Limit by Endpoint Type”| Endpoint Category | Per Minute | Per Hour |
|---|---|---|
| Read Operations (GET) | 100 | 1,000 |
| Write Operations (POST, PUT, PATCH) | 50 | 500 |
| Delete Operations (DELETE) | 10 | 100 |
| Search/Analytics | 30 | 300 |
Rate Limit Headers
Section titled “Rate Limit Headers”Every API response includes rate limit information:
X-RateLimit-Limit: 100X-RateLimit-Remaining: 95X-RateLimit-Reset: 1640995200| Header | Type | Description |
|---|---|---|
X-RateLimit-Limit |
Integer | Maximum requests allowed in current window |
X-RateLimit-Remaining |
Integer | Requests remaining in current window |
X-RateLimit-Reset |
Unix Timestamp | When the rate limit window resets |
Rate Limit Exceeded Response
Section titled “Rate Limit Exceeded Response”HTTP/1.1 429 Too Many RequestsContent-Type: application/jsonRetry-After: 60X-RateLimit-Limit: 100X-RateLimit-Remaining: 0X-RateLimit-Reset: 1640995260
{ "error": "rate_limit_exceeded", "message": "Rate limit exceeded. Retry after 60 seconds.", "retry_after": 60}Authentication Flow
Section titled “Authentication Flow”Request Authentication
Section titled “Request Authentication”sequenceDiagram
Client->>API: Request with X-API-Key header
API->>Database: Validate key
Database-->>API: Key valid + role
API->>API: Check permissions
API-->>Client: Response or 401/403
Authentication States
Section titled “Authentication States”| Response Code | Meaning | Action Required |
|---|---|---|
| 200-299 | Authenticated and authorized | Continue using key |
| 401 Unauthorized | Invalid or revoked key | Generate new key |
| 403 Forbidden | Valid key, insufficient permissions | Request higher-privilege key |
| 429 Too Many Requests | Rate limit exceeded | Implement backoff, reduce request rate |
Key Metadata
Section titled “Key Metadata”Each API key stores the following metadata:
| Field | Type | Description |
|---|---|---|
id |
UUID | Unique key identifier |
key |
String | Hashed API key value (original never stored) |
name |
String | User-provided descriptive name |
role |
Enum | admin, broker, or agent |
brokerage_id |
UUID | Associated brokerage (null for admin keys) |
created_at |
DateTime | Timestamp of creation |
created_by |
UUID | User who created the key |
last_used_at |
DateTime | Most recent successful authentication |
revoked_at |
DateTime | Timestamp when revoked (null if active) |
revoked_by |
UUID | User who revoked the key |
Usage Tracking
Section titled “Usage Tracking”Tracked Metrics
Section titled “Tracked Metrics”| Metric | Description | Retention Period |
|---|---|---|
| Request Count | Total successful requests | 90 days |
| Error Count | Failed requests (4xx, 5xx) | 90 days |
| Response Time | Average latency per endpoint | 30 days |
| Data Transfer | Bytes sent/received | 30 days |
| Endpoint Usage | Requests per endpoint path | 90 days |
Log Format
Section titled “Log Format”{ "timestamp": "2024-12-28T10:30:00Z", "api_key_id": "550e8400-e29b-41d4-a716-446655440000", "endpoint": "/api/v1/properties", "method": "GET", "status_code": 200, "response_time_ms": 45, "bytes_sent": 15234, "bytes_received": 256, "ip_address": "203.0.113.42", "user_agent": "Custom Integration v1.2.3"}Security Specifications
Section titled “Security Specifications”Key Generation
Section titled “Key Generation”- Algorithm: Cryptographically secure pseudo-random number generator (CSPRNG)
- Entropy: 256 bits minimum
- Character Set: Base62 (A-Z, a-z, 0-9)
- Length: 32-48 characters (excluding prefix)
Key Storage
Section titled “Key Storage”- Hashing Algorithm: bcrypt with work factor 12
- Original Key: Never stored, only hash
- Salt: Unique per key, generated by bcrypt
Validation
Section titled “Validation”Keys are validated in constant time to prevent timing attacks.
Related Documentation
Section titled “Related Documentation”- Manage API Keys — Creating, using, and revoking keys
- API Key Security — Security model and best practices
- API Overview — REST API documentation