forbidden
Authenticated, but the workspace does not have access to this resource or feature.
HTTP 403The request was authenticated, but not allowed.
When it fires
The request was authenticated, but the workspace is not entitled to call this endpoint. Common reasons:
- Calling a market-intelligence endpoint (
/v1/markets,/v1/markets/{city}/calendar) on a plan that does not include market data. - Calling an AI-tier endpoint with a free-tier key.
- Trying to write to a channel the workspace has not connected (
/v1/channels/{provider}/…with no active connection — note that some of these surface asno_connectioninstead). - The API key was scoped to read-only and the request is a write.
Response shape
Every Repull error follows the same envelope. The code is stable and safe to switch on.
{
"error": {
"code": "forbidden",
"message": "<human-readable explanation of what went wrong>",
"docs_url": "https://repull.dev/docs/errors/forbidden"
}
}How to fix
- Read the `message` field — it tells you exactly which capability is missing.
- Open /dashboard/usage to confirm which tier the workspace is on.
- If the missing capability is a paid add-on (markets, AI), upgrade the workspace from /dashboard/billing.
- If you are sure the workspace should have access, double-check you are using the right key — keys are workspace-scoped.
- For channel write endpoints, verify the connection is active in /dashboard/channels first.
Common gotchas
forbiddenis distinct fromunauthorized. The key is valid; it just does not have permission. Retrying with the same key will keep failing.- Some entitlement gates only check on the first request of a billing cycle. If you upgraded mid-cycle and are still seeing the error, the next call should succeed once the entitlement cache refreshes (under a minute).
Examples
curl
# Free-tier key calling a markets endpoint
curl https://api.repull.dev/v1/markets/london \
-H "Authorization: Bearer sk_test_FREE_TIER_KEY"
# {
# "error": {
# "code": "forbidden",
# "message": "Markets data requires the Atlas add-on. Upgrade at /dashboard/billing."
# }
# }TypeScript
import { Repull } from '@repull/sdk'
const repull = new Repull({ apiKey: process.env.REPULL_KEY! })
try {
await repull.markets.get('london')
} catch (err: any) {
if (err.code === 'forbidden') {
// Don't retry — surface the entitlement gap to the user
console.error('Plan upgrade required:', err.message)
return { needsUpgrade: true, reason: err.message }
}
throw err
}If you're an AI agent
The user's plan does not include the feature you tried to call. Do not retry. Read err.message and tell the user which add-on or upgrade they need, then offer them /dashboard/billing as the next step.
Related
- Error reference — the full table of error codes
- Using Repull from AI agents — patterns for handling errors in agent loops
- AI Pricing & plans
- Markets data
Hit an error that isn't covered? Email hello@repull.dev with the request id from the response headers.
AI