Credits & rate limits
Every plan is a monthly credit balance plus a per-second request allowance. Each endpoint has a fixed price in credits, charged when the lookup succeeds. Nothing is metered by the byte.
Plans
| Plan | Credits / month | Requests / sec | API keys | Price |
|---|---|---|---|---|
| Free | 100 | 2 | 2 | $0 |
| Starter | 80,000 | 30 | 5 | $19.99 |
| Pro | 300,000 | 60 | 10 | $49.99 |
| Enterprise | 1,500,000 | 100 | 25 | $199.99 |
Prices are monthly, in US dollars, and include any applicable tax. Credits refill every 30 days; credits_reset_at tells you when. Your live balance is on the dashboard, and integrations can read it, with the plan and its renewal dates, using an API key. The call is free.
curl -X GET "https://api.senapati.io/api/account/subscription" \ -H "X-API-Key: $SENAPATI_API_KEY"
{"request_id": "req_5d1e9b3c","timestamp": "2026-10-11T16:20:03.118402+00:00","data": {"plan": "Starter","billing_status": "active","credits_remaining": 61218,"credits_per_month": 80000,"credits_reset_at": "2026-11-04T09:12:40+00:00","current_period_end": "2026-11-05T09:10:17+00:00","cancel_at_period_end": false,"rate_limit_per_second": 30,"max_api_keys": 5}}
| Field | Type | Description |
|---|---|---|
| plan* | string | Plan name: Free, Starter, Pro or Enterprise |
| billing_status | string | null | Status of the paid subscription as the billing provider reports it; null on the Free plan |
| credits_remaining* | integer | Credits left in the current cycle |
| credits_per_month* | integer | Credits the plan grants per cycle |
| credits_reset_at | string | null | When the balance refills to credits_per_month (ISO 8601) |
| current_period_end | string | null | When the paid term ends or renews (ISO 8601); null on the Free plan |
| cancel_at_period_end | boolean | True when the subscription is cancelled and the plan ends at current_period_enddefault false |
| rate_limit_per_second* | integer | Requests per second allowed |
| max_api_keys* | integer | API keys the plan allows |
What each call costs
| Endpoint | Credits | Notes |
|---|---|---|
| POST /api/check-ip | 1 | IP reputation |
| POST /api/domain-reputation | 1 | Domain reputation |
| POST /api/url-reputation | 2 | Fetches and analyses the page as well as the host |
| POST /api/email-reputation | 1 | Email verification |
| POST /api/dns-lookup | 1 | Any record type, or ALL |
| POST /api/whois-lookup | 1 | WHOIS |
| POST /api/bulk/* | n × price | n items (max 100), one charge per batch |
| POST /api/free/* | 0 | No key; reduced output |
| GET /api/account/subscription | 0 | Plan and balance |
- Authentication and validation happen before the charge, so a
401or422never costs anything. - Bulk calls charge
items × pricefor the batch. Items that fail inside the batch are reported per item and are not refunded.
When the balance runs out
A call that would take the balance below zero is rejected with 402 and code INSUFFICIENT_CREDITS; the balance is left untouched.
{"errors": [{"code": "INSUFFICIENT_CREDITS","message": "Insufficient credits. This request costs 1 credit(s).","field": null,"details": {"cost": 1}}],"request_id": "req_8f2c1a7e"}
Rate limits
Each endpoint has two limits, both equal to your plan’s requests per second: how many requests you may start in any one-second sliding window, and how many may be in flight at once. They are counted per account and per endpoint, so all of an account’s keys share one budget and each endpoint has its own. URL reputation and the bulk endpoints get half the plan’s allowance.
Every authenticated response reports where you stand:
| Header | Meaning |
|---|---|
| X-Concurrency-Limit | Requests that may be in flight at once on this endpoint. |
| X-Concurrency-Remaining | In-flight slots still free. |
| X-RateLimit-Limit | Requests you may start per window on this endpoint. |
| X-RateLimit-Remaining | Requests left in the current window. |
| X-RateLimit-Window | Window length in seconds. |
| X-RateLimit-Reset-After | Seconds until a request slot frees up. |
| X-RateLimit-Scope | Only on 429: which limit was hit, requests or concurrency. |
| Retry-After | Only on 429: seconds to wait before retrying. |
A request over either limit is rejected with 429 and code RATE_LIMIT_EXCEEDED, and is not charged. Size your worker pool from X-Concurrency-Limit and pace requests from X-RateLimit-Limit; read both from a response rather than hard-coding them. Bulk endpoints count as one request regardless of item count, which is the cheapest way to stay under the limit when you have many lookups.
Free tool endpoints (/api/free/*) allow 5 requests per minute per client address, counted separately for each tool.