Developer documentationAPI + MCPRequest API access
API V2 / REFERENCE

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.

mode: ai

A streamed research answer

Use text events for the answer and tool_result events for the supporting data.

mode: data

Structured data for your app

Read collected tool outputs from the final done event. The transport is still SSE.

Ask Regis

#
POST/ai/query

Send a self-contained research question. Regis selects company-data tools and streams their results, with an optional written answer.

ParameterLocation / typeDescription
queryRequiredbodystringOne self-contained question; maximum 4,000 characters. No conversation history is stored by this endpoint.
modebodystringai streams prose and tool results; data returns tool results without prose. Default: ai.
cURL request
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().

Integration notes
  • 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.
Provider reference ↗

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.

EventPayload fieldsHow to use it
statusmessageProgress information.
tool_calltoolA data tool is about to run.
tool_resulttool, data, duration, is_errorA complete tool result; preserve its source context.
generatingtypeProse generation has started (ai mode).
textcontentAppend content in order (ai mode).
suggested_actionsactionsPossible follow-up questions (ai mode).
donetools_used, usage, message_id; data in data modeTerminal success. data mode carries collected {tool, data} entries.
errordetail, codeTerminal failure after the stream has started.
SSE · illustrative data-mode frames
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
JavaScript · complete streaming 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.