Try Opteryx

OData API

Base URL: https://odata.opteryx.app

Overview

OData service discovery, metadata, and dataset query endpoints for compatible clients and BI tools.

Endpoints

ServiceDocs
Well Known Llmsget/.well-known/llms.txt View
OData v4 Service Documentget/api/v4/ View
OData v4 Service-wide EDMX Metadataget/api/v4/$metadata View
Query dataset rowsget/api/v4/{workstream}/{collection}/{dataset} View
Per-dataset OData EDMX metadataget/api/v4/{workstream}/{collection}/{dataset}/$metadata View

Well Known Llms

Request: get/.well-known/llms.txt

Tags: service

Serve LLM directives file for automated agents.

Responses

  • 200 — Successful Response (text/plain string)

OData v4 Service Document

Request: get/api/v4/

Tags: OData v4

Returns the OData v4 service document listing all accessible EntitySets grouped by workspace and collection.

Header Parameters

  • authorization string | null [header; optional]

Responses

  • 200 — Service document with EntitySet list and access metadata (application/json object)
  • 401 — Missing or invalid authentication
  • 422 — Validation Error (application/json HTTPValidationError)

OData v4 Service-wide EDMX Metadata

Request: get/api/v4/$metadata

Tags: OData v4

Returns the complete OData v4 EDMX metadata document describing all EntityTypes and EntitySets accessible to the authenticated user.

Header Parameters

  • authorization string | null [header; optional]

Responses

  • 200 — EDMX metadata document (XML) (application/json object)
  • 401 — Missing or invalid authentication
  • 504 — Firestore unavailable; cannot enumerate datasets
  • 422 — Validation Error (application/json HTTPValidationError)

Query dataset rows

Request: get/api/v4/{workstream}/{collection}/{dataset}

Tags: OData v4

Retrieve data from a dataset with OData v4 query parameters ($filter, $select, $orderby, $top, $skip, $apply, $count). Returns paginated results with total count and nextLink for server-driven paging. The dataset segment may carry a @{label} version selector: dataset@current (the default, also what a bare dataset means), dataset@previous (the most recent version of the data before this one — maintenance snapshots such as compaction that changed no rows are skipped), dataset@{tag} (a named snapshot), or dataset@{snapshot_id} (a specific snapshot id). @current and @previous are resolved fresh on every page, so paging through them is not snapshot-isolated against concurrent writes; @{tag} and @{snapshot_id} are immutable and page consistently.

Path Parameters

  • workstream string [path; required]
  • collection string [path; required]
  • dataset string [path; required]

Query Parameters

  • $filter string | null [query; optional] OData $filter expression for row filtering. Operators: eq (equal), ne (not equal), lt/le/gt/ge (comparison), and/or/not (logical), contains/startswith/endswith (string), in_subnet (IPv4 CIDR containment). Case-sensitive. in_subnet(ip_column, 'cidr') is an Opteryx extension for IPv4-typed columns, e.g. in_subnet(src_addr, '192.168.4.0/24'); the PostgreSQL <<= operator is not valid OData syntax. Example: vendor eq 'Oracle' and price gt 100. Date/datetime literals must be unquoted per the OData v4 spec, e.g. shipped_date gt 2024-01-01 — a quoted date is compared as a string and raises a type-mismatch error. Date and time functions: now() (the query's wall clock, evaluated once per query so every row sees the same instant), year(), month(), day(), hour(), minute(), second() (each returns the named component of a date or timestamp as an integer, e.g. year(shipped_date) eq 2024), and date() (narrows a timestamp to its date part, e.g. date(created_at) eq 2024-01-01). The OData functions time(), mindatetime() and maxdatetime() are not implemented and are rejected with a message naming what to write instead. Rolling windows: combine now() with an ISO 8601 duration literal using add or sub, e.g. published_at ge now() sub duration'P30D' for the last 30 days. The duration syntax is duration'PnYnMnDTnHnMnS', optionally signed, e.g. duration'P1Y', duration'P18M', duration'PT12H', duration'-P7D'. Year and month durations are calendar-aware — duration'P1Y' means one calendar year and duration'P1M' one calendar month, so their length depends on the date they are applied to — while day, hour, minute and second durations are fixed spans (duration'P30D' is always exactly 30 × 24 hours).
  • $top integer | null [query; optional] Limit result rows (0-25000, default 100). Value 0 with $count=true returns count only. Returns @odata.nextLink if result is truncated.
  • $skip integer | null [query; optional] Skip N rows for pagination (server-driven). Requires $orderby: without a deterministic row order, paging duplicates some rows and drops others. Example: &$orderby=id asc&$skip=100 to fetch rows 101+. Combine with $top for paging.
  • $orderby string | null [query; optional] Sort by column(s): 'col1 asc, col2 desc'. Default ascending. Example: &$orderby=created_date desc
  • $count string | null [query; optional] Include total row count in response: 'true' or 'false' (default false). Use with $top=0 to get count only.
  • $select string | null [query; optional] Select specific columns: 'col1,col2,col3' or '*' for all (default all). Reduces payload size.
  • $search string | null [query; optional] Full-text search (not implemented; returns 501)
  • $apply string | null [query; optional] Data aggregation: groupby((col), aggregate(amount with sum as Total, $count as Count)). Aggregates are written as '$count as Alias' or 'col with as Alias', where is one of sum, average, min, max -- that list is exhaustive, and function-call forms such as sum(amount) are not accepted. Transformations chain with '/', e.g. filter(x gt 1)/groupby((col), aggregate($count as Count)); a groupby with no aggregate deduplicates, so a distinct count is groupby((a,b))/groupby((a), aggregate($count as N)).

Header Parameters

  • authorization string | null [header; optional]

Responses

  • 200 — Query succeeded; returns rows and pagination metadata (application/json object)
  • 400 — Invalid query: malformed $filter, unsupported $top value (not 0-25000), negative $skip, $skip without $orderby, invalid $count value, or invalid $apply expression. A malformed @{label} version selector also returns 400.
  • 401 — Missing or invalid authentication (no bearer token or basic auth)
  • 403 — Forbidden: authenticated but no permission for dataset
  • 404 — Dataset not found, or the @{label} version selector names a tag, snapshot, or previous version that does not exist
  • 501 — Unsupported query feature: $search or $expand not implemented
  • 422 — Validation Error (application/json HTTPValidationError)

Per-dataset OData EDMX metadata

Request: get/api/v4/{workstream}/{collection}/{dataset}/$metadata

Tags: OData v4

Returns OData $metadata (EDMX) for a single dataset, including column types and nullability, plus custom annotations carrying column statistics (Custom.Statistics.Min/Max, DistinctValueCount, NullCount, Distribution, and CIDR for IPv4 columns), the source type name (Custom.OriginalType, Custom.SourceType), the caller's access (Custom.Role, Custom.Policy), dataset and column descriptions (Custom.Description, Custom.LLMDescribed), current-snapshot metadata (Custom.Snapshot.Id/TotalRecords/TotalDataSize/CommitMessage/Author), physical sort order (Custom.SortOrder.Column/Direction), snapshot tags (Custom.Tags.Count and Custom.Tags, a Collection of Records with Name, SnapshotId and CreatedBy), and materialized-view state (Custom.MaterializedView.). Annotations are omitted where they do not apply to the dataset kind or are unavailable. The dataset segment may carry a @{label} version selector — dataset@current, dataset@previous, dataset@{tag}, or dataset@{snapshot_id} — and the Custom.Snapshot. and Custom.Tags annotations describe that version rather than the current one.

Path Parameters

  • workstream string [path; required]
  • collection string [path; required]
  • dataset string [path; required]

Header Parameters

  • authorization string | null [header; optional]

Responses

  • 200 — EDMX metadata document returned as XML (application/json object)
  • 400 — Malformed @{label} version selector, or the dataset kind does not support snapshot versioning
  • 401 — Missing or invalid authentication
  • 403 — Forbidden: no permission to view dataset metadata
  • 404 — Dataset not found in catalog, or the @{label} version selector names a tag, snapshot, or previous version that does not exist
  • 422 — Validation Error (application/json HTTPValidationError)