JSON-RPC API Reference
Triggerware communicates via JSON-RPC 2.0 over TCP (newline-delimited). Every request and response follows the JSON-RPC specification with the following Triggerware-specific extensions:
- An optional
"asynchronous"boolean member may be added to any request. Whentrue, the server spawns a new thread to handle the request. All documented methods default to asynchronous. - Batch requests are not supported.
- Parse errors close the connection (logged to the JSON-RPC log file).
- Handles (integer IDs referencing server-side objects) are scoped to a single TCP connection and are not valid on other connections.
Common Parameter Types
Section titled “Common Parameter Types”These parameter names recur across many methods and always carry the same meaning.
| Name | Type | Description |
|---|---|---|
handle | integer | Server-created ID referencing an internal object (result set, prepared query, polled query). Connection-scoped. |
query | string | An SQL or FOL query string. |
language | string | "sql" or "fol". Defaultable via set-global-default. |
namespace | string | Schema (SQL) or Lisp package (FOL) name. Defaultable via set-global-default. |
limit | integer | null | Maximum number of result tuples. null or omitted means no limit. |
timelimit | number | null | Maximum seconds to spend searching. Floating-point allowed. null or omitted means no limit. |
check-update | boolean | If true (default), verifies that no updates to relevant relations have occurred since the result set was created. FOL-specific. |
method | string | The JSON-RPC method name to use in later notifications sent back to the client. |
Common Response Types
Section titled “Common Response Types”Signature
Section titled “Signature”A sequence of objects describing the shape of output (or input) tuples.
[ { "attribute": "year", "type": "SMALLINT" }, { "attribute": "factor", "type": "FLOAT" }]An object describing a (possibly partial) set of query results.
{ "count": 2, "tuples": [ [ 1980, 1.64 ], [ 1990, 2.31 ] ], "exhausted": true}count— Number of tuples in this batch.tuples(optional) — Array of result tuples. Omitted when count is 0.exhausted(optional) —trueif no more tuples exist. Absent (notfalse) when more may remain.
Server Configuration
Section titled “Server Configuration”set-global-default
Section titled “set-global-default”Sets defaults that affect all connections. Effects persist until the server restarts or another call changes them.
Params: object with any subset of:
| Member | Type | Description |
|---|---|---|
sql-mode | string | "case-insensitive" (default), "case-sensitive", or "case-sensitive-preferred" |
language | string | "sql" or "fol" — default language for future requests |
fol-namespace | string | Default namespace when language is "fol" |
sql-namespace | string | Default namespace when language is "sql" |
{ "jsonrpc": "2.0", "id": 1, "method": "set-global-default", "params": { "sql-mode": "case-insensitive", "sql-namespace": "DEMO" }}Query Execution
Section titled “Query Execution”execute-query
Section titled “execute-query”The simplest way to run a query and retrieve results. Returns a signature, an initial batch of tuples, and (if not exhausted) a handle for fetching more.
Params: object
| Member | Required | Description |
|---|---|---|
query | yes | SQL or FOL query string |
language | no | "sql" or "fol" |
namespace | no | Schema or package name |
limit | no | Max tuples to return (0 creates a result set without fetching) |
timelimit | no | Max seconds to search |
check-update | no | Boolean, default true (FOL only) |
Response result:
{ "signature": [ { "attribute": "X", "type": "" }, { "attribute": "Y", "type": "" } ], "batch": { "count": 2, "tuples": [ [ "value1" ], [ "value2" ] ] }, "handle": 1}signature— Describes the output columns.batch— Initial set of tuples.handle— Present only if the batch is not exhausted. Use withnext-resultset-batchornext-resultset-incremental.
Example — FOL query with limit:
{ "jsonrpc": "2.0", "id": 1, "method": "execute-query", "params": { "query": "select * from x_posts_by_user where username='alice'", "schema": "DEMO", "limit": 2 }}prepare-query
Section titled “prepare-query”Parses and prepares a parameterized query without executing it. Returns a handle used with create-resultset to supply inputs and execute.
Params: object
| Member | Required | Description |
|---|---|---|
query | yes | SQL or FOL query string (may contain parameters) |
language | no | "sql" or "fol" |
namespace | no | Schema or package name |
check-update | no | Boolean, default true |
parameter-types | no | Array or object declaring static types for query parameters (SQL only) |
SQL queries support two parameter styles (cannot be mixed in the same query):
- Named:
:year,:y1,:y2 - Positional:
?,?1,?2
FOL parameters are simply free variables not in the output list and not bound by a quantifier.
Response result:
{ "handle": 2, "inputSignature": [ { "attribute": "?Y1", "type": "SMALLINT" }, { "attribute": "?Y2", "type": "SMALLINT" } ], "signature": [ { "attribute": "FACTOR", "type": "FLOAT" } ], "usesNamedParameters": true}Example:
{ "jsonrpc": "2.0", "id": 1, "method": "prepare-query", "params": { "query": "SELECT factor FROM inflation WHERE year1 = :y1 AND year2 = :y2" }}release-query
Section titled “release-query”Releases server resources held by a prepared query. Existing result sets created from it remain usable.
Params: array of [handle]
{ "jsonrpc": "2.0", "id": 1, "method": "release-query", "params": [ 2 ]}create-resultset
Section titled “create-resultset”Executes a prepared query with the given inputs. Returns the same structure as execute-query.
Params: object
| Member | Required | Description |
|---|---|---|
handle | yes | Handle from prepare-query |
inputs | no | Array of input values matching the inputSignature order. Default: [] |
limit | no | Max tuples to return |
timelimit | no | Max seconds to search |
check-update | no | If false, overrides true from prepare-query. Cannot upgrade false to true. |
Example:
{ "jsonrpc": "2.0", "id": 1, "method": "create-resultset", "params": { "handle": 2, "inputs": [ 1980, 1990 ], "limit": 0 }}Response:
{ "jsonrpc": "2.0", "id": 1, "result": { "batch": { "count": 0 }, "handle": 3 }}next-resultset-batch
Section titled “next-resultset-batch”Fetches the next batch of tuples from an existing result set. The result set auto-closes when exhausted.
Params: array of [handle, limit?, timelimit?]
handle— Result set handle.limit— Must be a positive integer (not 0).timelimit— Optional seconds.
Example:
{ "jsonrpc": "2.0", "id": 1, "method": "next-resultset-batch", "params": [ 3, 1 ]}Response:
{ "jsonrpc": "2.0", "id": 1, "result": { "count": 1, "tuples": [ [ 1.64 ] ] }}If the batch includes "exhausted": true, the result set is automatically closed.
next-resultset-incremental
Section titled “next-resultset-incremental”Streams results via JSON-RPC notifications instead of returning them in a single batch. The response itself is just an acknowledgment.
Params: object
| Member | Required | Description |
|---|---|---|
handle | yes | Result set handle |
method | no | Notification method name. Default: "resultset-incremental-notification" |
limit (or count) | no | Max total tuples across all notifications |
timelimit | no | Max seconds for the entire operation |
notify-limit | no | Send a notification when this many tuples are pending (positive integer) |
notify-timelimit | no | Max seconds to wait after finding a tuple before sending it (number) |
Request:
{ "jsonrpc": "2.0", "id": 1, "method": "next-resultset-incremental", "params": { "handle": 1, "limit": 10, "notify-limit": 3, "timelimit": 30, "notify-timelimit": 5 }}Response (acknowledgment only):
{ "jsonrpc": "2.0", "id": 1, "result": null}Intermediate notifications:
{ "jsonrpc": "2.0", "method": "resultset-incremental-notification", "params": { "handle": 1, "count": 3, "tuples": [ [ "a", 0 ], [ "a", 1 ], [ "a", 2 ] ] }}Final notification (identified by the presence of total-count):
{ "jsonrpc": "2.0", "method": "resultset-incremental-notification", "params": { "handle": 1, "count": 1, "total-count": 8, "exhausted": false, "tuples": [ [ "a", 7 ] ] }}Error notification (result set is closed after this):
{ "jsonrpc": "2.0", "method": "resultset-incremental-notification", "params": { "handle": 1, "error": { "code": -7, "message": "state has changed" } }}close-resultset
Section titled “close-resultset”Releases server resources for a result set. Not required if the result set has already reported "exhausted": true.
Params: array of [handle]
{ "jsonrpc": "2.0", "id": 1, "method": "close-resultset", "params": [ 1 ]}Subscriptions (FOL / Non-SQL)
Section titled “Subscriptions (FOL / Non-SQL)”subscribe
Section titled “subscribe”Registers for change notifications using a two-state query. When a database transition matches the query, the server sends a notification on the same connection.
Params: object
| Member | Required | Description |
|---|---|---|
description | yes | Two-state query string |
language | no | "sql" or "fol" |
package | no | Namespace |
label | yes | String label identifying this subscription in notifications |
method | yes | Notification method name |
combine | yes | Boolean — false for one notification per tuple, true to batch with other subscriptions sharing the same method |
Example (combine = false):
{ "jsonrpc": "2.0", "id": 1, "method": "subscribe", "params": { "description": "((x y) s.t. (start (R1 x y)))", "language": "fol", "package": "AP5", "label": "r1-watcher", "method": "my-notifications", "combine": false }}Notification (combine = false):
{ "jsonrpc": "2.0", "method": "my-notifications", "params": { "update#": 17, "label": "r1-watcher", "tuple": [ 3, "foo" ] }}Notification (combine = true):
{ "jsonrpc": "2.0", "method": "my-notifications", "params": { "update#": 17, "matches": [ { "label": "r1-watcher", "tuples": [ [ 3, "foo" ], [ 4, "bar" ] ] }, { "label": "another-sub", "tuples": [ [ 3, 4, "fum" ] ] } ] }}unsubscribe
Section titled “unsubscribe”Stops notifications for a previously registered subscription. Closing the connection also unsubscribes all subscriptions.
Params: Same as subscribe.
{ "jsonrpc": "2.0", "id": 1, "method": "unsubscribe", "params": { "description": "((x y) s.t. (start (R1 x y)))", "label": "r1-watcher", "method": "my-notifications", "combine": false }}Polled Queries
Section titled “Polled Queries”create-polled-query
Section titled “create-polled-query”Creates a server object that re-runs a query on a schedule (or on demand) and reports deltas via notifications.
Params: object
| Member | Required | Description |
|---|---|---|
query | yes | SQL or FOL query string |
language | no | "sql" or "fol" |
namespace | no | Schema or package name |
method | no | Notification method name. Default: "polled-query-notification" |
schedule | no | A number (poll every N seconds), a cron-like object, or an array of schedules. Default: no automatic polling. |
report-noops | no | Boolean (default false). If true, notify even when no changes are detected. |
report-initial | no | "none" (default), "with delta", or "without delta" |
delay-schedule | no | Boolean (default false). If false, attempts an immediate initial poll. |
limit | no | Max tuples per poll operation |
timelimit | no | Max seconds per poll operation |
Schedule Formats
Section titled “Schedule Formats”Periodic — poll every N seconds:
60Cron-like — an object with time-unit fields:
{ "timezone": "America/New_York", "minutes": "0,30", "hours": "9-17", "days": "*", "months": "*", "weekdays": "1-5"}Field value syntax: "*" (all), an integer as string, "N-M" (range), or comma-separated list. Ranges: minutes 0–59, hours 0–23, days 1–31, months 1–12, weekdays 0–6 (0 = Sunday).
Combined — an array of schedules:
[ { "hours": "9", "minutes": "0" }, { "hours": "17", "minutes": "0" }]Response result:
{ "handle": 5, "signature": [ { "attribute": "NAME", "type": "CASESENSITIVE" } ]}Poll Notifications
Section titled “Poll Notifications”Success with delta:
{ "jsonrpc": "2.0", "method": "polled-query-notification", "params": { "handle": 5, "timestamp": "2025-12-06T17:37:41.000000Z", "delta": { "added": [ [ "Alice" ], [ "Bob" ] ], "deleted": [ [ "Charlie" ] ] } }}Initialization (report-initial = “with delta”):
{ "jsonrpc": "2.0", "method": "polled-query-notification", "params": { "handle": 5, "timestamp": "2025-12-06T17:37:41.000000Z", "initialized": true, "delta": { "added": [ [ "Alice" ], [ "Bob" ] ], "deleted": [] } }}Initialization (report-initial = “without delta”):
{ "jsonrpc": "2.0", "method": "polled-query-notification", "params": { "handle": 5, "timestamp": "2025-12-06T17:37:41.000000Z", "initialized": true }}Error:
{ "jsonrpc": "2.0", "method": "polled-query-notification", "params": { "handle": 5, "timestamp": "2025-12-06T17:37:41.000000Z", "error": "timelimit exceeded", "initialized": false }}poll-now
Section titled “poll-now”Triggers an immediate poll of a polled query. The result is delivered via notification (not in the response).
Params: object { "handle": <int>, "timelimit": <number>? } or array [handle, timelimit?]
{ "jsonrpc": "2.0", "id": 1, "method": "poll-now", "params": { "handle": 5 }}close-polled-query
Section titled “close-polled-query”Stops all scheduled polling and invalidates the handle. Closing the connection also closes all its polled queries.
Params: array of [handle]
{ "jsonrpc": "2.0", "id": 1, "method": "close-polled-query", "params": [ 5 ]}Virtual Table & View Definition
Section titled “Virtual Table & View Definition”create view
Section titled “create view”Defines a named virtual table from a query. Equivalent to SQL CREATE VIEW. Column names and types are derived from the query.
Method name: "create view"
Params: object
| Member | Required | Description |
|---|---|---|
name | yes | View name |
query | yes | SQL (or FOL) query string defining the view |
namespace | no | Schema for both the name and the query. Defaultable. |
{ "jsonrpc": "2.0", "id": 1, "method": "create view", "params": { "name": "high_inflation", "query": "SELECT year1, year2, factor FROM inflation WHERE factor > 2.0", "namespace": "DEMO" }}create jsonrpc table
Section titled “create jsonrpc table”Declares a virtual table backed by an external connector.
Method name: "define-external-jsonrpc-table"
Params: object
| Member | Required | Description |
|---|---|---|
name | yes | Table name |
namespace | no | Schema name (defaultable) |
host | yes | Connector hostname or IP |
port | yes | Connector TCP port |
columns | yes | Array of [name, type] pairs |
generator | yes | Array of generator descriptors |
size | no | Array of size estimate entries |
documentation | no | Description string |
Each generator descriptor:
| Member | Description |
|---|---|
inputs | Array of column names that are inputs |
name | Algorithm name passed to the connector |
cost | Estimated cost of generating all outputs for a given input |
Each size entry is [[column_names], estimate].
{ "jsonrpc": "2.0", "id": 1, "method": "define-external-jsonrpc-table", "params": { "name": "orders", "namespace": "DEMO", "host": "localhost", "port": 12345, "columns": [ { "name": "productid", "type": "StringCase" }, { "name": "arrival", "type": "Date" }, { "name": "price", "type": "integer" } ], "generator": [ { "inputs": [ "productid" ], "name": "gen_from_product", "cost": 100 }, { "inputs": [ "productid", "arrival" ], "name": "gen_from_product_arrival", "cost": 10 } ], "size": [ [ [ "productid" ], 10 ], [ [ "productid", "arrival" ], 1 ] ] }}create jsonrpc function
Section titled “create jsonrpc function”Declares a virtual function backed by an external connector. Similar to create jsonrpc table but simplified: only one generator (all columns except the last are inputs, the last is the output), and no size estimates are needed.
Method name: "define-external-jsonrpc-function"
Params: object
| Member | Required | Description |
|---|---|---|
name | yes | Function name |
namespace | no | Schema name |
host | yes | Connector hostname or IP |
port | yes | Connector TCP port |
inputtypes | yes | Array of type strings for the input arguments |
outputtype | yes | Type string for the return value |
cost | yes | Estimated cost |
{ "jsonrpc": "2.0", "id": 1, "method": "define-external-jsonrpc-function", "params": { "name": "compute_score", "namespace": "DEMO", "host": "127.0.0.1", "port": 8080, "inputtypes": [ "int", "casesensitive" ], "outputtype": "int", "cost": 1000 }}Removes a relation / SQL table / SQL function from the server. Also decaches it from the SQL translator.
Params: object
| Member | Required | Description |
|---|---|---|
name | yes | Name of the relation to drop |
schema | yes | Schema name |
{ "jsonrpc": "2.0", "id": 1, "method": "drop", "params": { "name": "orders", "schema": "DEMO" }}define-relation
Section titled “define-relation”General-purpose method for defining virtual tables. Accepts the full set of parameters supported by the underlying defrelation mechanism.
Params: object — any subset of:
| Member | Type | Description |
|---|---|---|
name | string | Relation name. Can include schema prefix ("demo::rel1") |
schema | string | Schema name (combined with name if present) |
arity | integer | Number of columns |
argnames | string[] | Column names |
types | string[] | Type names (e.g., "sql-int", "sql-casesensitive") |
size | array | Size estimates: alternating IO patterns and numbers |
documentation | string | Description |
representation | string | array | Storage format: "base", "tree", ["partial-index", 0, 2], etc. |
derivation | string | array | object | How data is derived: ["sql-definition", "SELECT ..."], ["fol-definition", "..."], or an external-jsonrpc object |
computation | same as derivation | Same options — implies the data never changes |
{ "jsonrpc": "2.0", "id": 1, "method": "define-relation", "params": { "name": "r1", "schema": "DEMO", "derivation": [ "sql-definition", "SELECT code FROM ag_code_index" ] }}create-sql-schema
Section titled “create-sql-schema”Creates a new SQL schema (namespace).
Params: string — the schema name.
{ "jsonrpc": "2.0", "id": 1, "method": "create-sql-schema", "params": "MY_SCHEMA"}Connector Management
Section titled “Connector Management”activate-connector
Section titled “activate-connector”Loads and activates a named connector. Looks for a connector definition file (.lisp or .py) in the configured connectors directory.
Params: object
| Member | Required | Description |
|---|---|---|
name | yes | Connector name (matches filename in connectors directory) |
json_data | no | Arbitrary JSON data passed to the connector on load |
{ "jsonrpc": "2.0", "id": 1, "method": "activate-connector", "params": { "name": "salesforce", "json_data": { "api_key": "..." } }}deactivate-connector
Section titled “deactivate-connector”Removes a connector and drops its associated relation.
Params: object
| Member | Required | Description |
|---|---|---|
name | yes | Connector name |
{ "jsonrpc": "2.0", "id": 1, "method": "deactivate-connector", "params": { "name": "salesforce" }}Utility Methods
Section titled “Utility Methods”Does nothing. Useful for performance testing and connection keep-alive.
Params: array of [] (empty)
{ "jsonrpc": "2.0", "id": 1, "method": "noop", "params": []}Response:
{ "jsonrpc": "2.0", "id": 1, "result": null}runtime
Section titled “runtime”Returns server runtime statistics. Available on CLISP builds.
Params: array of [] (empty)
Response result: array of [run_time, gc_time, bytes_allocated] (internal time units).
{ "jsonrpc": "2.0", "id": 1, "method": "runtime", "params": []}Connector Protocol (Outbound)
Section titled “Connector Protocol (Outbound)”These are the methods that Triggerware sends to external connectors. Connector implementors must handle these.
generate
Section titled “generate”Asks the connector to produce tuples for a given algorithm and inputs.
Params: object
| Member | Required | Description |
|---|---|---|
name | yes | Generator algorithm name (from the table declaration) |
inputs | yes | Array of input values |
limit | no | Advisory max tuples |
timelimit | no | Advisory max seconds |
notify-limit | no | Advisory: send notification when this many tuples are pending |
notify-timelimit | no | Advisory: max seconds before flushing pending tuples |
{ "jsonrpc": "2.0", "id": 1, "method": "generate", "params": { "name": "gen_from_product", "inputs": [ "product14" ], "limit": 10, "timelimit": 30, "notify-timelimit": 1 }}The connector may respond in any of these forms:
A) Single tuple shorthand:
{ "jsonrpc": "2.0", "id": 1, "result": [ 5, 29.99 ]}B) Batch with exhausted:
{ "jsonrpc": "2.0", "id": 1, "result": { "count": 2, "exhausted": true, "tuples": [ [ 5, 29.99 ], [ 6, 14.5 ] ] }}C) Partial batch with handle (more available):
{ "jsonrpc": "2.0", "id": 1, "result": { "count": 1, "handle": 10, "tuples": [ [ 5, 29.99 ] ] }}D) Handle-only with subsequent notifications:
{ "jsonrpc": "2.0", "id": 1, "result": { "handle": 10 }}Followed by intermediate notifications:
{ "jsonrpc": "2.0", "method": "resultset-incremental-notification", "params": { "count": 1, "handle": 10, "tuples": [ [ 5, 29.99 ] ] }}And a final notification (identified by total-count):
{ "jsonrpc": "2.0", "method": "resultset-incremental-notification", "params": { "count": 1, "handle": 10, "total-count": 2, "exhausted": true, "tuples": [ [ 6, 14.5 ] ] }}generate more
Section titled “generate more”Requests additional tuples from an existing connector result set. Same response forms as generate. The handle must match the one from the original generate response.
Method name: "generate" (distinguished by the presence of handle instead of name/inputs)
Params: object
| Member | Required | Description |
|---|---|---|
handle | yes | Handle from a previous generate response |
limit | no | Advisory max tuples |
timelimit | no | Advisory max seconds |
notify-limit | no | Advisory notification threshold |
notify-timelimit | no | Advisory notification time threshold |
{ "jsonrpc": "2.0", "id": 2, "method": "generate", "params": { "handle": 10, "limit": 10, "notify-timelimit": 1 }}close (connector)
Section titled “close (connector)”Tells the connector it can release resources for a result set handle. Not required if the result set already reported "exhausted": true or an error.
Params: the handle (integer)
{ "jsonrpc": "2.0", "id": 3, "method": "close", "params": 10}function call
Section titled “function call”Simplified method for connectors that implement functions (single return value).
Params: object
| Member | Required | Description |
|---|---|---|
name | yes | Function name |
inputs | yes | Array of input values |
{ "jsonrpc": "2.0", "id": 1, "method": "function call", "params": { "name": "sqrt", "inputs": [ 25 ] }}Response:
{ "jsonrpc": "2.0", "id": 1, "result": 5}Type Reference
Section titled “Type Reference”Column types used in signatures, table definitions, and connector declarations.
| SQL Type Name | JSON Representation | Description |
|---|---|---|
int / integer / smallint / tinyint / bigint | number (integer) | Integer values |
float / double | number (floating point) | IEEE 754 double-precision |
casesensitive / StringCase | string | Case-sensitive text comparison |
caseinsensitive / StringNoCase | string | Case-insensitive text comparison |
date | string (ext-type object) | Calendar date |
time | string (ext-type object) | Time of day |
timestamp | string (ext-type object) | Date and time |
interval | string (ext-type object) | Duration |
json | any | Universal supertype — accepts any JSON value |
blob | string (base64) | Binary data |
Extended types are represented as JSON objects with "ext-type" and "ref" members.
Error Codes
Section titled “Error Codes”| Code | Meaning |
|---|---|
-32700 | Parse error |
-32600 | Invalid request |
-32601 | Method not found |
-32602 | Invalid params |
-7 | State has changed (relation updated since result set was created) |
1 | General uncaught error |
2 | Encode error (response could not be serialized) |
3 | Write error (could not send on connection) |
4 | Error during result generation (reported via notification) |
13 | Connection closed while request was pending |