Skip to main content

Documentation Index

Fetch the complete documentation index at: https://demeterrr.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Overview

demeterrr enforces public API rate limits per organization, not per API key. All API keys in the same organization share the same limit pool. The current implementation applies two windows:
PolicyPurpose
Per-minute burstSmooth short spikes from automation or retries
Per-hour sustainedCap ongoing system-to-system traffic
API access and API rate-limit profile are related but separate concerns. An organization can have API access disabled, and an enabled organization can still use a custom rate-limit profile.

Default Profiles

These are the deployment defaults used when no organization-specific override is configured:
ProfilePer MinutePer Hour
starter1001,000
pro2505,000
business50010,000
enterprise1,00025,000
Enterprise organizations commonly use an override above the default profile. The default exists so enterprise traffic can be raised without a code change even before a per-org override is set.

Organization Overrides

Operations can raise or lower a specific organization’s limits without editing code by setting API_V1_RATE_LIMIT_ORGANIZATION_OVERRIDES. Example:
{
  "00000000-0000-4000-8000-000000000123": {
    "profile": "enterprise",
    "perMinute": 1500,
    "perHour": 30000
  }
}
Supported override fields:
FieldDescription
profileOptional base profile: starter, pro, business, or enterprise
perMinuteOptional custom burst cap
perHourOptional custom sustained cap

Tier Defaults By Environment

Each default profile can also be tuned through environment variables:
ProfilePer Minute EnvPer Hour Env
starterAPI_V1_RATE_LIMIT_STARTER_PER_MINUTEAPI_V1_RATE_LIMIT_STARTER_PER_HOUR
proAPI_V1_RATE_LIMIT_PRO_PER_MINUTEAPI_V1_RATE_LIMIT_PRO_PER_HOUR
businessAPI_V1_RATE_LIMIT_BUSINESS_PER_MINUTEAPI_V1_RATE_LIMIT_BUSINESS_PER_HOUR
enterpriseAPI_V1_RATE_LIMIT_ENTERPRISE_PER_MINUTEAPI_V1_RATE_LIMIT_ENTERPRISE_PER_HOUR
This lets operations tune a whole class of customers without changing application code.

Headers On Limit Responses

When a request is throttled, the API returns:
Retry-After: 60
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1762679700
X-RateLimit-Policy: minute
X-RateLimit-Profile: business
HeaderDescription
Retry-AfterSeconds to wait before retrying
X-RateLimit-LimitMax requests allowed in the triggered window
X-RateLimit-RemainingAlways 0 on a throttled response
X-RateLimit-ResetUnix timestamp for the current window reset
X-RateLimit-PolicyWhich policy triggered: minute or hour
X-RateLimit-ProfileResolved profile name for the organization

Throttled Response Shape

When a request exceeds the active policy, the API returns 429 Too Many Requests:
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "API per-minute burst rate limit exceeded for this organization.",
    "retryAfter": 60,
    "details": {
      "profile": "business",
      "policy": "minute",
      "limit": 500,
      "scope": "organization",
      "recommendedAction": "Honor Retry-After and retry with exponential backoff plus jitter."
    }
  }
}

Retry Guidance

1. Always honor Retry-After

If the API returns 429, wait at least the number of seconds in Retry-After before retrying.

2. Add jitter

Do not have all workers retry at the same instant. Add randomized delay on top of your backoff.
async function waitForRetry(response, attempt) {
  const retryAfter = Number(response.headers.get("Retry-After") || "1");
  const jitterMs = Math.floor(Math.random() * 500);
  const backoffMs = Math.pow(2, attempt) * 250;

  await new Promise((resolve) => {
    setTimeout(resolve, retryAfter * 1000 + backoffMs + jitterMs);
  });
}

3. Prefer batching over bursts

Use the bulk sequence execute path instead of many single-contact calls when possible.
for (const contact of contacts) {
  await executeSequence(sequenceId, {
    contacts: [contact],
  });
}

4. Treat 429s as backpressure, not as hard failures

High-volume clients should queue and retry rather than surfacing every 429 directly to end users.

Increasing Limits

Need a higher API profile for a pilot or an enterprise rollout?

Contact Sales

Enterprise customers can use per-org overrides or higher deployment defaults during rollout planning.

Next Steps

Error Handling

Learn how to handle API errors

Quick Start

Make your first API call