Table of Contents

Class MetadataQueryParams

Namespace
DatabentoDotNet.Historical
Assembly
DatabentoDotNet.Historical.dll

The parameter set the three metadata.* billing endpoints take.

public sealed record MetadataQueryParams : IEquatable<MetadataQueryParams>
Inheritance
MetadataQueryParams
Implements
Inherited Members

Remarks

One type, deliberately, and not named for billing. Upstream declares this once as GetQueryParams and aliases it three times (metadata.rs:348-359). Sharing it matters more than the name does: a caller who prices a request with GetCostAsync(MetadataQueryParams, CancellationToken) and then sends a different request has been badly served by the API surface, and a shared type is what makes sending the same one the path of least resistance.

This is not the full parameter set timeseries.get_range takes, and the sentence above used to claim it was. #37 found the discrepancy while porting symbology.resolve's From<GetRangeParams> conversion: upstream keeps two distinct types, and GetRangeParams (timeseries.rs:166-199) carries a stype_out this one has no field for, posting it together with encoding=dbn and compression=zstd (timeseries.rs:128-138) — three fields the billing endpoints neither take nor send (metadata.rs:462-471). None of the three affects a price, a record count or a billable size, so their absence here is correct rather than an omission; what was wrong was the promise that #38 could send this type as-is.

#38 closed it with a second type. GetRangeParams carries the stype_out, as upstream's own GetRangeParams does, and ToQuery() narrows one back to this type — so a caller still prices exactly the request they are about to send, which is the property this type was built for. The rejected alternative was widening this type with a StypeOut the billing renderer would drop: an inert public field on the type whose whole job is to describe what bills. That conversion is an addition over upstream, which has no equivalent and leaves its callers to build the second object by hand.

Meanwhile FromQuery(MetadataQueryParams, SType) takes the missing stype_out as an explicit argument rather than defaulting it, because there is no default for it that is right — see that method for what the wrong one would silently do. Callers holding a GetRangeParams should prefer FromQuery(GetRangeParams), which reads the value instead of asking for it.

Limit is ulong? where upstream is Option<NonZeroU64>. C# has no non-zero integer type, so the constraint moves into the initializer, which throws rather than sending limit=0.

That sentence used to guess at what the API does with a zero, and the guess was wrong. It read "a value the API would read as a limit rather than as its absence". #38 asked instead: these three endpoints reject it, with 422 and a validation body saying Input should be greater than 0. So the initializer is not preventing a silently misread request; it is turning a round trip into a compile-site error.

And timeseries.get_range does not agree with them about it, which is the part worth knowing. The same limit=0 that fails validation here is accepted there, returns a body byte-identical to the one with no limit at all, and carries a X-Warning claiming no data was found. See Limit. Refusing zero in both types is what keeps a request that was priced here and sent there from behaving differently at each end.

"Query" in this type's name means a data query, not a URL query string. Its siblings' ToQueryParameters() render onto the URL query string, but this type's ToFormParameters() renders onto a form body instead — upstream's own GetQueryParams already carries this same double meaning, and the name is kept for consistency with it rather than renamed away from it.

Properties

Dataset

The dataset code, for example XNAS.ITCH.

public required string Dataset { get; init; }

Property Value

string

DateTimeRange

The request range: inclusive start, exclusive end.

public required DateTimeRange DateTimeRange { get; init; }

Property Value

DateTimeRange

Limit

The maximum number of records. Defaults to no limit, in which case the field is omitted from the request rather than sent empty.

public ulong? Limit { get; init; }

Property Value

ulong?

Exceptions

ArgumentOutOfRangeException

The value is zero.

Schema

The record schema to query.

public required Schema Schema { get; init; }

Property Value

Schema

StypeIn

The symbology type of Symbols. Defaults to RawSymbol, and is sent on every request even when left at the default — upstream pushes it unconditionally (metadata.rs:466).

public SType StypeIn { get; init; }

Property Value

SType

Symbols

The symbols to query.

public required Symbols Symbols { get; init; }

Property Value

Symbols

Methods

ToFormParameters()

Renders this parameter set as the form body the three billing endpoints post.

public IReadOnlyList<KeyValuePair<string, string>> ToFormParameters()

Returns

IReadOnlyList<KeyValuePair<string, string>>

The form fields, in upstream's push order.

Remarks

The order is upstream's push order (metadata.rs:462-471), which is not the order the properties are declared in: stype_in precedes symbols. It makes no difference to the API and it makes the rendered body byte-comparable with upstream's, which is the cheapest way to tell this rendering apart from a plausible one.

Exceptions

InvalidOperationException

Symbols or DateTimeRange is left at its type's default value. required forces a caller to assign each property but does not stop them assigning default, and ToApiString() and StartUnixNanoseconds/ EndUnixNanoseconds each refuse to render one, the same way their own accessors document.