Sume rate limit scope: /v1 and MCP count, OPTIONS preflights do not

The Sume limiter covers /v1 paths and the MCP route. CORS OPTIONS preflights are exempt, and reads and writes use separate buckets. What that means.

4 min readSume
All posts

Not every request to api.sume.com spends from your rate limit. In the API source the limiter applies to paths that start with /v1/ and to the MCP route. An OPTIONS request is exempt, whatever the path. Knowing the boundary stops you from counting requests that cost nothing, and from expecting protection on requests that do count.

What is counted

Request types and the Sume rate limiter (read 2026-10-04)
RequestCountedBucket
GET or HEAD under /v1/yesread
POST, PUT, PATCH or DELETE under /v1/yeswrite
POST /v1/generation/admission-previewyesread
POST to the MCP endpointyesread
OPTIONS to any pathnonone

Browsers and preflight

A browser sends an OPTIONS preflight before a cross-origin request that carries a custom header such as x-api-key. Those preflights do not spend from the bucket, so a page that makes 100 calls does not make 200 requests against the budget. The CORS configuration exposes ratelimit-limit, ratelimit-remaining, ratelimit-reset, retry-after and x-sume-poll-after to the page, so client JavaScript can read them. Do not ship an API key to a browser, though. Call the API from your server.

Reads and writes

The two buckets are separate. A read is any GET or HEAD, plus the two POSTs that submit nothing. Everything else is a write. Reads get forty times the plan's write number, so a Free key has 120 writes and 4800 reads a minute.

Count with the headers

The simplest proof is to read the header on two calls. An OPTIONS call leaves ratelimit-remaining unchanged on the next real request, apart from your own other traffic.

import os, urllib.request

def remaining():
    req = urllib.request.Request("https://api.sume.com/v1/me", headers={"x-api-key": os.environ["SUME_API_KEY"]})
    with urllib.request.urlopen(req, timeout=15) as resp:
        return int(resp.headers["ratelimit-remaining"])

before = remaining()
opts = urllib.request.Request("https://api.sume.com/v1/me", method="OPTIONS",
                              headers={"Origin": "https://example.com", "Access-Control-Request-Method": "GET"})
urllib.request.urlopen(opts, timeout=15).read()
print("spent by OPTIONS + next GET:", before - remaining())  # 1, the GET only

Practical rule

Budget by the plan number, pace writes, and let reads be cheap. Do not try to avoid preflights to save budget, because they were never charged.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume