Skip to content

SAPI reference

This page is the reference for the SAPI client libraries: the methods available in each language and the fields of each configuration object.

For how to use these methods, see Connect with SAPI, Query data with SAPI, and Publish data with SAPI.

Methods

SAPI exposes the same set of operations in each language, with naming that follows the language's conventions. The C library uses free functions that take a handle; the others use methods on a client object (Kxs in C# and Java, SAPI in Python).

Operation C C# Java Python
Connect sapiConnect Connect connect connect
Disconnect sapiDisconnect Disconnect disconnect disconnect
Call an API sapiExecute Execute execute execute
Register a publisher sapiRegisterPublisher RegisterPublisher registerPublisher register_publisher
Publish a message sapiPublish Publish publish publish
Unregister a publisher sapiUnregisterPublisher UnregisterPublisher unregisterPublisher unregister_publisher
Register a queue listener sapiRegisterQueueListener RegisterQueueListener registerQueueListener register_queue_listener
Unregister a queue listener sapiUnregisterQueueListener UnregisterQueueListener unregisterQueueListener unregister_queue_listener
Acknowledge a queue message sapiAckQueue AckQueue ackQueueMessage ack_queue
Register a log handler sapiRegisterLogHandler RegisterLogHandler Not needed. See Logging and events in Java. register_log_handler
Set log levels sapiSetLogLevels SetLogLevels Not available Not available
Get the event handler sapiEventHandler GetSapiEvents addEventListener. See Logging and events in Java. events property
Get the TCP endpoint sapiGetTcpEndpoint GetTcpEndpoint getTcpEndpoint get_tcp_endpoint
Free a response object sapiFreeKxsResponse Not applicable Not applicable Not applicable
Free a configuration object sapiFreeSAPIConfig Not applicable Not applicable Not applicable

Logging and events in Java

Java has no log handler call. SAPI routes the native log lines into SLF4J loggers named com.kx.sapi.c.*, so you control them through your logging configuration.

Java delivers the three connection events as SapiEvent objects to listeners that you register with addEventListener. The events are GW_CONNECTED, GWS_CONNECTED, and RP_CONNECTED. The method is protected, so to use it you subclass Kxs. See Connection event callbacks.

The other languages expose the same three events: one Gateway connected, all Gateways connected, and the response server connected. In C, sapiEventHandler returns a structure of three wait handles, and C# mirrors it with GetSapiEvents. In Python, the events property holds three threading.Event objects.

Method signatures

KxsHandle sapiConnect(SAPIConfig *config, KxsResponse *response);

void sapiDisconnect(KxsHandle handle);

bool sapiExecute(KxsHandle handle, char *apiName, K request, K header,
                 bool deserializeResponse, SAPIRetryPolicy *retryPolicy,
                 KxsResponse *response);

TopicHandle sapiRegisterPublisher(KxsHandle handle, char *topicName,
                                  KxsResponse *response);

bool sapiPublish(TopicHandle handle, short msgType, K data, K header,
                 SAPIRetryPolicy *retryPolicy, KxsResponse *response);

bool sapiUnregisterPublisher(KxsHandle handle, TopicHandle topicHandle,
                             KxsResponse *response);

bool sapiRegisterQueueListener(KxsHandle handle, char *queue,
                               SAPIQueueHandler handler, SAPIAckMode ackMode,
                               int workers, KxsResponse *response);

bool sapiUnregisterQueueListener(KxsHandle handle, char *queue,
                                 KxsResponse *response);

bool sapiAckQueue(KxsHandle handle, char *queue, long long id);

bool SAPIQueueHandler(KxsHandle handle, char *queue, long long id,
                      KxsResponse *response);

void sapiRegisterLogHandler(LogHandler callback);

void sapiSetLogLevels(short traceLevel, short debugLevel, short infoLevel,
                      short warnLevel, short errorLevel, short fatalLevel);

SAPIEvents *sapiEventHandler(KxsHandle handle);

bool sapiGetTcpEndpoint(KxsHandle handle, char *sb, int len);

void sapiFreeKxsResponse(KxsResponse *response);

void sapiFreeSAPIConfig(SAPIConfig *config);
bool Connect(SapiConfig config, KxsResponse kxsResponse = null);

void Disconnect();

bool Execute(string apiName, c.Dict request = null, c.Dict header = null,
             bool deserializeResponse = true, RetryPolicy retryPolicy = null,
             KxsResponse kxsResponse = null);

IntPtr RegisterPublisher(string topic, KxsResponse kxsResponse = null);

bool Publish(IntPtr topicHandle, short msgType, object data,
             c.Dict header = null, RetryPolicy retryPolicy = null,
             KxsResponse kxsResponse = null);

void UnregisterPublisher(IntPtr topicHandle, KxsResponse kxsResponse = null);

bool RegisterQueueListener(string queue,
                           Func<IntPtr, string, int, KxsResponse, bool> handler,
                           short ackMode, KxsResponse kxsResponse = null);

bool UnregisterQueueListener(string queue, KxsResponse kxsResponse = null);

static bool AckQueue(IntPtr client, string queue, long id);

static void RegisterLogHandler(Action<int, string, string> logMessageHandler);

static void SetLogLevels(short traceLevel, short debugLevel, short infoLevel,
                         short warnLevel, short errorLevel, short fatalLevel);

Events.Events GetSapiEvents();

string GetTcpEndpoint();
boolean connect(SapiConfig sapiConfig, KxsResponse kxsResponse);

void disconnect();

boolean execute(String apiName, c.Dict params, c.Dict header,
                RetryPolicy retryPolicy, KxsResponse kxsResponse);

long registerPublisher(String topic, KxsResponse kxsResponse);

boolean publish(long topicHandle, short msgType, Object data,
                c.Dict header, KxsResponse response);

boolean publish(long topicHandle, short msgType, Object data, c.Dict header,
                RetryPolicy retryPolicy, KxsResponse kxsResponse);

boolean unregisterPublisher(long topicHandle, KxsResponse kxsResponse);

boolean registerQueueListener(String queue, KxsQueueListener listener,
                              AckMode ackMode, KxsResponse response);

boolean unregisterQueueListener(String queue, KxsResponse response);

boolean ackQueueMessage(String queue, long messageId);

String getTcpEndpoint();
connect(config: SAPIConfig, response: Optional[KxsResponse] = None) -> bool

disconnect() -> None

execute(req_corr: int, api_name: str, request: pykx.Dictionary,
        header: Optional[pykx.Dictionary] = None,
        retry_policy: Optional[SAPIRetryPolicy] = None,
        response: Optional[KxsResponse] = None) -> bool

register_publisher(topic_name: str,
                   response: Optional[KxsResponse] = None) -> TopicHandle

publish(topic_handle: TopicHandle, req_corr: int, msg_type: int,
        payload: pykx.Dictionary, header: Optional[pykx.Dictionary] = None,
        retry_policy: Optional[SAPIRetryPolicy] = None,
        response: KxsResponse = None) -> bool

unregister_publisher(topic_handle: TopicHandle,
                     response: Optional[KxsResponse] = None) -> bool

register_queue_listener(queue: str, handler: QueueHandler,
                        ack_mode: SAPIAckMode, workers: int,
                        response: KxsResponse) -> bool

unregister_queue_listener(queue: str, response: KxsResponse) -> bool

ack_queue(queue: str, queue_id: int) -> bool

register_log_handler(callback: LogHandler) -> None

get_tcp_endpoint(buf_len: int = 512) -> str

Differences between the languages

  • Request correlator. Python's execute and publish take a req_corr parameter. Pass 0 to have SAPI generate the correlator, which is the normal value. SAPI uses any non-zero value as supplied, so you can set your own to find a request in the client and server logs. The C serialized entry points take the same argument. In Java, set the reqCorr key in the header dictionary instead. C and C# always generate the correlator.
  • Queue listener workers. register_queue_listener in Python and sapiRegisterQueueListener in C require a workers argument, which has no default. It's the number of messages that the client asks the queue to keep in flight for that listener at once. Use 1 unless the handler is slow and the queue is deep. It's not the same as mqWorkersCount in the configuration, which sizes the shared thread pool that processes queue messages. C# and Java don't expose it and always pass 1.
  • Publish without a retry policy. The Java publish overload without a retry policy passes null. A publish with no retry policy is asynchronous: the call returns success as soon as the client accepts the message. See Choose synchronous or asynchronous publishing.
  • Unregistering a publisher in C#. UnregisterPublisher returns void, while the other languages return a boolean. Pass a response object to see the outcome.

Configuration objects

The configuration object is the same structure in every language, with per-language naming. The fields that differ by more than capitalization are:

Purpose C and Python C# Java
Discovery endpoints discoverySvcHosts DiscoveryHosts discoveryHosts
Service classes of interest scs ServiceClasses scs
Build information build Build buildInfo
Network interface addresses addrs Addresses addrs
Event callbacks sapiCallbacks Not applicable. See Connection event callbacks. Not applicable. See Connection event callbacks.
Gateway worker threads gwWorkersCount GWWorkerThreadCount gwWorkersCount
RP worker threads rpWorkersCount RPWorkerThreadCount rpWorkersCount
MQ worker threads mqWorkersCount MQWorkerThreadCount mqWorkersCount
Publish worker threads pubWorkersCount PublishWorkerThreadCount pubWorkersCount
Discovery worker threads dsWorkersCount DSWorkerThreadCount dsWorkersCount
TLS settings tls Tls tls (set with setTLS)
Socket options socketConfig SocketConfig socketConfig
RT settings rtConfig RtConfig rtConfig

In C, every array field has a companion count field — discoverySvcHostsCount, listenHostsCount, advertiseHostsCount, gatewayHostsCount, scsCount, and addrsCount — which you must set to the number of entries in the array. The Python library also accepts the Count fields. The C# and Java libraries take arrays and derive the count.

Connection configuration fields

The field names below use the C and Python spelling.

Field Type Description
discoverySvcHosts string list Addresses and ports of the Discovery service — the qetcd process on KX Sensors nodes.
gatewayHosts string list Addresses and ports of Gateway processes. Setting this disables Discovery.
username string KX Sensors user name.
password string Password.
instanceName string Name for this client. Appears in the SAPI header of every request and in server-side logs. Defaults to a generated unique value.
listenHosts string list Addresses that the client binds its listening socket to, for inbound connections. Defaults to ["0.0.0.0"]. Set it if the default bind is wrong for the host.
listenPorts string Port range to accept inbound connections on, for example 8000-8010.
advertiseHosts string list Addresses that the client sends to Discovery so that the server can connect back. Set it when the bind address isn't reachable from the server. No default.
advertisePorts string Ports advertised to the server as accepting inbound connections.
udpPort int Set by the client. SAPI overwrites it with the client's actual listening port when it sets up the socket, then sends it to Discovery. Don't set it. Defaults to 0.
addrs string list Set by the client. SAPI fills it in from its own listening endpoint and sends it to Discovery. Don't set it.
connTimeout int Timeout in milliseconds for a Gateway connection to succeed. -1 waits indefinitely. In Java, 0 uses the native default of 30 seconds.
bridgeTimeout int Reserved. SAPI doesn't enforce it. Available in C and Java. In Java, 0 uses the native default of 60 seconds.
gatewayStrategy short Strategy for choosing the destination Gateway. Round-robin is the default and the only strategy that works, so don't set it.
scs string list Unused. SAPI copies and logs the value but doesn't act on it. Defaults to ["/reg/GW/"].
domain string Sent to Discovery as domain on the client's registration record. Leave the default unless your deployment team tells you otherwise. Defaults to an empty string.
serviceClass string Sent to Discovery as svcClass on the client's registration record. The default, EXT, marks the process as an external client. Leave the default unless your deployment team tells you otherwise.
family string Sent to Discovery as family on the client's registration record. Leave the default unless your deployment team tells you otherwise. Defaults to an empty string.
version int Set by the client. SAPI sends it to Discovery as the registration revision. Don't set it. Defaults to 0.
build string Build information.
useTLS bool Whether to use TLS for connections to remote processes.
tls SAPITLS TLS settings. See TLS fields.
retryPolicy SAPIRetryPolicy Default retry policy. Null means no retries. See Retry policy fields.
socketConfig SAPISocketConfig Socket options. See Socket option fields.
rtConfig SAPIRTConfig RT settings. See RT configuration fields.
sapiCallbacks SAPICallbacks Called on connection events. See Connection event callbacks.
gwWorkersCount short No effect. SAPI logs the value, but the Gateway pool always has one worker. Defaults to 3.
rpWorkersCount short Size of the pool that handles query responses. Defaults to 6.
mqWorkersCount short Size of the pool that runs queue listener callbacks. Defaults to 3.
pubWorkersCount short No effect. SAPI never reads it. Defaults to 3.
dsWorkersCount short No effect. SAPI never reads it. Defaults to 1.
reqMaxPending int Maximum number of outstanding requests and pending publishes. When the limit is reached, the call fails with -1, unless reqMaxPendingBlock is true. Set it if the application needs more calls in flight. Defaults to 10000.
reqMaxPendingBlock bool Whether a call waits, instead of failing, when reqMaxPending is reached. Defaults to false.
sapiProtocol byte Set by each language binding. Don't set it. The library sends it in every request header as clientProtocol, and uses it to decide whether queue messages must be serialized for a managed language. The values are 0x02 for C, 0x04 for Java, and 0x05 for C# and Python.

Retry policy fields

Field Type Description
maxAttempts unsigned int Maximum number of attempts before the operation fails.
timeout unsigned int Timeout for a single attempt, in milliseconds.
retryInterval unsigned int Interval between attempts, in milliseconds.
retryScaling float Multiplier applied to the interval after each attempt. Must be 1 or greater.

The C# constructor takes the fields in the order maxAttempts, timeout, retryInterval, retryScaling; the Java constructor takes the same order. See Retry failed calls.

Socket option fields

Field Type Description
socRoundTripTime int Expected maximum round-trip time to the server, in milliseconds.
socSendRate int Expected send rate per connection, in bytes per second.
socReceiveRate int Expected receive rate per connection, in bytes per second.

The C# field names are SocketRoundTripTime, SocketSendRate, and SocketReceiveRate.

TLS fields

Field Type Description
CA string CA certificate, as a string.
CAFile string Path to a file holding the CA certificate. Overrides CA.
cert string Client certificate, as a string.
certFile string Path to a file holding the client certificate. Overrides cert.
key string Certificate key, as a string.
keyFile string Path to a file holding the certificate key. Overrides key.
verifyClient bool Verify the certificate presented on inbound connections.
verifyServer bool Verify the certificate presented on outbound connections.

The C# field names are capitalized: CA, CAFile, Cert, CertFile, Key, KeyFile, VerifyClient, VerifyServer. See Encrypt the connection with TLS.

RT configuration fields

These fields configure the RT layer that carries published messages. Most clients set only a few of them, usually rtDir and dedupId.

When configUrl is empty, SAPI writes its own RT configuration file under configPath, named <instance>_<topic>, and fills it with the feed endpoints that it gets from Discovery. SAPI also appends the instance name and topic to rtDir, so each publisher gets its own log directory.

Field Type Description Default
useBridge bool Whether to use a bridge connection instead of persisting messages to a local disk.
rtDir string Base directory for RT logs. SAPI appends the instance name and topic to it. /tmp/rt on Linux, c:/Temp/rt on Windows
configPath string Directory where SAPI writes the RT configuration file that it generates. Used when configUrl isn't set.
caInfoFile string Path to a CA certificate bundle. Empty string
dedupId string Label that tells publishers apart. It doesn't deduplicate messages. See Deduplication. None
logLevel string General log level: info, warn, err, or off. info
consoleLogLevel string Console log level: info, warn, err, or off. err
replFileLogLevel string Replicator file log level: trace, debug, info, warn, error, fatal, or off. off
replConsoleLogLevel string Replicator console log level, same values as replFileLogLevel. err
connTimeout int RT connection timeout, in milliseconds. 2000
configMaxAge int Maximum age of configuration details, in milliseconds. 300000
fetchConfigSleep int Delay between configuration reads, in milliseconds. 5000
localPersistencePeriod int Local data persistence period, in milliseconds. 600000
rtFlushTimeoutSecs int Timeout, in seconds, for flushing local logs to the server on close. -1 means no timeout. A value of 0 from a language binding keeps the default. No timeout
rtLogSizeSoftCap int Soft cap on the size of an RT log file, in bytes. 0 uses the RT SDK's default roll behavior. 0
rtLogSizeHardCap int Hard cap on the size of an RT log file, in bytes. 0 uses the RT SDK's default roll behavior, which rolls at 1 GB. 0
deleteFiles int Whether to delete RT log files. 0
truncateArchived int Whether archived RT log files are truncated automatically. 1

Advanced RT fields

SAPI passes these fields to the RT SDK unchanged. Leave them unset unless the RT team tells you otherwise. SAPI doesn't derive stream, endPoints, rtPort, prefix, or clientName from Discovery; it leaves them empty.

Field Type Description Default
configUrl string URL or file that supplies the RT endpoints. Set it only when you supply endpoints by hand instead of using Discovery. None
clientName string RT client identifier.
prefix string Prefix for RT resources.
stream string RT stream identifier.
endPoints string RT endpoint identifiers.
rtPort string RT port number.
restPortStart int Port on which to start the RT REST server. 0
clientType string RT client type. SAPI publishes only, so leave it as pub. pub

The RT SDK also has subscriber fields (logPosition, pauseThreshold, and exchangeArchived). They have no effect in SAPI, which has no subscribe call.

The Java field names are rtDir, caInfoFile, and rtFlushTimeoutSecs; the C# names are capitalized, with Dir for the log directory, CaInfoFile for the CA bundle, and FlushTimeoutSecs for the flush timeout. The Python name for the CA bundle is CAInfoFile.

Response object fields

Field Type Description
reqCorr long Request correlator.
queueTm int Queue time, in milliseconds.
svcTm int Service time, in milliseconds.
rc short Response code. 0 indicates success.
ac short Application code.
ai string or object Application information.
header dictionary Response header.
payload object Response payload.

In C, ai, header, and payload each have a companion length field: aiLen, headerLen, and payloadLen. Call sapiFreeKxsResponse to release a response object in C.

The type of ai was reverted to Object to match v2 behavior, which may require small changes in clients written against an earlier v3 release. See Release notes.

Connection event callbacks

SAPI raises three connection events. Each language exposes them differently.

Event Message passed to the handler
Gateway connected The Gateway's process name.
All Gateways connected An empty string.
Response connection accepted The remote IP address.

Every handler is optional. Each event also signals a matching wait object, for code that prefers to wait instead of register a handler.

No event fires when a Gateway or response connection is lost. The client reconnects on its own and raises the Gateway connected event again when the Gateway returns, so the only signals your application gets are a failed query in the meantime and the reconnect event afterwards.

Fill in a SAPICallbacks structure and set it on config->sapiCallbacks before you call sapiConnect. The handler type is void handler(const char *msg, const void *opt), where opt is the client handle.

Field Invoked when
gwConnectedEvent A Gateway connection is established.
gwsConnectedEvent All Gateways have at least one connection established.
rpConnectedEvent A response connection is accepted.

To wait instead, use the semaphores in the structure that sapiEventHandler(handle) returns.

Subscribe to the .NET events GwConnected, GwsConnected, and RpConnected on the object that GetSapiEvents() returns. The handler receives a SapiEventsArgs with a Message string.

kxs.GetSapiEvents().GwConnected += (sender, args) => Console.WriteLine(args.Message);

Don't use the public SapiCallbacks class or its IntPtr fields. Connect overwrites them.

Java has no function pointers. Implement the one-method EventListener interface, handle(SapiEvent). Read event.getEventType(), which is GW_CONNECTED, GWS_CONNECTED, or RP_CONNECTED, and event.getMessage(). Register the listener with addEventListener(type, listener).

addEventListener is protected, so your application has to subclass Kxs.

Java listeners see only reconnections. The two Gateway events raised during the initial connect are dropped, because the Kxs object isn't registered until connect returns.

Pass SAPICallbacks(gwConnectedEvent=..., gwsConnectedEvent=..., rpConnectedEvent=...) as config.sapiCallbacks. Each handler is a callable that takes (msg, opt).

If you supply none, the library sets the three threading.Event objects on kxs.events, so you can wait on them instead, for example kxs.events.gwConnected.

Threads and timing

In C, C# and Python, the Gateway callbacks run inline on that Gateway's communication worker thread, and the response connection callback runs on the listening thread. A slow handler stalls that thread. Record the event or signal another thread, and return at once. Don't block in a handler, and don't call back into SAPI from one.

Java hands listeners to an executor, so a Java listener can do real work.

The Gateway events fire while connect is still blocking. In C, C# and Python, the callback runs before connect returns.

Acknowledgement modes

SAPIAckMode sets how a queue listener acknowledges messages.

Value Numeric Behavior
SAPI_ACK_UNKNOWN Not yet set.
SAPI_ACK_AUTO 1 The message is acknowledged automatically when the queue handler returns true.
SAPI_ACK_CLIENT 2 The client must acknowledge explicitly.
SAPI_ACK_NONE 3 No acknowledgement is sent. The server treats the message as acknowledged when it sends it.

In C# the mode is passed as a short; in Java it is the AckMode enum with values AUTO, CLIENT, and NONE. For the server side of message queues, see Publish and subscribe to a message queue.

Generate enumeration files

KX Sensors uses enumerations and flags for the numeric codes that a client exchanges with the server, such as return codes, application codes, log levels, service classes, and your application's own message types. The generator writes those codes as named constants, so each client language uses the same names as the server.

Which sets you need depends on your application. Every client needs the return and application codes, and the SAPI library already ships those in sapidefns.h and its Java and C# counterparts. The generated files add the application-specific sets.

Generate the files from the server rather than hand-writing them, so they stay in step with the deployment's configuration.

  1. Connect to the target environment over SSH and switch to the KX Sensors user.
  2. Start a q console with the enumeration generation console: mc enumGen
  3. Load the export library: li`kxsSapiExport
  4. Generate the files: .flagsenums.writeAll[]

    The log message Writing export files to: shows the resolved output path. By default that is the sapi subdirectory of the environment's miscellaneous data directory (${MISC}/sapi), which you can change with the sapiExportDir system parameter. Each language has its own subdirectory, for example java/Flags.java and java/Enum.java.

  5. Exit the console with \\.

  6. Copy the generated files from that directory to your development machine.

The generator produces files for Java, C#, C++, C, and PL/SQL. It doesn't produce Python files, and the Python library ships no generated constants.

In C#, the Kx.SapiCS.Enum.dll assembly ships with the library so that example code compiles. Replace it with enumerations generated on your own server before you run against a real deployment.

Regenerate after an upgrade

The generated files are a snapshot, stamped with the environment version and the generation time. The client never checks that version. After any upgrade that adds, removes, or renumbers a flag or enumeration, regenerate the files and rebuild your client.

SAPI gives no error if the files are stale. The client sends the old numbers, which the server may map to a different or illegal value, and it can't name new codes that it receives.

Next steps