listings_limit_exceeded
The workspace has more active listings than its plan allows. DELETE listings or upgrade to clear.
When it fires
The workspace's active-listing count is above the cap for its plan. Repull enforces a hard per-tier cap on how many listings a workspace can keep active at one time. When you exceed it, the API short-circuits every request that would create or operate on listings until you drop back under the cap or upgrade.
The cap by tier:
| Tier | Active listings cap |
|---|---|
free | 5 |
starter | 50 |
custom | unlimited |
The error envelope tells you exactly where you stand: tier is the current plan, limit is the cap, and active_listings is the live count.
Response shape
Every Repull error follows the same envelope. The code is stable and safe to switch on.
{
"error": {
"code": "listings_limit_exceeded",
"message": "Your account has 24 active listings but the 'free' tier is capped at 5...",
"fix": "Either reduce your active listings to 5 or fewer (via DELETE endpoints — these are still served), or upgrade your plan at https://repull.dev/dashboard/billing to lift the cap immediately.",
"docs_url": "https://repull.dev/docs/errors/listings_limit_exceeded",
"tier": "free",
"limit": 5,
"active_listings": 24,
"upgrade_url": "https://repull.dev/dashboard/billing",
"request_id": "req_01HXY..."
}
}How to fix
- Read `error.tier`, `error.limit`, and `error.active_listings` — they give you the exact gap you need to close.
- Path A — trim listings: call `DELETE /v1/listings/{id}` until `active_listings <= limit`. DELETE is on the allowlist and continues to work over-cap, so you can self-recover without paying.
- Path B — upgrade: send the operator to `https://repull.dev/dashboard/billing` (also surfaced as `error.upgrade_url`). The server-side usage cache is 60 seconds, so the first 200 response after upgrade may take up to a minute.
- While over-cap, `/v1/health` and `/v1/usage/*` continue to return 200 — use them to render the over-cap state on a dashboard without hitting the 402 wall.
- Do NOT implement a retry loop on 402. Unlike 429, this is not a transient condition — no `Retry-After` is set and there is nothing to wait for. The status only clears via DELETE or an upgrade.
Common gotchas
- 402 ≠ 429. Both block traffic, but 402 has no
Retry-Afterheader. SDK retry/backoff middleware that ignores the status code and just sleeps on any error will spin forever. Switch onerror.codeand short-circuitlistings_limit_exceededto a human-visible upgrade prompt instead of retrying. - DELETE is always served. The gate explicitly allowlists any
DELETEmethod so customers can never get stuck — they can always trim listings without paying./v1/healthand/v1/usage/*are also allowlisted. - Post-upgrade is not instant. The active-listings count is cached for 60 seconds. If you upgrade and immediately retry, you may see one more 402 before the first 200. Wait a minute or backoff once before declaring the upgrade failed.
- The cap is on active listings. Listings that are deleted, archived, or otherwise inactive do not count. The full set of states that count is defined by the API; check
/v1/usage/listingsfor the canonical number. - The `custom` tier is uncapped, so this error is never returned to
customworkspaces.
Examples
curl
# Over-cap free-tier workspace calling any non-DELETE endpoint
curl https://api.repull.dev/v1/listings \
-H "Authorization: Bearer sk_test_FREE_TIER_KEY"
# HTTP/1.1 402 Payment Required
# {
# "error": {
# "code": "listings_limit_exceeded",
# "message": "Your account has 24 active listings but the 'free' tier is capped at 5...",
# "fix": "Either reduce your active listings to 5 or fewer (via DELETE endpoints — these are still served), or upgrade your plan at https://repull.dev/dashboard/billing to lift the cap immediately.",
# "docs_url": "https://repull.dev/docs/errors/listings_limit_exceeded",
# "tier": "free",
# "limit": 5,
# "active_listings": 24,
# "upgrade_url": "https://repull.dev/dashboard/billing",
# "request_id": "req_01HXY..."
# }
# }
# Recovery path A — trim listings (DELETE is allowlisted, still 200s)
curl -X DELETE https://api.repull.dev/v1/listings/listing_123 \
-H "Authorization: Bearer sk_test_FREE_TIER_KEY"
# Recovery path B — upgrade and wait for the 60s usage cache to refresh
open https://repull.dev/dashboard/billing
# … wait ~60s …
curl https://api.repull.dev/v1/listings \
-H "Authorization: Bearer sk_test_FREE_TIER_KEY"
# HTTP/1.1 200 OK
# Allowlist — these continue to work over-cap
curl https://api.repull.dev/v1/health -H "Authorization: Bearer ..." # 200
curl https://api.repull.dev/v1/usage/listings -H "Authorization: Bearer ..." # 200TypeScript
import { Repull } from '@repull/sdk'
const repull = new Repull({ apiKey: process.env.REPULL_KEY! })
try {
await repull.listings.list()
} catch (err: any) {
if (err.code === 'listings_limit_exceeded') {
// 402 — NOT a "wait and retry" condition. Do not back off.
// Two paths back to 200:
// 1. DELETE listings until active_listings <= limit
// 2. Upgrade at err.upgrade_url
console.error(
`Over plan cap: ${err.active_listings} active / ${err.limit} on the '${err.tier}' tier.`,
)
if (err.active_listings - err.limit < 5) {
// Path A — trim a few listings (DELETE is allowlisted)
const overflow = err.active_listings - err.limit
const listings = await repull.usage.listings() // /v1/usage/* is allowlisted
for (const id of listings.lowest_priority.slice(0, overflow)) {
await repull.listings.delete(id)
}
} else {
// Path B — surface the upgrade URL to the operator
return { needsUpgrade: true, upgradeUrl: err.upgrade_url, message: err.message }
}
} else {
throw err
}
}If you're an AI agent
The workspace is over its plan's active-listings cap. STOP. This is NOT a rate-limit-style transient error — there is no Retry-After and nothing to wait for. Tell the user err.message verbatim, then offer two paths: (a) DELETE listings until active_listings <= limit (DELETE is still served over-cap), or (b) upgrade at err.upgrade_url. After an upgrade, wait ~60s before the next call to let the server-side usage cache refresh. Never retry in a loop.
Related
- Error reference — the full table of error codes
- Using Repull from AI agents — patterns for handling errors in agent loops
- AI Pricing & plans
- Credits and usage
- Rate Limits
- rate_limited (429) — the wait-and-retry sibling
Hit an error that isn't covered? Email hello@repull.dev with the request id from the response headers.