4xx for a problem with the request or account, 5xx for a problem on Dataville’s side or with an upstream source. Every error body includes a human-readable message that is safe to show to a user. Data-source failures also include a stable data.code for clients to branch on.
Errors are never billed. Credit is deducted only after results are returned, and a download that fails part-way is refunded. Error responses do not count toward the anonymous request limit.
Error format
Data lookups (GET /{source}/{keywords}) return errors in the same envelope as results:
data.code is present on upstream and internal failures. Validation errors on these routes (an unsupported source, no results) use the same envelope without a code.
Export, SQL, and connected-sheet routes return a flat shape:
data.code or error where present.
Data source errors
These codes appear indata.code on data lookups. The UPSTREAM_* codes come from sources Dataville fetches live: Wikipedia, arXiv, Stack Exchange, PyPI, and OpenAlex. Sources served from Dataville’s own database fail as INTERNAL_ERROR or return a 404.
UPSTREAM_RATE_LIMITED is the only error that sets a Retry-After header (in seconds, only when the source said how long to wait). Its message tells the caller it is not a limit on their account:
Validation errors (400)
The message states what to fix. On data lookups it is indata.error; elsewhere it is the flat shape. An unsupported source name returns the full list of valid names and aliases in the message.
POST /api/v1/query accepts SELECT statements only. The validator rejects CREATE, DROP, ALTER, INSERT, UPDATE, DELETE, MERGE, TRUNCATE, COPY, ATTACH, DETACH, INSTALL, LOAD, EXPORT DATABASE, IMPORT DATABASE, read_csv, read_parquet, read_json, read_ndjson, GLOB, and postgres_scan with Disallowed operation: {OP}. Matching is textual, so these words are rejected inside string literals too.
LIMIT is not validated. Queries are capped at 1,000 rows and the sql_executed field in the response shows the query that ran.
Authentication errors (401)
Routes that require a key return 401 when none is sent. Export and SQL routes use the flat shape:account_state in the response. "anonymous" means the key was not accepted. See Create an API key.
Insufficient credit (402)
Returned when your credit balance can’t cover the request. Nothing is charged.X-Credits-Remaining on successful responses shows the balance falling. See Usage limits.
Access errors (403 and 404)
These mean the thing you asked for doesn’t exist or isn’t yours.Timeouts (408)
SQL queries and sheet searches are limited to 30 seconds:WHERE clause, or a lower LIMIT. Nothing is billed.
Rate limit errors (429)
Three limits produce a 429, each with a different body. The limits themselves are on Usage limits. Anonymous request limit (50 per 24 hours per IP):RateLimit-* headers and Retry-After.
Burst limit (100 per 15 minutes per IP) returns a plain-text body, not JSON: Too many requests from this IP, please try again after 15 minutes.
Back off until Retry-After or the window resets, and send an API key. The anonymous limit is the one you will hit first.
Server errors (5xx)
Unexpected failures return 500 with{ "error": { "message": "Internal Server Error" } }, or the INTERNAL_ERROR envelope on data lookups. 502 and 503 are upstream-source problems covered by the codes above. Retry with exponential backoff. If a 500 persists, email support@dataville.com with the request path and time.
Stale results are not errors
When arXiv is down and Dataville holds a stored copy of the result, the request succeeds with a 200 and astale notice inside data:
cached_at is null when the copy’s age isn’t known. Stale responses are billed normally. If no stored copy matches, you receive the UPSTREAM_* error instead.
MCP errors
The MCP endpoint reports errors at two levels:- Tool errors are the common case.
search_datavillereturns a tool result withisError: trueand a plain-text message mirroring the REST errors: unsupported source, with the valid names listed, no results, insufficient credit, orSearch failed for {source}: {reason}. These arrive as HTTP 200. - HTTP errors come from the endpoint itself, which is stateless and POST-only.
GETorDELETE /mcpreturns 405. Rate limiting returns the same 429 bodies as the REST routes, not a JSON-RPC envelope.
/mcp endpoint has no authentication error. With no key, or with an invalid one, the connection runs on the anonymous allowance and its limit of 50 requests per 24 hours.