Install the SDK
mssql11 or 12, and@types/mssql9 or later as a dev dependency, to query Exigo’s SQL replica.undici6 or 7, to call Exigo’s REST API through Fluid’s egress proxy.
Define the credentials
The SDK reads no environment variables and stores nothing. You tell it where the credentials come from, once per app. If a field is missing, the SDK throwsExigoCredentialsError and names the field.
A droplet that many companies install looks the credentials up per company:
lib/exigo.ts
trustServerCertificate is required and has no default. Exigo’s replicas present a certificate that doesn’t verify against their host name, so they need true, which skips certificate verification.
The resolver runs on every call. If the lookup is slow, cache the result in your app.
Call the REST API
get and delete take params, query, headers, timeoutMs and signal. post, put and patch also take a body, sent as JSON.
The client:
- Adds
/3.0to the base URL, unless the stored URL already ends in it. A base URL that ends in another version, such as/2.0, throwsExigoCredentialsError. - Requires an
httpsbase URL, because every request carries the password. Plainhttpworks only forlocalhost,127.0.0.1and[::1], so you can test against a local stub. - Sends Basic authentication as
username@company. - Times out after 15 seconds by default. Set
timeoutMson the client or on one call to change it. - Resolves to the parsed JSON, or to
undefinedwhen the response body is empty. - Throws
ExigoAuthErrorfor a 401 or 403, andExigoApiErrorfor any other status outside the 2xx range or for a 200 response whose body is an HTML page or isn’t JSON. The error’s message andbodySnippetnever contain the password. - Refuses a path that is a full URL, so the credentials only go to the configured host. It also refuses a path that starts with an API version, such as
/3.0/customers, because it adds the version itself. - Refuses a path parameter that is empty,
.or.., which would otherwise reach a different endpoint than the path names.
Query the SQL replica
getExigoPool returns an mssql connection pool. For typed parameters, import the types from mssql itself: request.input("id", sql.Int, id).
How pools are reused
The SDK keeps one pool per host, port, database, user name and TLS settings. Repeated calls reuse it, and calls made while the first connect is still running share that connect. A failed connect isn’t kept, so the next call tries again. When a password changes, the new password gets its own pool and the old one keeps serving the requests already running. The SDK closes the old pool once nothing has used it for about five minutes, and any pool once nothing has used it for about 30 minutes. The defaults:
Pools are small because every running instance of your app opens its own. To change the pool settings, pass
{ max, idleTimeoutMs, connectTimeoutMs, requestTimeoutMs } as the second argument. The options apply when the pool opens.
Errors from SQL
A failed connect throwsExigoAuthError, ExigoTimeoutError or ExigoConnectionError, with a message that says what to check.
The SDK leaves errors from your own queries alone. To map a query’s timeout or dropped connection to the same errors, pass the error through translateExigoSqlError. Any other query error, such as a wrong table name, comes back unchanged, so it’s never reported as a network failure.
Close pools on shutdown
Use it in Next.js
Keepmssql out of the bundle, and run every route that queries on the Node runtime:
next.config.ts
app/api/customers/route.ts
Reach Exigo through Fluid’s egress proxy
Exigo accepts calls only from IP addresses each tenant allowlists, and a Mist app on Vercel has no fixed outbound address. Fluid’s egress proxy lends your app a fixed one. Both the REST client and the SQL pool take anegressProxy option:
resolveFluidInstallation comes from the Mist app template. It finds the installation from a request header, but doesn’t authenticate whoever sent the request. Before a route loads a company’s Exigo credentials, check that the caller may act for that company. See Authentication.
When FLUID_EGRESS_PROXY_URL isn’t set, as in a local run, the code above calls Exigo directly.
- The REST client needs the
undicipackage for the proxy. The SQL pool needs nothing extra. - Clients built with the same proxy URL and token share their connections, so you can create a client per request.
- The proxy URL and token are part of a SQL pool’s identity: a different proxy or token gets its own pool.
- Through the proxy, the SQL connection must be encrypted.
encrypt: falsethrowsExigoCredentialsError. If the replica doesn’t offer encryption, the SDK closes the connection before it sends the login and throwsExigoConnectionError. - When the proxy refuses a connection, the SDK throws
ExigoProxyError, whosestatusis the proxy’s answer. See When the proxy refuses.
Errors
Every error extendsExigoError.
On the auth, timeout and connection errors,
source is "rest" or "sql".
ExigoProxyError extends ExigoConnectionError, so a check for instanceof ExigoConnectionError also catches proxy refusals. Check for ExigoProxyError first if your app retries connection failures, since a 403 or 407 from the proxy won’t succeed on retry.
The SDK’s own messages and fields never contain a password or an Authorization header. An error that wraps a driver error keeps the original as cause, which the SDK doesn’t redact. Don’t log or serialize cause whole.
Related pages
- Egress proxy: turn on Fluid’s fixed outbound address for your droplet.
- Connect Exigo to Fluid: link a company’s Exigo account to Fluid itself.
- Authentication: where a Mist app gets its droplet installation token.