Regis AI
Stream research answers grounded in company data.
Working inside your own AI client? See the MCP connection guide →
Use Regis to research an existing customer and investigate companies in its wider group. Supply the customer’s country, your offer and your territory when they matter to the question.
A streamed research answer
Use text events for the answer and tool_result events for the supporting data.
Structured data for your app
Read collected tool outputs from the final done event. The transport is still SSE.
Ask Regis
#/ai/querySend a self-contained research question. Regis selects company-data tools and streams their results, with an optional written answer.
| Parameter | Location / type | Description |
|---|---|---|
queryRequired | bodystring | One self-contained question; maximum 4,000 characters. No conversation history is stored by this endpoint. |
mode | bodystring | ai streams prose and tool results; data returns tool results without prose. Default: ai. |
curl --no-buffer --request POST "https://api.globaldatabase.com/v2/ai/query" \
--header "Authorization: Token $GLOBAL_DATABASE_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Accept: text/event-stream' \
--data '{
"query": "Find GLOBAL DATA INTELLIGENCE in GB and show its corporate group. Separate company facts from possible expansion questions.",
"mode": "ai"
}'Response
200 text/event-stream. Read frames incrementally until done or error; do not call response.json().
- Each successful request uses one AI-query request. Underlying data-tool usage is metered separately.
- For follow-ups, include only the relevant prior context in a new query and keep the complete string within 4,000 characters.
Read the stream
Regis uses a POST request. Use fetch with a body reader rather than the browser’s GET-only EventSource interface. Network chunks are not complete events: buffer until the blank line between SSE frames.
| Event | Payload fields | How to use it |
|---|---|---|
status | message | Progress information. |
tool_call | tool | A data tool is about to run. |
tool_result | tool, data, duration, is_error | A complete tool result; preserve its source context. |
generating | type | Prose generation has started (ai mode). |
text | content | Append content in order (ai mode). |
suggested_actions | actions | Possible follow-up questions (ai mode). |
done | tools_used, usage, message_id; data in data mode | Terminal success. data mode carries collected {tool, data} entries. |
error | detail, code | Terminal failure after the stream has started. |
event: tool_result
data: {"type":"tool_result","tool":"get_company_by_identifiers","data":{"id":29707645},"is_error":false}
event: done
data: {"type":"done","data":[{"tool":"get_company_by_identifiers","data":{"id":29707645}}],"tools_used":["get_company_by_identifiers"],"message_id":null}
Abbreviated frames showing the wire format. Tool payloads vary. Ignore comment keepalives and unknown future events; a closed connection without done is an incomplete response.
A complete server-side streaming example
This Node.js client handles split frames, UTF-8 decoding, HTTP errors, SSE errors and premature disconnection. The 120-second timeout and 5 MB frame cap are example application choices, not provider limits.
Download JavaScript client// Node.js 20+. Run on your server; never ship the API key to a browser.
import { pathToFileURL } from 'node:url';
export async function* readSSE(body) {
const reader = body.getReader();
const decoder = new TextDecoder();
let pending = '';
try {
while (true) {
const { value, done } = await reader.read();
pending += done ? decoder.decode() : decoder.decode(value, { stream: true });
let boundary;
while ((boundary = /\r?\n\r?\n/.exec(pending))) {
const frame = pending.slice(0, boundary.index);
pending = pending.slice(boundary.index + boundary[0].length);
if (frame.length > 5_000_000) throw new Error('Application frame limit exceeded');
const data = frame.split(/\r?\n/)
.filter(line => line.startsWith('data:'))
.map(line => line.slice(5).replace(/^ /, ''))
.join('\n');
if (data) yield JSON.parse(data);
}
if (pending.length > 5_000_000) throw new Error('Application frame limit exceeded');
if (done) break;
}
} finally {
await reader.cancel().catch(() => {});
reader.releaseLock();
}
}
export async function askRegis(query, mode = 'ai') {
const key = process.env.GLOBAL_DATABASE_API_KEY;
if (!key) throw new Error('Set GLOBAL_DATABASE_API_KEY on your server');
if (typeof query !== 'string' || !query.trim() || [...query].length > 4000) {
throw new Error('Supply a question of 1–4,000 characters');
}
if (!['ai', 'data'].includes(mode)) throw new Error('Mode must be ai or data');
const response = await fetch('https://api.globaldatabase.com/v2/ai/query', {
method: 'POST',
headers: {
Authorization: `Token ${key}`,
'Content-Type': 'application/json',
Accept: 'text/event-stream'
},
body: JSON.stringify({ query, mode }),
signal: AbortSignal.timeout(120_000)
});
if (!response.ok) {
const retryAfter = response.headers.get('Retry-After');
throw new Error(`API HTTP ${response.status}; Retry-After: ${retryAfter ?? 'not supplied'}`);
}
if (!response.body || !response.headers.get('content-type')?.includes('text/event-stream')) {
throw new Error('Expected a Server-Sent Events response');
}
let answer = '';
for await (const event of readSSE(response.body)) {
if (event.type === 'error') {
throw new Error(`Regis stream error: ${event.code ?? 'unknown'}`);
}
if (event.type === 'text') {
answer += event.content ?? '';
process.stdout.write(event.content ?? '');
}
if (event.type === 'done') {
return { answer, data: event.data ?? [], usage: event.usage };
}
// Handle status, tool_result and suggested_actions as needed.
// Keep tool_result source metadata with any data used in your UI.
}
throw new Error('The stream ended before a done event; the response is incomplete');
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
const query = process.argv[2] || 'Find GLOBAL DATA INTELLIGENCE in GB and show its corporate group.';
askRegis(query, process.argv[3] || 'ai')
.then(result => console.log('\n', JSON.stringify(result, null, 2)))
.catch(error => { console.error(error.message); process.exitCode = 1; });
}
Set GLOBAL_DATABASE_API_KEY, then run node regis-client.mjs. Add a quoted question and an optional data mode argument to customize the request.
Based on the Global Database API v2 reference ↗ · Reviewed 14 September 2026. Examples are illustrative or abbreviated, not live company reports.