shiply.now

Errors

Every error code shiply.now returns, its HTTP status, what it means, and what to do next

Every error response — REST, MCP, and site-relative endpoints alike — uses the same envelope:

{ "error": { "code": "not_found", "message": "no site with that slug" } }

Site-relative endpoints (/.shiply/data/*, /.shiply/email, proxy routes) also mirror the message at the top level for older callers: { "error": { "code", "message" }, "message": "..." }. Always parse error.code — it's the stable, machine-checked field. message is human-readable and may change wording over time.

This page is the canonical reference. Every error response's code appears in one of the two tables below.

Core codes (/api/v1/*, MCP, and shared by site-relative endpoints)

These come from the shared CoreErrorCode set and apply across the whole platform — REST, MCP tool errors, and the site-relative endpoints below all reuse them alongside their own ad-hoc codes.

CodeHTTPMeaningNext action
invalid_request400Malformed body, bad path segment, or a field failed validation. Zod validation errors list every invalid field in one message, not just the first.Fix the field(s) named in message and retry.
invalid_transition409The resource exists but is in the wrong state for this action (e.g. signing an already-signed contract, archiving a closed project).GET the resource to read its current state, then retry from a valid one.
unauthorized401Missing, invalid, or revoked credentials.Authenticate: Authorization: Bearer shp_..., the device flow (POST /api/v1/auth/device/start), or persist a key to ~/.shiply/credentials. Never "sign in" — this is a machine auth path.
forbidden403Authenticated, but not allowed to do this (wrong owner, a non-public Site Data collection, etc).Use the resource owner's key, or check the resource's access policy.
not_found404Unknown slug, id, version, or path.Verify the identifier; list the parent collection to confirm it exists.
method_not_allowed405The /api/v1/* path exists but doesn't support this HTTP verb.Use one of the verbs in the Allow header (also listed in message).
conflict409The request collides with existing state (uploads incomplete, version not pending, handle already taken).Read message for what's colliding; retry with a different value or after resolving it.
payment_required402A plan limit was reached (sites/drives/handles/domains) or the feature is paid-only (analytics, password/invite-only access).Upgrade at /dashboard/plan, or reduce usage to fit the current plan.
rate_limit_exceeded429Too many requests to an /api/v1/* endpoint.Back off. A Retry-After header (seconds) is set when available.
quota_exceeded422A quantity limit was hit that isn't a plan gate (distinct from payment_required).Reduce the size/scope of the request, or free up quota first.
service_unavailable503Transient failure — email delivery, an upstream AI provider not configured, or an unhandled internal error.Retry with backoff. If it persists, it's worth reporting.

Site-relative ad-hoc codes

These are emitted only by the site-relative surfaces — Site Data (/.shiply/data/*), Agent Email capture (/.shiply/email), and Proxy routes (arbitrary paths declared in .shiply/proxy.json) — layered on top of the core codes above (invalid_request, forbidden, not_found, etc. also appear from these endpoints).

CodeHTTPMeaningNext action
rate_limited429Too many requests to a site-relative endpoint (Site Data insert, a proxy route).Back off; raise limits on a paid plan.
data_manifest_invalid400The site's .shiply/data.json manifest failed validation.Fix the manifest per message and republish.
collection_full409A Site Data collection hit its 25,000-record cap.Delete records, or write to a different collection.
method_not_allowed405Wrong HTTP verb for this site-relative endpoint.Check the documented verb — capture endpoints are POST, most reads are GET.
bad_request400Malformed site-relative request — most commonly a .. path-traversal segment in a proxy route path.Remove the offending path segment and retry.
body_too_large413Request body exceeded the 10 MB proxy-route cap.Shrink the payload.
proxy_requires_account403Proxy routes only work on an owned site.Claim the site (or publish with an API key) first.
proxy_var_missing502A ${VAR_NAME} token in .shiply/proxy.json has no matching Variable.Set it: PUT /api/v1/variables {"name","value"} (or shiply dashboard → Variables).
proxy_upstream_unreachable502The proxy route's upstream URL didn't respond.Check the upstream URL and that the service is reachable over HTTPS.
data_requires_account403Site Data only works on an owned site.Claim the site first.
email_requires_account403Agent Email capture (/.shiply/email) only works on an owned site.Claim the site first.

A note on rate_limited vs rate_limit_exceeded

This split is intentional, not drift: /api/v1/* endpoints (the owner-auth REST surface) return rate_limit_exceeded; the site-relative surfaces (/.shiply/data/*, /.shiply/email, proxy routes) return rate_limited. Both mean the same thing — too many requests, back off — check for either code if you talk to both surfaces from the same client.

Machine-readable pointers

Full field-by-field endpoint shapes: /docs/reference · /openapi.json. Agent-facing summary: /llms.txt and /llms-full.txt.