Skip to main content
The Workspace API runs read-only SQL with JSON in and JSON out. You do not need a Flight SQL client. These operations suit scripts, serverless functions, and AI agents that read Provider data. Each result fits in a fixed size, so a script or a model can read every response whole. The API Reference has the full request and response of each operation.

Before you start

Send the two headers that every Workspace API request sends (see Authentication):
  • Authorization: Bearer <token>, with a Parable token or an MCP token. These operations only read, so an MCP token works. The API refuses a SQL token.
  • X-Tenant: <workspace-slug>.
An MCP token works only while the Workspace allows external agents. People who manage sign-in turn on Allow external agents in Protection → Access Tokens. While it is off, the API refuses every MCP token with 403 and WA-PAT-006. The token’s owner needs a role with one of these permissions: The examples on this page use three variables. Set PARABLE_API_TOKEN to a Parable token or an MCP token, not to a SQL token:

What these operations read

These operations read only the Provider Pools: providers, providers_quarantine, and providers_quality. A statement that names another pool, such as workspace.users, fails with 400 and Query references an unknown relation (QL-PL-002). To read the artifacts, parables, or workspace pools, use Flight SQL, or Arrow over HTTP with a Parable token. Provider Policies and source permissions narrow the rows of every statement for every person, holders of All data access included. A script that runs with a Workspace Administrator’s token reads only what the Policies give that administrator’s roles. To read every row as a holder of All data access, use Flight SQL with a SQL token. Rows you can read explains both.

Walk through a query

1. Find the table

Describe the data in plain words. scope narrows the search to a pool, a Provider, or a table, with the same patterns as search_available_data:
Response (shortened)
Use tableRef in FROM and columnName in SELECT. score ranks the results of one search. Compare it only within that search. matchedBy says whether the words (keyword), the meaning (semantic), or both matched. A search ranks at most 500 results. Page through them with offset. To list tables instead of searching, send an empty query or *. With no scope, the listing returns each Provider and its table count in providers. With a scope such as providers.google, it returns that Provider’s tables. A listing page holds up to 100 tables or 40,000 characters. When there are more, send nextCursor back as cursor.

2. Describe the table

Response (shortened)
tableRef is the exact name pool.schema.table. A name that the catalog does not list returns 404 with Pool table not found. A field with no Parable scalar has no scalarRef. system: true marks a column that Parable adds, such as the state columns. Other fields are not shown. They are the same as in the catalog.

3. Plan the query

plan checks a statement against the catalog and your access, and returns the columns that it would return. It runs nothing and reads no rows:
Response (shortened)
When Parable refuses a statement for a reason that you can correct, plan still answers 200. planned is false, and refusal has the error code and a message that says what to change:

4. Run the query

query takes the same body as plan:
Response (shortened)
Each row is a JSON array in the order of columns. arrowType says how to read a value that arrives as text, such as a timestamp. Some values change form so that JSON carries them exactly:
  • A 64-bit integer outside ±(253 − 1), and every decimal, is a string.
  • Binary data is base64 text.
  • NaN and infinities are strings.

Bind parameters

Write $1, $2, and so on in the SQL, and send the values in parameters in the same order. Each value is a JSON string, number, boolean, or null. Bind every value that comes from a person or a program. Do not build it into the SQL text.

See how Parable runs a statement

Send EXPLAIN followed by a query to query. It returns two rows, logical_plan and physical_plan, in the columns plan_type and plan, and runs nothing. The plan explains what the plan shows.

Results that are cut

A result is never larger than these limits. When a result reaches one, Parable cuts it and says so. It never changes a value without saying so. warnings says the same in plain sentences. A LIMIT in your SQL is the best way to keep the whole result.

Limits

Errors

Errors use the Problem Details format with a code, as described in the API Reference.

Read the query guidance

GET /api/provider-pool/guidance returns the guidance that Parable’s own agents read before they write SQL for these tables: how to find tables, read Provider data, and write Plots. Each text has a name, a title, a description, and Markdown content. version changes when the text changes. The guidance is the same in every Workspace. Give it to your own agent as context.

Check a query before you run it

POST /api/parables/immediate-plot-query/actions/estimate is a dry run. It plans a statement exactly as running it would, and runs nothing. It tells you how much data the statement reads, what that costs, and how many paid AI calls it can make. It needs a Parable token. It refuses an MCP token with 403 and WA-PAT-005. The owner needs tenant.view or tenant.data.query.providers. The statement can read every pool that the owner’s role can query, as over Flight SQL.
Response (shortened)
The dry run refuses what running the statement would refuse, with the same codes. It never refuses a statement for its size.

Arrow over HTTP, for every pool

POST /api/parables/immediate-plot-query runs one statement and returns its rows as an Arrow IPC stream (application/vnd.apache.arrow.stream). It takes the same body as the dry run. Use it when you need Arrow, or a pool other than the Provider Pools, without a Flight SQL client.
  • It needs a Parable token. It refuses an MCP token and a SQL token.
  • It reads every pool that the owner’s role can query, under the same rules as Flight SQL. All data access applies.
  • It stops a query after 30 seconds. Write a LIMIT: it caps no rows itself.
  • The body is complete only when it ends with the Arrow end-of-stream marker. A body that ends without it failed. A refusal is a Problem Details error with the same codes as on this page.
Read the file with any Arrow IPC stream reader, such as pyarrow.ipc.open_stream.