Quickstart
First requests and backends.
Output formats
A backend chooses the JavaScript container; a format chooses the column layout of reference and historical results. Both are request options.
| Constant | Value | Result | Metadata |
|---|---|---|---|
Backend.ARROW | 'arrow' (default) | Apache Arrow Table | ResultMetadata properties on the table |
Backend.JSON | 'json' | Array of row objects keyed by column name | ResultMetadata properties on the array |
Backend.POLARS | 'polars' | nodejs-polars DataFrame | None |
import type { Table } from 'apache-arrow';
import { Backend, connect } from '@xbbg/core';
const engine = await connect();
const table = (await engine.bdp(['AAPL US Equity'], ['PX_LAST', 'SECURITY_NAME'])) as Table;
for (const row of table) {
console.log(row.toJSON());
}
const rows = (await engine.bdp(['AAPL US Equity'], ['PX_LAST'], {
backend: Backend.JSON,
})) as Array<Record<string, unknown>>;
const frame = await engine.bdh(['SPX Index'], ['PX_LAST'], {
start: '2024-01-01',
end: '2024-01-31',
backend: Backend.POLARS, // requires the nodejs-polars package
});
console.log(rows, frame);unknown; cast to the container of the backend you chose.request, bdp, bds, bdh, bdib, bdtick, bql, beqs, bsrch, bta, bflds, fieldInfo, fieldSearch, blkp, bport, bcurves, bgovts, and the top-level helpers.delayStatus, and Subscription.latest() accept only 'arrow' and 'json'. Recipes reject 'polars' with a TypeError before calling Bloomberg, and latest() throws for it. Request methods reject an unknown backend string with a TypeError.nodejs-polars (>=0.10.0) is an optional peer dependency, loaded on first use. Without it, a Polars request fails with nodejs-polars is required for Polars backend. Install: npm install nodejs-polars. Polars frames carry no xbbg metadata.bigint (Time64 in microseconds since midnight), Date32 values and timestamps are epoch-millisecond numbers, and nulls stay null. Convert bigint values before calling JSON.stringify.engine.requestRaw() takes the same RequestInput as engine.request() and returns the Arrow IPC stream as a Buffer, for consumers that read Arrow IPC directly:
import { tableFromIPC } from 'apache-arrow';
import { connect } from '@xbbg/core';
const engine = await connect();
const ipc = await engine.requestRaw({
service: '//blp/refdata',
operation: 'ReferenceDataRequest',
securities: ['AAPL US Equity'],
fields: ['PX_LAST'],
});
const table = tableFromIPC(ipc);
console.log(table.schema.metadata.get('xbbg.bloomberg_request_id'));format controls the column layout of reference data (bdp) and historical data (bdh):
| Constant | Wire value | Columns |
|---|---|---|
Format.LONG | 'long' (default) | ticker, field, value, with every value as text |
Format.LONG_TYPED | 'long_typed' | ticker, field, value_f64, value_i64, value_str, value_bool, value_date, value_ts, value_time |
Format.LONG_WITH_METADATA | 'long_metadata' | ticker, field, value, dtype: text values plus each value's Arrow type name |
Format.SEMI_LONG | 'semi_long' | One row per ticker (bdp) or per ticker and date (bdh), one column per field |
ticker here is the engine's key column. With keyColumn: 'security' the column is named security; the ticker default is deprecated (see Configuration).
import { Backend, Format, connect } from '@xbbg/core';
const engine = await connect();
const typed = await engine.bdp(['AAPL US Equity'], ['PX_LAST', 'DVD_EX_DT'], {
format: Format.LONG_TYPED,
});
const wide = await engine.bdh(['SPX Index', 'NDX Index'], ['PX_LAST', 'PX_VOLUME'], {
start: '2024-01-01',
end: '2024-01-31',
format: Format.SEMI_LONG,
backend: Backend.JSON,
});
console.log(typed, wide);bdh results add a date column after ticker in every format.LONG_TYPED puts date-only values in value_date (Date32), full datetimes in value_ts, and time-only values in value_time (Time64, microseconds); SEMI_LONG date and time columns become Date32, Time64, or UTC timestamps; LONG_WITH_METADATA reports dtype values such as 'date32' and 'time64'. LONG stays textual.format. bds, bql, beqs, bsrch, bta, bflds, blkp, bport, bcurves, bgovts, bdib, and bdtick reject it with BlpValidationError (format is not supported for ... output), even where their option types list it. Recipes have fixed schemas.'typed', 'metadata', 'with_metadata', and 'wide'. Format values are case-sensitive.Format.LONG_WITH_METADATA is 'long_metadata'. Releases before 1.4.8 exported 'long_with_metadata', which the engine rejects; use the constant rather than a hard-coded string.Arrow tables and JSON row arrays expose response metadata as properties of the ResultMetadata type:
| Property | Contents | Present when |
|---|---|---|
metadata | Raw Arrow schema metadata, Record<string, string> | Always |
bloombergRequestId | The SDK-assigned RequestId for Bloomberg support | The result came from a single Bloomberg request |
bloombergRequestIds | Every RequestId behind the result, sorted and deduplicated | Bloomberg assigned at least one ID |
eidData | { [ticker]: number[] } entitlement IDs | returnEids: true on bdp, bds, bdh, bdib, or bdtick |
delayed | { [ticker]: { delayed, delay_minutes } } | onDelayed was set and the delayed-data check ran |
securityErrors | { [ticker]: { category, code, subcategory, message } } | Bloomberg reported security errors |
fieldExceptions | { [ticker]: [{ field, category, code, subcategory, message }] } | Bloomberg reported field exceptions |
fieldErrors | { [fieldId]: { category, code, subcategory, message, source? } } | A fieldInfo, bflds, or FieldInfoRequest call asked for ids that Bloomberg refused, including results with no rows |
import type { Table } from 'apache-arrow';
import { connect, type ResultMetadata } from '@xbbg/core';
const engine = await connect();
const ref = (await engine.bdp(['VOD LN Equity', 'AAPL US Equity'], ['PX_LAST'], {
returnEids: true,
onDelayed: 'ignore',
})) as Table & ResultMetadata;
console.log(ref.bloombergRequestIds); // quote these to Bloomberg support
console.log(ref.eidData); // { 'AAPL US Equity': [...], ... }
console.log(ref.delayed); // { 'VOD LN Equity': { delayed: true, delay_minutes: 15 } }
const typeMisses = ref.metadata['xbbg.type_misses'];
if (typeMisses !== undefined) {
console.warn(JSON.parse(typeMisses) as Record<string, number>);
}bloombergRequestId(s) are Bloomberg's support identifiers, distinct from xbbg's request_id label and from SDK correlation IDs. Sharded, streamed, and recipe results keep the IDs of every contributing data request; cached field and exchange introspection is not included, and an unavailable ID is never replaced with a substitute. Errors carry the same IDs as bloomberg_request_id and bloomberg_request_ids.ReferenceDataRequest (bdp, bds), HistoricalDataRequest, IntradayBarRequest, and IntradayTickRequest, and only for exchanges the requester is entitled to. Check them with engine.checkEntitlements(); see Recipes for entitlement and delayed-data workflows.onDelayed: 'warn' | 'raise' | 'ignore' on bdp, bdh, bdib, bdtick, or request() records { delayed, delay_minutes } per ticker. 'warn' also emits one BlpDelayedDataWarning per delayed ticker, and 'raise' rejects the call with BlpRequestError. Omitting onDelayed skips the check.metadata['xbbg.type_misses'] as JSON { [field]: count }; there is no parsed property for them.requestRaw() buffers carry the same information in their schema metadata under xbbg.bloomberg_request_id, xbbg.bloomberg_request_ids, xbbg.eid_data, xbbg.delayed, xbbg.security_errors, xbbg.field_exceptions, xbbg.field_errors, and xbbg.type_misses. Raw xbbg.field_exceptions is a compact version-1 dictionary of unique exceptions with per-security indices; the fieldExceptions property still returns the expanded per-security arrays.Every date or datetime argument accepts the DateLike / DateTimeLike input types:
| Input | Example | Notes |
|---|---|---|
| ISO 8601 string | '2024-01-17', '2024-01-17T10:30:00', '2024-01-17T10:30:00-05:00' | Offsets are preserved |
| Bloomberg-native string | '20240117' | |
Date | new Date('2024-01-17T00:00:00Z') | Dates use the UTC calendar day |
| Epoch milliseconds | Date.UTC(2024, 0, 17) | |
| Luxon-style object | DateTime.fromISO('2024-01-17') | Anything with toJSDate(): Date |
Ambiguous strings such as '01/17/2024' are rejected with a TypeError instead of guessing the month and day order, so the call fails before anything is sent. The exported formatDate and formatDateTime helpers apply the same conversions the engine uses:
import { formatDate, formatDateTime } from '@xbbg/core';
formatDate('2024-01-02'); // '20240102'
formatDate(new Date('2024-01-02T23:00:00Z')); // '20240102' (UTC calendar day)
formatDateTime('2024-12-02 09:30'); // '2024-12-02T09:30' (naive; read in requestTz)
formatDateTime('20241202'); // '2024-12-02T00:00:00'
formatDateTime(new Date('2024-12-02T14:30:00Z')); // '2024-12-02T14:30:00.000Z'formatDate returns Bloomberg-native YYYYMMDD and is used for bdh start and end dates, beqs asof, bta dates, recipe dates, the dt day of abdib, and Date override values passed through ovr().formatDateTime keeps naive strings naive and converts Date, epoch, and Luxon values to UTC ISO strings. It is used for bdib and bdtick start/end (including abdtick) and for bqr startDatetime/endDatetime.Date built from local midnight, such as new Date(2024, 0, 17), can fall on the previous UTC day in time zones east of UTC. Use date strings or Date.UTC(...) for calendar dates.requestTz decides how naive intraday datetimes are read, and outputTz relabels the returned time column (the instants are unchanged). Both accept:
'UTC', the default'local', the machine's time zone'exchange', the exchange time zone of the requested security'NY', 'LN', 'TK', and 'HK', aliases for New York, London, Tokyo, and Hong Kong'America/New_York'Datetimes that carry an offset are converted from that offset whatever requestTz says.
First requests and backends.
Tick and Arrow subscription output.
The same formats in the Python package.
Backend, Format, ResultMetadata, and the date helpers.