Skip to content

Headless BI API Documentation

Overview

Asemic Analytics provides a powerful headless Business Intelligence (BI) and semantic layer API that enables programmatic access to your data analytics. This API allows you to integrate advanced analytics capabilities directly into your applications, dashboards, and data pipelines without requiring a traditional BI interface.

Production Base URL: https://api.asemicanalytics.com/api/v1

Test Base URL: https://api-test.asemicanalytics.com/api/v1

Use Cases

  • Embedded Analytics: Integrate real-time analytics into your applications
  • Custom Dashboards: Build tailored visualization solutions
  • Data Pipelines: Automate data extraction and reporting
  • Semantic Layer Integration: Access pre-defined metrics and dimensions
  • Programmatic Reporting: Generate reports via API calls

Authentication

API Key Authentication

For headless BI use cases, authenticate using an API key in the Authorization header:

bash
Authorization: Apikey YOUR_API_KEY

Example Authentication

bash
curl -X GET 'https://api.asemicanalytics.com/api/v1/{appId}/datasources/daily' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Accept: application/json'

Core Endpoints

1. Get Data Sources and Metrics

Retrieve available metrics, KPIs, and dimensions from your semantic layer.

Endpoint: GET /{appId}/datasources/daily

Purpose: Discover available data entities, their properties, and metrics for querying.

Example Request:

bash
curl -X GET 'https://api.asemicanalytics.com/api/v1/{appId}/datasources/daily' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Accept: application/json'

Response Structure:

json
{
  "entity_registrations": {
    "id": "entity_registrations",
    "type": "action",
    "label": "Registrations",
    "columns": [
      {
        "id": "entity_id",
        "label": "Entity Id",
        "data_type": "string",
        "can_filter": true,
        "can_group_by": true,
        "authorized": true
      },
      {
        "id": "timestamp",
        "label": "Timestamp",
        "data_type": "datetime",
        "can_filter": true,
        "can_group_by": true,
        "authorized": true
      }
    ],
    "kpis": [],
    "dateFrom": null,
    "dateTo": null,
    "authorized": true
  },
  "user_wide": {
    "id": "user_wide",
    "type": "user_wide",
    "label": "Entity",
    "columns": [...],
    "kpis": [
      {
        "id": "revenue",
        "label": "Revenue",
        "is_daily_kpi": true,
        "is_cohort_kpi": false,
        "unit": {
          "symbol": "$",
          "isPrefix": true
        },
        "authorized": true
      }
    ]
  }
}

2. Submit Chart Query

Execute analytical queries to retrieve chart data with grouping, filtering, and time-based aggregation.

Endpoint: POST /{appId}/charts/submit

Purpose: Query your data with flexible parameters for visualization and analysis.

Request Parameters:

ParameterTypeDescriptionRequired
kpi_idstringThe KPI/metric identifierYes
date_intervalobjectDate range for the queryYes
date_interval.date_fromstringStart date (YYYY-MM-DD or ISO 8601)Yes
date_interval.date_tostringEnd date (YYYY-MM-DD or ISO 8601)Yes
compare_date_intervalobjectComparison date range for fetching data from a previous period (sets is_compare to true in response)No
compare_date_interval.date_fromstringComparison period start date (YYYY-MM-DD)No
compare_date_interval.date_tostringComparison period end date (YYYY-MM-DD)No
time_grainstringTime aggregation: hour, day, week, monthYes
x_axisstringX-axis dimension (e.g., "date", "timestamp")Yes
column_group_bysarrayDimensions to group byNo
group_by_limitintegerNumber of groups: positive for top N, negative for bottom NNo
sort_bystringAlternative metric to sort by (omit to use primary metric)No
sort_by_modestring"total", "change", or "impact" (default: "total")No
filtersarrayBasic filter conditions (deprecated, use property_filter_groups)No
property_filter_groupsarrayAdvanced filter groups including time travel filtersNo

Example 1: Daily Revenue by Provider

bash
curl -X POST 'https://api.asemicanalytics.com/api/v1/{appId}/charts/submit' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "kpi_id": "revenue",
    "date_interval": {
      "date_from": "2025-08-08",
      "date_to": "2025-08-11"
    },
    "time_grain": "day",
    "x_axis": "date",
    "column_group_bys": ["provider"],
    "group_by_limit": 5
  }'

Example 2: Query with Comparison Period

bash
curl -X POST 'https://api.asemicanalytics.com/api/v1/{appId}/charts/submit' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "kpi_id": "revenue",
    "date_interval": {
      "date_from": "2025-10-27",
      "date_to": "2025-10-29"
    },
    "compare_date_interval": {
      "date_from": "2025-10-24",
      "date_to": "2025-10-26"
    },
    "time_grain": "day",
    "x_axis": "date",
    "column_group_bys": ["provider"],
    "group_by_limit": 5
  }'

This query will fetch revenue data for October 27-29 along with comparison data from October 24-26. Rows with comparison data will have is_compare set to "true" in the response.

Example 3: Hourly Analysis with DateTime Precision

bash
curl -X POST 'https://api.asemicanalytics.com/api/v1/{appId}/charts/submit' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "kpi_id": "revenue",
    "date_interval": {
      "date_from": "2025-09-30T15:00:00",
      "date_to": "2025-09-30T20:00:00"
    },
    "time_grain": "hour",
    "x_axis": "timestamp",
    "column_group_bys": ["provider"],
    "group_by_limit": 5
  }'

Example 4: Advanced Query - Revenue in Markets with Highest User Growth

bash
curl -X POST 'https://api.asemicanalytics.com/api/v1/{appId}/charts/submit' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "kpi_id": "revenue",
    "date_interval": {
      "date_from": "2025-08-01",
      "date_to": "2025-08-31"
    },
    "time_grain": "day",
    "x_axis": "date",
    "column_group_bys": ["provider", "currency"],
    "group_by_limit": 10,
    "sort_by": "active_users",
    "sort_by_mode": "change",
    "filters": [
      {
        "column": "is_active",
        "operator": "=",
        "value": true
      },
      {
        "column": "revenue",
        "operator": ">",
        "value": 1000000
      }
    ]
  }'

This query shows Revenue data for the top 10 provider/currencies that had the biggest increase in active users (user growth), filtered to only active users with significant revenue.

Response Format:

json
{
  "total_overall": {
    "dimension_names": ["is_compare", "metric_id"],
    "metric_names": ["metric_value"],
    "rows": [
      {
        "dimensions": ["false", "kpi"],
        "metrics": [49883776913.61]
      }
    ]
  },
  "granular": {
    "dimension_names": ["group_by_0", "xaxis", "is_compare", "metric_id"],
    "metric_names": ["metric_value", "sort_by_value"],
    "rows": [
      {
        "dimensions": ["coin", "2025-09-30T15:00Z", "false", "kpi"],
        "metrics": [35573336082.27, 35284450111.94]
      }
    ]
  },
  "total": {
    "dimension_names": ["group_by_0", "is_compare", "metric_id"],
    "metric_names": ["metric_value", "sort_by_value"],
    "rows": [...]
  },
  "queries": [
    {
      "duration_seconds": 1.431,
      "rows": 30,
      "name": "main",
      "sql": "WITH ...",
      "cached": false,
      "bytesProcessed": 1243032717
    }
  ]
}

3. Data Backfill

Trigger data backfill operations for historical data processing.

Endpoint: POST /{appId}/datasources/backfill-userwide/{dateFrom}/{dateTo}

Purpose: Reprocess or backfill historical data for a specific date range.

Parameters:

  • appId: Your application identifier
  • dateFrom: Start date (YYYY-MM-DD format)
  • dateTo: End date (YYYY-MM-DD format)

Example Request:

bash
curl -X POST 'https://api.asemicanalytics.com/api/v1/{appId}/datasources/backfill-userwide/2025-01-01/2025-01-31' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Content-Type: application/json'

Query Parameters Guide

Time Grain Options

Control the temporal aggregation of your data:

  • custom - Custom time bucket
  • hour - Hourly aggregation
  • day - Daily aggregation
  • week - Weekly aggregation
  • month - Monthly aggregation
  • quarter - Quarterly aggregation
  • year - Yearly aggregation

Date Interval Formats

The API supports multiple date/time formats:

Date Only (Daily Precision):

json
{
  "date_from": "2025-08-08",
  "date_to": "2025-08-11"
}

DateTime (Hourly/Minute Precision):

json
{
  "date_from": "2025-09-30T15:00:00",
  "date_to": "2025-09-30T20:00:00"
}

Grouping, Sorting, and Limiting

Control how your data is grouped, sorted, and limited for optimal visualization:

Group By Multiple Dimensions:

json
{
  "column_group_bys": ["provider", "currency", "coin"],
  "group_by_limit": 10,
  "sort_by": "revenue",
  "sort_by_mode": "total"
}

Parameters Explained:

  • column_group_bys: Array of dimension columns to group by. The order matters - first dimension is the primary grouping.

  • group_by_limit: Controls which groups to return:

    • Positive number (e.g., 10): Returns top N groups with highest values
    • Negative number (e.g., -10): Returns bottom N groups with lowest values
    • The sorting criteria is determined by sort_by and sort_by_mode
  • sort_by: Selects which metric to use for sorting:

    • Omit this parameter: Uses the primary metric (kpi_id) for sorting
    • Specify another metric: Sort by a different metric than the one being displayed
    • Example: View revenue data but sort by user activity metrics
  • sort_by_mode: Determines how to calculate the sort value:

    • "total" (default): Uses the overall metric value for the entire period
    • "change": Sorts by the biggest/smallest changes over time
    • "impact": Sorts by contribution to overall metric value (how much each group affects the total)

Sorting Examples:

json
// Top 10 provider by revenue (default sorting)
{
  "kpi_id": "revenue",
  "column_group_bys": ["provider"],
  "group_by_limit": 10
}

// Bottom 5 provider by revenue
{
  "kpi_id": "revenue",
  "column_group_bys": ["provider"],
  "group_by_limit": -5
}

// Revenue by country, sorted by user growth
{
  "kpi_id": "revenue",
  "column_group_bys": ["country"],
  "group_by_limit": 10,
  "sort_by": "active_users",
  "sort_by_mode": "total"
}

// Top 10 products by biggest change in sales
{
  "kpi_id": "sales",
  "column_group_bys": ["product"],
  "group_by_limit": 10,
  "sort_by_mode": "change"
}

// Markets with highest impact on total revenue
{
  "kpi_id": "revenue",
  "column_group_bys": ["market"],
  "group_by_limit": 10,
  "sort_by_mode": "impact"
}

Filtering

Apply filters to narrow your data scope. The API supports various operators for different data types:

Available Filter Operators:

OperatorDescriptionUsageData Types
=Equals{"column": "status", "operator": "=", "value": "active"}All
!=Not equals{"column": "status", "operator": "!=", "value": "inactive"}All
>Greater than{"column": "volume", "operator": ">", "value": 1000000}Numeric, Date
<Less than{"column": "price", "operator": "<", "value": 100}Numeric, Date
>=Greater than or equal{"column": "count", "operator": ">=", "value": 10}Numeric, Date
<=Less than or equal{"column": "count", "operator": "<=", "value": 50}Numeric, Date
inIn list{"column": "provider", "operator": "in", "values": ["provider1", "provider2"]}All
not_inNot in list{"column": "status", "operator": "not_in", "values": ["cancelled", "failed"]}All
containsContains substring{"column": "name", "operator": "contains", "value": "USD"}String
not_containsDoesn't contain{"column": "description", "operator": "not_contains", "value": "test"}String
is_nullIs null{"column": "end_date", "operator": "is_null"}All
is_not_nullIs not null{"column": "start_date", "operator": "is_not_null"}All

Filter Examples:

json
{
  "filters": [
    {
      "column": "provider",
      "operator": "in",
      "values": ["provider1", "provider2", "provider3"]
    },
    {
      "column": "volume",
      "operator": ">",
      "value": 1000000
    },
    {
      "column": "currency",
      "operator": "contains",
      "value": "IDR"
    },
    {
      "column": "is_centralized",
      "operator": "=",
      "value": true
    }
  ]
}

Complex Filter Example:

json
{
  "kpi_id": "revenue",
  "date_interval": {
    "date_from": "2025-08-01",
    "date_to": "2025-08-31"
  },
  "time_grain": "day",
  "x_axis": "date",
  "filters": [
    {
      "column": "provider",
      "operator": "in",
      "values": ["provider1", "provider2"]
    },
    {
      "column": "revenue",
      "operator": ">=",
      "value": 5000000
    },
    {
      "column": "market",
      "operator": "is_not_null"
    }
  ]
}

## Time Traveling Filters

Time traveling filters enable sophisticated temporal analysis by filtering entities based on their properties or actions at different points in time. This goes beyond simple date range filtering to enable cohort analysis, retention tracking, and behavioral segmentation over time.

### Understanding Time-Based Cohorts

Time traveling filters answer questions like:
- "Show me revenue from users who were premium subscribers last month"
- "Track users who were active yesterday relative to each day"
- "Analyze users who spent more than $100 on average in January"
- "Find users who performed an action 30 days before their conversion"

### Filter Group Structure

Time traveling filters are organized within `property_filter_groups`. Each group can contain multiple filter types:

```json
{
  "property_filter_groups": [
    {
      "column_filters": [...],                              // Basic dimension filters
      "property_static_cohort_filters": [...],              // Static time-based property filters
      "property_dynamic_cohort_filters": [...],             // Dynamic time-based property filters
      "performed_action_static_cohort_filters": [...],      // Static action-based filters
      "performed_action_dynamic_cohort_filters": [...]      // Dynamic action-based filters
    }
  ]
}

Filter Types

1. Property Static Cohort Filters

Filter entities based on their properties during a specific fixed date range.

Structure:

json
{
  "property_static_cohort_filters": [
    {
      "window": {
        "from": "2025-01-01",
        "to": "2025-01-31"
      },
      "filters": [
        {
          "column_id": "subscription_type",
          "operation": "=",
          "value_list": ["premium"]
        }
      ],
      "aggregation_filters": []
    }
  ]
}

Use Case: "Show current month's revenue from users who had premium subscription in January 2025"

2. Property Dynamic Cohort Filters

Filter entities based on their properties relative to each data point in your query.

Structure:

json
{
  "property_dynamic_cohort_filters": [
    {
      "window": {
        "from": -7,    // Days before each data point
        "to": -1       // Days before each data point
      },
      "filters": [
        {
          "column_id": "status",
          "operation": "=",
          "value_list": ["active"]
        }
      ],
      "aggregation_filters": [
        {
          "column_id": "status",
          "operation": ">=",
          "value_list": ["3"],
          "aggregation_function": "count"
        }
      ]
    }
  ]
}

Use Case: "For each day, show users who had an active status at least three times in the previous 7 days"

3. Performed Action Static Cohort Filters

Filter entities who performed specific actions during a fixed time window.

Structure:

json
{
  "performed_action_static_cohort_filters": [
    {
      "action": "purchase",
      "window": {
        "from": "2025-01-01",
        "to": "2025-01-31"
      },
      "filters": [
        {
          "column_id": "product_category",
          "operation": "=",
          "value_list": ["electronics"]
        }
      ],
      "aggregation_filters": [
        {
          "column_id": "amount",
          "operation": ">",
          "value_list": ["100"],
          "aggregation_function": "avg"
        }
      ]
    }
  ]
}

Use Case: "Show users who made electronics purchases averaging over $100 in January 2025"

4. Performed Action Dynamic Cohort Filters

Filter entities who performed actions relative to the current time period.

Structure:

json
{
  "performed_action_dynamic_cohort_filters": [
    {
      "action": "login",
      "window": {
        "from": -30,   // 30 days before each data point
        "to": -1       // 1 day before each data point
      },
      "filters": [
        {
          "column_id": "device_type",
          "operation": "=",
          "value_list": ["mobile"]
        }
      ],
      "aggregation_filters": [
        {
          "column_id": null,    // null means count of events
          "operation": ">=",
          "value_list": ["5"],
          "aggregation_function": "count"
        }
      ]
    }
  ]
}

Use Case: "For each day, show users who logged in via mobile at least 5 times in the previous 30 days"

Aggregation Filters

Aggregation filters apply mathematical functions to event properties over the time window:

Available Aggregation Functions:

  • count - Number of occurrences
  • sum - Total sum of values
  • avg - Average value
  • min - Minimum value
  • max - Maximum value
  • distinct - Count of unique values

Example:

json
{
  "aggregation_filters": [
    {
      "column_id": "order_value",
      "operation": ">",
      "value_list": ["500"],
      "aggregation_function": "sum"    // Total spent > 500
    },
    {
      "column_id": "order_value",
      "operation": ">=",
      "value_list": ["50"],
      "aggregation_function": "avg"    // Average order value >= 50
    }
  ]
}

Complex Example: Multi-Cohort Analysis

bash
curl -X POST 'https://api.asemicanalytics.com/api/v1/{appId}/charts/submit' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "kpi_id": "revenue",
    "date_interval": {
      "date_from": "2025-03-01",
      "date_to": "2025-03-31"
    },
    "time_grain": "day",
    "x_axis": "date",
    "property_filter_groups": [
      {
        "column_filters": [
          {
            "column_id": "country",
            "operation": "in",
            "value_list": ["US", "UK", "CA"]
          }
        ],
        "property_static_cohort_filters": [
          {
            "window": {
              "from": "2025-01-01",
              "to": "2025-01-31"
            },
            "filters": [
              {
                "column_id": "registration_source",
                "operation": "=",
                "value_list": ["organic"]
              }
            ],
            "aggregation_filters": []
          }
        ],
        "performed_action_dynamic_cohort_filters": [
          {
            "action": "purchase",
            "window": {
              "from": -60,
              "to": -30
            },
            "filters": [],
            "aggregation_filters": [
              {
                "column_id": null,
                "operation": ">=",
                "value_list": ["2"],
                "aggregation_function": "count"
              }
            ]
          }
        ]
      }
    ]
  }'

This complex query shows:

  • March 2025 daily revenue
  • From users in US, UK, or Canada
  • Who registered organically in January 2025
  • And made at least 2 purchases between 30-60 days before each date

Time Window Reference

Static Windows:

  • Use ISO date strings: "from": "2025-01-01", "to": "2025-01-31"
  • Inclusive date range

Dynamic Windows:

  • Use negative integers for days before: "from": -7, "to": -1
  • Use positive integers for days after: "from": 1, "to": 7
  • 0 represents the current data point day
  • Example: "from": -30, "to": 0 means "last 30 days including today"

Common Use Cases

  1. Retention Analysis

    json
    // Users who were active on day 1 after registration
    {
      "performed_action_dynamic_cohort_filters": [{
        "action": "login",
        "window": {"from": 1, "to": 1},
        "filters": [],
        "aggregation_filters": []
      }]
    }
  2. High-Value Customer Segmentation

    json
    // Users who spent over $1000 in their first 30 days
    {
      "performed_action_dynamic_cohort_filters": [{
        "action": "purchase",
        "window": {"from": 0, "to": 30},
        "aggregation_filters": [{
          "column_id": "amount",
          "operation": ">",
          "value_list": ["1000"],
          "aggregation_function": "sum"
        }]
      }]
    }
  3. Churned User Analysis

    json
    // Users who were active 30-60 days ago but not in last 30 days
    {
      "performed_action_dynamic_cohort_filters": [
        {
          "action": "activity",
          "window": {"from": -60, "to": -30},
          "aggregation_filters": [{
            "column_id": null,
            "operation": ">",
            "value_list": ["0"],
            "aggregation_function": "count"
          }]
        },
        {
          "action": "any_event",
          "window": {"from": -30, "to": 0},
          "aggregation_filters": [{
            "column_id": null,
            "operation": "=",
            "value_list": ["0"],
            "aggregation_function": "count"
          }]
        }
      ]
    }

Response Data Structure

Understanding the Response

The API returns data in a tabular format optimized for visualization:

  1. total_overall: Grand total across all data
  2. granular: Time-series data with all dimensions
  3. total: Totals grouped by dimensions
  4. queries: Query performance metadata

Data Tables Explained

Dimension Names: Column headers for categorical data

  • group_by_0, group_by_1: Grouped dimensions in order
  • xaxis: Time dimension
  • is_compare: Comparison period flag
  • metric_id: Metric identifier

Metric Names: Column headers for numerical values

  • metric_value: The actual metric value
  • sort_by_value: Value used for sorting

Working with Results

javascript
// Example: Processing API response
const response = await fetch(apiUrl, options);
const data = await response.json();

// Extract time series data
const timeSeries = data.granular.rows.map(row => ({
  market: row.dimensions[0],
  timestamp: row.dimensions[1],
  value: row.metrics[0]
}));

// Get totals by group
const totals = data.total.rows.map(row => ({
  market: row.dimensions[0],
  total: row.metrics[0]
}));

Performance Optimization

Query Performance Metrics

Each response includes performance metadata:

json
{
  "queries": [
    {
      "duration_seconds": 1.431,
      "rows": 30,
      "name": "main",
      "cached": false,
      "bytesProcessed": 1243032717
    }
  ]
}

Best Practices

  1. Use Appropriate Time Grains: Match time grain to your visualization needs
  2. Limit Group By Cardinality: Use group_by_limit to control result size
  3. Leverage Caching: Repeated identical queries may be cached
  4. Optimize Date Ranges: Query only the data you need
  5. Filter Early: Apply filters to reduce data processing

Common Use Cases

1. Time Series Dashboard

bash
# Daily metrics for the last 30 days
curl -X POST 'https://api.asemicanalytics.com/api/v1/{appId}/charts/submit' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "kpi_id": "active_entities",
    "date_interval": {
      "date_from": "2025-08-01",
      "date_to": "2025-08-31"
    },
    "time_grain": "day",
    "x_axis": "date"
  }'

2. Comparative Analysis

bash
# Compare metrics across dimensions
curl -X POST 'https://api.asemicanalytics.com/api/v1/{appId}/charts/submit' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "kpi_id": "revenue",
    "date_interval": {
      "date_from": "2025-08-01",
      "date_to": "2025-08-31"
    },
    "time_grain": "week",
    "x_axis": "date",
    "column_group_bys": ["provider", "currency"],
    "group_by_limit": 10
  }'

3. Real-time Monitoring

bash
# Hourly metrics for today
curl -X POST 'https://api.asemicanalytics.com/api/v1/{appId}/charts/submit' \
  -H 'Authorization: Apikey YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "kpi_id": "revenue",
    "date_interval": {
      "date_from": "2025-09-30T00:00:00",
      "date_to": "2025-09-30T23:59:59"
    },
    "time_grain": "hour",
    "x_axis": "timestamp"
  }'

Error Handling

HTTP Status Codes

  • 200 OK - Request successful
  • 400 Bad Request - Invalid parameters or query
  • 401 Unauthorized - Invalid or missing API key
  • 403 Forbidden - Access denied to requested resource
  • 404 Not Found - Resource or endpoint not found
  • 429 Too Many Requests - Rate limit exceeded
  • 500 Internal Server Error - Server error

Error Response Format

json
{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "Invalid API key: 2582c9af-5e59-473d-9123-9ec4019a1606",
    "details": {}
  }
}

Common Error Scenarios

  1. Invalid API Key

    • Verify your API key is correct
    • Check key permissions for the requested resource
  2. Invalid Date Range

    • Ensure date_from is before date_to
    • Use supported date formats
  3. Unknown KPI or Column

    • Verify against /datasources/daily endpoint
    • Check authorization for specific metrics

SDK and Integration Examples

JavaScript/TypeScript

javascript
class BedrockAPI {
  constructor(apiKey, appId) {
    this.apiKey = apiKey;
    this.appId = appId;
    this.baseUrl = 'https://api.asemicanalytics.com/api/v1';
  }

  async getMetrics() {
    const response = await fetch(
      `${this.baseUrl}/${this.appId}/datasources/daily`,
      {
        headers: {
          'Authorization': `Apikey ${this.apiKey}`,
          'Accept': 'application/json'
        }
      }
    );
    return response.json();
  }

  async queryChart(params) {
    const response = await fetch(
      `${this.baseUrl}/${this.appId}/charts/submit`,
      {
        method: 'POST',
        headers: {
          'Authorization': `Apikey ${this.apiKey}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(params)
      }
    );
    return response.json();
  }
}

// Usage
const api = new BedrockAPI('YOUR_API_KEY', 'your-app-id');
const data = await api.queryChart({
  kpi_id: 'revenue',
  date_interval: {
    date_from: '2025-08-01',
    date_to: '2025-08-31'
  },
  time_grain: 'day',
  x_axis: 'date'
});

Python

python
import requests
from datetime import datetime, timedelta

class BedrockAPI:
    def __init__(self, api_key, app_id):
        self.api_key = api_key
        self.app_id = app_id
        self.base_url = 'https://api.asemicanalytics.com/api/v1'
        self.headers = {
            'Authorization': f'Apikey {api_key}',
            'Content-Type': 'application/json'
        }

    def get_metrics(self):
        url = f'{self.base_url}/{self.app_id}/datasources/daily'
        response = requests.get(url, headers=self.headers)
        return response.json()

    def query_chart(self, params):
        url = f'{self.base_url}/{self.app_id}/charts/submit'
        response = requests.post(url, json=params, headers=self.headers)
        return response.json()

# Usage
api = BedrockAPI('YOUR_API_KEY', 'your-app-id')
data = api.query_chart({
    'kpi_id': 'revenue',
    'date_interval': {
        'date_from': '2025-08-01',
        'date_to': '2025-08-31'
    },
    'time_grain': 'day',
    'x_axis': 'date'
})

Support and Resources

  • API Status: Check system status at status.asemicanalytics.com
  • Rate Limits: Monitor your usage in response headers
  • Data Freshness: Most metrics updated in real-time or near real-time
  • Historical Data: Available based on your subscription plan

Changelog

Version 1.0 (Current)

  • Core headless BI functionality
  • Semantic layer with predefined metrics
  • Flexible date/time filtering including datetime precision
  • Multi-dimensional grouping and aggregation
  • Data backfill capabilities
  • Performance query metadata

Last Updated: November 2025API Version: v1For technical support, contact support@asemic.me