Aggregate Table

https://{your-workspace-slug}.{region}.xata.sh/db/db_branch_name/tables/table_name/aggregate
Expected Parameters
NameDescriptionInRequiredSchema
db_branch_nameThe DBBranchName matches the pattern `{db_name}:{branch_name}`. pathstring
table_nameThe Table namepathstring

Run Aggregattions Over a Table

POST  https://{your-workspace-slug}.{region}.xata.sh/db/db_branch_name/tables/table_name/aggregate

This endpoint allows you to run aggragations (analytics) on the data from one table. While the summary endpoint is served from a transactional store and the results are strongly consistent, the aggregate endpoint is served from our columnar store and the results are only eventually consistent. On the other hand, the aggregate endpoint uses a store that is more appropiate for analytics, makes use of approximative algorithms (e.g for cardinality), and is generally faster and can do more complex aggregations.

For usage, see the API Guide.

Request Body Type Definition
type AggregateTable = {
    filter?: FilterExpression;
    aggs?: AggExpressionMap;
};

/**
 * @minProperties 1
 */
type FilterExpression = {
    $exists?: string;
    $existsNot?: string;
    $any?: FilterList;
    $all?: FilterList;
    $none?: FilterList;
    $not?: FilterList;
} & {
    [key: string]: FilterColumn;
};

/**
 * The description of the aggregations you wish to receive.
 * 
 * @example {"totalCount":{"count":"*"},"dailyActiveUsers":{"dateHistogram":{"column":"date","interval":"1d"},"aggs":{"uniqueUsers":{"uniqueCount":{"column":"userID"}}}}}
 */
type AggExpressionMap = {
    [key: string]: AggExpression;
};

type FilterList = FilterExpression | FilterExpression[];

type FilterColumn = FilterColumnIncludes | FilterPredicate | FilterList;

/**
 * The description of a single aggregation operation. It is an object with only one key-value pair.
 * The key represents the aggreagtion type, while the value is an object with the configuration of
 * the aggreagtion.
 */
type AggExpression = {
    count?: CountAgg;
} | {
    sum?: SumAgg;
} | {
    max?: MaxAgg;
} | {
    min?: MinAgg;
} | {
    average?: AverageAgg;
} | {
    uniqueCount?: UniqueCountAgg;
} | {
    dateHistogram?: DateHistogramAgg;
} | {
    topValues?: TopValuesAgg;
} | {
    numericHistogram?: NumericHistogramAgg;
};

/**
 * @maxProperties 1
 * @minProperties 1
 */
type FilterColumnIncludes = {
    $includes?: FilterPredicate;
    $includesAny?: FilterPredicate;
    $includesAll?: FilterPredicate;
    $includesNone?: FilterPredicate;
};

type FilterPredicate = FilterValue | FilterPredicate[] | FilterPredicateOp | FilterPredicateRangeOp;

/**
 * Count the number of records with an optional filter.
 */
type CountAgg = {
    filter?: FilterExpression;
} | ("*");

/**
 * The sum of the numeric values in a particular column.
 */
type SumAgg = {
    /*
     * The column on which to compute the sum. Must be a numeric type.
     */
    column: string;
};

/**
 * The max of the numeric values in a particular column.
 */
type MaxAgg = {
    /*
     * The column on which to compute the max. Must be a numeric type.
     */
    column: string;
};

/**
 * The min of the numeric values in a particular column.
 */
type MinAgg = {
    /*
     * The column on which to compute the min. Must be a numeric type.
     */
    column: string;
};

/**
 * The average of the numeric values in a particular column.
 */
type AverageAgg = {
    /*
     * The column on which to compute the average. Must be a numeric type.
     */
    column: string;
};

/**
 * Count the number of distinct values in a particular column.
 */
type UniqueCountAgg = {
    /*
     * The column from where to count the unique values.
     */
    column: string;
    /*
     * The threshold under which the unique count is exact. If the number of unique
     * values in the column is higher than this threshold, the results are approximative.
     * Maximum value is 40,000, default value is 3000.
     */
    precisionThreshold?: number;
};

/**
 * Split data into buckets by a datetime column. Accepts sub-aggregations for each bucket.
 */
type DateHistogramAgg = {
    /*
     * The column to use for bucketing. Must be of type datetime.
     */
    column: string;
    /*
     * The fixed interval to use when bucketing.
     * It is fromatted as number + units, for example: `5d`, `20m`, `10s`.
     *
     * @pattern ^(\d+)(d|h|m|s|ms)$
     */
    interval?: string;
    /*
     * The calendar-aware interval to use when bucketing. Possible values are: `minute`,
     * `hour`, `day`, `week`, `month`, `quarter`, `year`.
     */
    calendarInterval?: "minute" | "hour" | "day" | "week" | "month" | "quarter" | "year";
    /*
     * The timezone to use for bucketing. By default, UTC is assumed.
     * The accepted format is as an ISO 8601 UTC offset. For example: `+01:00` or
     * `-08:00`.
     *
     * @pattern ^[+-][01]\d:[0-5]\d$
     */
    timezone?: string;
    aggs?: AggExpressionMap;
};

/**
 * Split data into buckets by the unique values in a column. Accepts sub-aggregations for each bucket.
 * The top values as ordered by the number of records (`$count`) are returned.
 */
type TopValuesAgg = {
    /*
     * The column to use for bucketing. Accepted types are `string`, `email`, `int`, `float`, or `bool`.
     */
    column: string;
    aggs?: AggExpressionMap;
    /*
     * The maximum number of unique values to return.
     *
     * @default 10
     * @maximum 1000
     */
    size?: number;
};

/**
 * Split data into buckets by dynamic numeric ranges. Accepts sub-aggregations for each bucket.
 */
type NumericHistogramAgg = {
    /*
     * The column to use for bucketing. Must be of numeric type.
     */
    column: string;
    /*
     * The numeric interval to use for bucketing. The resulting buckets will be ranges
     * with this value as size.
     *
     * @minimum 0
     */
    interval: number;
    /*
     * By default the bucket keys start with 0 and then continue in `interval` steps. The bucket
     * boundaries can be shiftend by using the offset option. For example, if the `interval` is 100,
     * but you prefer the bucket boundaries to be `[50, 150), [150, 250), etc.`, you can set `offset`
     * to 50.
     *
     * @default 0
     */
    offset?: number;
    aggs?: AggExpressionMap;
};

type FilterValue = number | string | boolean;

/**
 * @maxProperties 1
 * @minProperties 1
 */
type FilterPredicateOp = {
    $any?: FilterPredicate[];
    $all?: FilterPredicate[];
    $none?: FilterPredicate | FilterPredicate[];
    $not?: FilterPredicate | FilterPredicate[];
    $is?: FilterValue | FilterValue[];
    $isNot?: FilterValue | FilterValue[];
    $lt?: FilterRangeValue;
    $le?: FilterRangeValue;
    $gt?: FilterRangeValue;
    $ge?: FilterRangeValue;
    $contains?: string;
    $startsWith?: string;
    $endsWith?: string;
    $pattern?: string;
};

/**
 * @maxProperties 2
 * @minProperties 2
 */
type FilterPredicateRangeOp = {
    $lt?: FilterRangeValue;
    $le?: FilterRangeValue;
    $gt?: FilterRangeValue;
    $ge?: FilterRangeValue;
};

type FilterRangeValue = number | string;
Possible Responses
Status CodeDescriptionExample Response/Type Definition
200OK
{
  "aggs": {
    "dailyUniqueUsers": {
      "values": [
        {
          "key": "2022-02-22T22:22:22Z",
          "uniqueUsers": 134
        },
        {
          "key": "2022-02-23T22:22:22Z",
          "uniqueUsers": 90
        }
      ]
    }
  }
}
400Bad Request
type AggregateTable = {
    id?: string;
    message: string;
};
401Authentication Error
{
  "message": "invalid API key"
}
404Example response
type AggregateTable = {
    id?: string;
    message: string;
};
5XXUnexpected Error