README.md

# EZConfig

Community-maintained rate limits and concurrency settings for popular APIs.

No more guessing at rate limits or risking API bans - use battle-tested defaults contributed by the community.

## Installation

```sh
gleam add ezconfig@1
```

## Usage

```gleam
import ezconfig
import gleam/option

pub fn main() {
  // Get full config for an API
  case ezconfig.get_config("api.openai.com") {
    option.Some(config) -> {
      // config.rps = 60 requests per second
      // config.max_concurrent = 10 concurrent requests
      // config.notes = "Tier 1: 60 req/min = 1 req/sec, but bursts allowed"
    }
    option.None -> {
      // Use your own defaults
    }
  }

  // Or get specific values
  let rps = ezconfig.get_rps("api.stripe.com")           // Some(100)
  let concurrent = ezconfig.get_max_concurrent("slack.com")  // Some(1)

  // Check if a domain has configuration
  let has_config = ezconfig.has_config("api.github.com")  // True

  // List all configured domains
  let domains = ezconfig.list_domains()
  // ["api.openai.com", "api.stripe.com", "api.github.com", ...]
}
```

## Integration Pattern

### With EZThrottle

When integrating with [EZThrottle](https://ezthrottle.com):

1. **Default Configuration:** Use ezconfig for initial rate limits and concurrency
2. **Runtime Override:** Response headers always take precedence

```gleam
// Example: Setting defaults from ezconfig
let domain = extract_domain(job.url)  // "api.openai.com"

// Use ezconfig defaults if available
let default_rps = case ezconfig.get_rps(domain) {
  option.Some(rps) -> rps
  option.None -> 2  // Fallback to conservative default
}

let default_concurrent = case ezconfig.get_max_concurrent(domain) {
  option.Some(max) -> max
  option.None -> 2  // Fallback to conservative default
}

// Apply to URL queue
let queue = URLQueue(
  rate_limit_ms: float.round(1000.0 /. int.to_float(default_rps)),
  max_concurrent: default_concurrent,
  ...
)

// Later: Headers override config
// X-EZTHROTTLE-RPS: 100  -> Updates rate_limit_ms
// X-EZTHROTTLE-MAX-CONCURRENT: 20  -> Updates max_concurrent
```

### Convention

**Priority (highest to lowest):**

1. **Response Headers** - APIs can dynamically tune their own limits
   - `X-EZTHROTTLE-RPS: 100`
   - `X-EZTHROTTLE-MAX-CONCURRENT: 20`
2. **EZConfig Defaults** - Community-verified safe values
3. **System Defaults** - Conservative fallback (2 RPS, 2 concurrent)

This allows:
- **Safe defaults** out of the box (via ezconfig)
- **Dynamic tuning** by API providers (via headers)
- **Community contributions** for better defaults (via PRs)

## Configured APIs

Currently includes rate limit configurations for:

- **AI/LLM:** OpenAI, Anthropic (Claude)
- **Payments:** Stripe
- **Dev Tools:** GitHub
- **Social:** Twitter, Facebook, Discord
- **Communication:** Slack, SendGrid, Twilio
- **Business:** HubSpot, Notion, Airtable, Shopify
- **More:** Google APIs

See the full list in [src/ezconfig.gleam](src/ezconfig.gleam).

## Contributing

Want to add or update an API configuration?

1. Fork this repo
2. Update the `api_configs()` dict in `src/ezconfig.gleam`
3. Submit a PR with your changes

Please include links to official rate limit documentation in your PR.

## License

MIT

---

Built for [EZThrottle](https://ezthrottle.com) - Distributed async job execution with built-in rate limiting.