The HTTP layer
Calling an endpoint that has no typed wrapper, and the six per-request options every call accepts.
Most of the time you use client.api.*, which is typed and does the post-processing. The layer underneath is
there for what it does not cover: a plugin endpoint, an API newer than the library, a request that needs an
abort signal.
await client.http.get<T>(endpoint, params?, options?);
await client.http.post<T>(endpoint, body, options?);
await client.http.put<T>(endpoint, body, options?);
await client.http.patch<T>(endpoint, body, options?);
await client.http.del<T>(endpoint, params?, options?);Every one of them adds the headers, the body fields and the error handling described below — so a raw call is still an authenticated, audited, recoverable call.
What a request carries for you
Whichever verb you use, the library adds:
Sinequa-csrf-token | The stored session token, when there is one |
Authorization: Bearer | In bearer mode — unless a transport is configured, which attaches its own |
sinequa-override-user · -domain | While impersonation is active |
Sinequa-Force-Camel-Case | So the response keys are camel-cased |
app | In the body of every POST/PUT/PATCH/DELETE |
locale · ui-language | From uiLanguage, falling back to the browser's language |
noUserOverride | The negation of userOverrideActive |
noAutoAuthentication | Resolved from the auth mode — false only in sso |
And on the way back: the token is refreshed from the sinequa-jwt-refresh header, a 401 may trigger recovery,
and any failure emits requestFailed before throwing.
Calling an endpoint with no wrapper
import { createAtomicClient } from "@sinequa/atomic";
const client = createAtomicClient({
app: "<your-app>",
backendUrl: "https://<your-sinequa-server>",
});
await client.initializeConfig();
await client.auth.login();
/** The shape your plugin answers with — you declare it, nothing validates it. */
type Summary = { text: string; tokens: number };
// An endpoint starting with `plugin` gets the `api/v1/` prefix automatically.
const summary = await client.http.post<Summary>("plugin/summarize", {
documentId: "abc123",
maxTokens: 200,
});
console.log(summary.text);import { Injectable, inject } from "@angular/core";
import { SINEQUA } from "./sinequa";
/** The shape your plugin answers with — you declare it, nothing validates it. */
export type Summary = { text: string; tokens: number };
@Injectable({ providedIn: "root" })
export class PluginService {
private readonly client = inject(SINEQUA);
/**
* `plugin/*` endpoints get the `api/v1/` prefix automatically. The request is
* authenticated and recoverable exactly like a typed call.
*/
summarize(documentId: string, signal?: AbortSignal) {
return this.client.http.post<Summary>(
"plugin/summarize",
{ documentId, maxTokens: 200 },
{ signal },
);
}
}import { ready, sinequa } from "./sinequa";
/** The shape your plugin answers with — you declare it, nothing validates it. */
export type Summary = { text: string; tokens: number };
/**
* `plugin/*` endpoints get the `api/v1/` prefix automatically. The request is
* authenticated and recoverable exactly like a typed call.
*/
export async function summarize(documentId: string, signal?: AbortSignal) {
await ready;
return sinequa.http.post<Summary>(
"plugin/summarize",
{ documentId, maxTokens: 200 },
{ signal },
);
}API_ENDPOINTS autocompletes the 32 known paths while still accepting any string, so a plugin or a new endpoint
needs no cast.
Request options
Prop
Type
A timeout for one request
There is no timeout option: ordinary requests wait as long as the network does. createTimeoutController gives
you a signal that aborts:
import { createTimeoutController, TimeoutError } from "@sinequa/atomic";
const { signal } = createTimeoutController(5_000);
try {
await client.http.post("api/v1/query", { name: "<your-query>", text }, { signal });
} catch (error) {
if (error instanceof TimeoutError) notify("The server is not responding.");
else throw error;
}Only the authentication layer has a timeout of its own — auth.timeoutMs, ten seconds by default.
Getting the raw response
responseType: "response" is what an export or a download needs:
const response = await client.http.get<Response>("api/v1/…", undefined, {
responseType: "response",
});
const name = /filename="?([^"]+)"?/.exec(response.headers.get("content-disposition") ?? "")?.[1];
const blob = await response.blob();