Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.userepo.com/llms.txt

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

All errors are returned as JSON with a top-level error field — plus structured fields when they help.
{ "error": "Human-readable message" }

Status code catalog

CodeMeaningWhen
200OKSuccessful read or idempotent write
201CreatedNew resource created (key, request, sync run)
202AcceptedAsync work queued (sync run)
204No ContentSuccessful CORS preflight
302FoundOAuth redirect to provider
400Bad RequestValidation failed, missing params, malformed OAuth state
401UnauthorizedMissing or invalid bearer token
402Payment RequiredNo active subscription (paywalled tiers only)
403ForbiddenAuthenticated but lacking the required scope, role, or tier limit
404Not FoundResource doesn’t exist or you don’t have access to see it
409Conflicte.g. revoking the key currently in use
429Too Many RequestsRate limit OR credit budget exceeded
500Internal Server ErrorRepo bug or DB failure — file a report
502Bad GatewayUpstream OAuth provider or LLM error
503Service UnavailableA required service isn’t configured (e.g. Stripe in dev)

Common error shapes

Quota exceeded (Builder tier)

{
  "error": "quota_exceeded",
  "message": "This organization has used its monthly credit budget (5,000). Upgrade in /console/billing to continue.",
  "tier": "builder",
  "creditsUsed": 5000,
  "creditsIncluded": 5000
}
Builder tier hard-blocks at the cap. Upgrade to Studio (overage allowed) or wait for the next billing cycle.

Rate limit exceeded

{
  "error": "Rate limit exceeded",
  "action": "search",
  "limit": 60,
  "retryAfterSeconds": 47,
  "resetAt": "2026-05-30T20:15:00Z"
}
Plus headers:
Retry-After: 47
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-05-30T20:15:00Z
Honor Retry-After — back off with jitter rather than hammering.

Subscription inactive

{
  "error": "subscription_inactive",
  "message": "This organization does not have an active subscription. Visit /console/billing to subscribe."
}
Sent on 402 when an org’s subscription is canceled, unpaid, or incomplete_expired. Internal/enterprise tiers never see this.

Tier limit reached (agent/connector)

{
  "error": "agent_limit_reached",
  "message": "Your builder plan allows 2 agents. Upgrade to add more.",
  "tier": "builder",
  "limit": 2,
  "current": 2
}
Same shape for connector_limit_reached.

Invalid OAuth state

{ "error": "OAuth state expired" }
Possible reasons: state was issued more than 10 minutes ago, was tampered with, was issued for a different provider, or was forged. Restart the OAuth flow from the console.

Provider errors (502)

{ "error": "OAuth exchange failed: invalid_grant" }
These pass through the upstream provider’s error message when available. Common causes: revoked tokens, expired refresh tokens, provider API downtime.

Idempotency

/v1/ingest is idempotent on (organizationId, provider, externalId) — re-posting the same document is a no-op (counted in skipped). /v1/sync-runs enforces “at most one active run per connector” at the DB level — duplicate queue attempts return the existing run with alreadyActive: true. Other endpoints (/v1/search, /v1/context, /v1/ask) are not idempotent — each call consumes a credit. If you retry, you’ll burn an extra credit.