# Overview

Welcome to the Rated slaOS Developer Documentation ✨

{% hint style="info" %}
Rated slaOS is an all-in-one solution for building, monitoring, managing and enforcing software SLAs.&#x20;
{% endhint %}

**Rated slaOS is for:**&#x20;

* Operationally excellent, customer minded **Vendors of SLAs**
* **Consumers of SLAs** with large vendor surfaces that need managing

**With Rated** **slaOS you can:**

* collect and aggregate data (logs or metrics) across your services
* define and monitor Service Level Indicators (SLIs) and Service Level Objectives (SLOs)&#x20;
* deploy Service Level Agreements (SLAs) on a per org, integration, or customer basis
* showcase service reliability via shareable customer dashboards

**Our documentation will guide you through how to:**

* push your data (logs or metrics) to slaOS&#x20;
* create and consume SLIs and SLOs
* deploy SLA dashboards for your customers

If you're new to slaOS, head over to the [Getting started](/onboarding-your-data/getting-started) section!

{% hint style="info" %}
For any questions not covered in the docs, feel free to reach to our team at 📧[hello@rated.network](emailto:hello@rated.network).&#x20;
{% endhint %}


# Quickstart

Get started with slaOS in a flash

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Pushing data to slaOS</strong></td><td>How to link your data to slaOS, prerequisites and code examples</td><td><a href="/pages/Ol5lcngEBx7WJD6TshF7">/pages/Ol5lcngEBx7WJD6TshF7</a></td><td><a href="/files/MVgZlmEefDeTwfgvurmw">/files/MVgZlmEefDeTwfgvurmw</a></td></tr><tr><td><strong>Integrations</strong></td><td>Supported logging and monitoring stacks and how to's</td><td><a href="/pages/okmRho4vZBtrgis7Hv3L">/pages/okmRho4vZBtrgis7Hv3L</a></td><td><a href="/files/7NIvoQjlaiTvDbpZuAEh">/files/7NIvoQjlaiTvDbpZuAEh</a></td></tr><tr><td><strong>Key features</strong></td><td>Overview of the core functionality of slaOS by Rated</td><td><a href="/pages/ziZ9Tq39ZxQvS2bDGqQi">/pages/ziZ9Tq39ZxQvS2bDGqQi</a></td><td><a href="/files/5UjuR9PyLpOiftaZem8v">/files/5UjuR9PyLpOiftaZem8v</a></td></tr><tr><td><strong>Writing queries</strong></td><td>Best practices and overview of the capabilities of the slaOS query editor</td><td><a href="/pages/iHax8U9OsWGOfx4uqsUN">/pages/iHax8U9OsWGOfx4uqsUN</a></td><td><a href="/files/5oJMEdPdSuRQonVqduwc">/files/5oJMEdPdSuRQonVqduwc</a></td></tr><tr><td><strong>SLIs, Os and As</strong></td><td>Tutorials on buiding Service Level Indicators, Objectives and Agreements</td><td><a href="/pages/kJtM545ueaVYifuNLSiR">/pages/kJtM545ueaVYifuNLSiR</a></td><td><a href="/files/8o2NXtwrhZHCKGBveJcl">/files/8o2NXtwrhZHCKGBveJcl</a></td></tr><tr><td><strong>SLA Portal</strong></td><td>How to enable dashboards to explose the SLA status to your customers</td><td><a href="/pages/FEElrk4GQ01WqsVIKcGR">/pages/FEElrk4GQ01WqsVIKcGR</a></td><td><a href="/files/WX7dw402hs9vtYOLTHW2">/files/WX7dw402hs9vtYOLTHW2</a></td></tr></tbody></table>


# Key Features

Overview of the core functionality of slaOS by Rated

slaOS is designed to handle the broadest possible spectrum of SLAs and SLOs. From standard software metrics such as *uptime*, *latency*, and *error rates*, to more advanced use cases like *data freshness*, *AI model drift* , *spam detection* and *mean time to detect (MTTD)* . Beyond software, it supports SLOs like *customer response time*, and *service resolution times* amongst others.

Here's a brief run through of our key features:

## Query Builder

With Rated slaOS, you can work with logs, metrics, or any combination of data types and sources. Our query builder allows you to construct multiple queries and define relationships between them, capturing  performance indicators like latency, uptime, throughput, data freshness, or availability.&#x20;

<figure><img src="/files/iuri1U0f4EJdootXLQnt" alt=""><figcaption></figcaption></figure>

## SLA Engine

We recognise that service levels are promised to customers individually and should be upheld as such. The SLA engine allows you to compute, monitor, and manage Service Level Agreements (SLAs) on a per-customer basis. Configure custom service levels for each client, tailoring your commitments to match the expectations you've set.&#x20;

<figure><img src="/files/iyhGOIR78lFcBONbBWor" alt=""><figcaption></figcaption></figure>

## SLA Portal

Build trust and transparency with your customers or vendors through customisable, shareable SLA dashboards. They offer real-time insights into your service's performance, including SLA status, service performance over time, and breach history.

<figure><img src="/files/0kM7WAqVlGwr6iR1Yh00" alt=""><figcaption></figcaption></figure>

## Admin Environment

The admin interface is your SLA command centre. Set up different configurations, experiment with different service targets, and push live SLAs with ease. Get a bird's-eye view of all your SLAs and manage everything from a single, intuitive interface.

<figure><img src="/files/JMcb5M4aePtfP6n9hwrs" alt=""><figcaption></figcaption></figure>

## Reports

Keep both internal and external stakeholders informed with reports on SLA compliance, SLO trends, and service health.&#x20;

`[COMING SOON]`

## Verifiable On-chain

Add an extra layer of trust and accountability to your SLAs with verifiable, on-chain SLA statuses.&#x20;

`[COMING SOON]`


# Demo

For vendors :: turn 1080p ON

{% embed url="<https://drive.google.com/file/d/1rq8iCMdHC51Fa2AwoLAYu_0If5Elif_U/view?usp=sharing>" %}

{% hint style="info" %}
Join the closed beta [here](https://rated.co/closed-beta)!
{% endhint %}


# Getting started

Picking the right path to onboard your data to slaOS

The first step to getting onboarded to slaOS, is to connect and start pushing relevant logs and/or metrics the system. These could be logs and metrics from your own data warehouse, or they could originate from third party data sources.&#x20;

When integrating with slaOS, selecting the appropriate data ingestion method is a critical decision that can significantly impact your system's performance, scalability, and operational efficiency.&#x20;

<figure><img src="/files/TTn6kK2Wpi6Jse0KRGkb" alt="" width="563"><figcaption></figcaption></figure>

{% hint style="info" %}
We allow for both pushing data to the system yourself, and letting us do most of the heavy lifting with a suite of integration agents on popular monitoring stacks.&#x20;
{% endhint %}

This guide offers a comprehensive comparison of the available ingestion methods to help you make an informed choice based on your specific technical requirements and operational constraints.

## **Overview of ingestion paths**

There are 3 ways in which you can push data to Rated. These are:&#x20;

<div><figure><img src="/files/mS6XrKjzhfeKYHpuhBJS" alt=""><figcaption></figcaption></figure> <figure><img src="/files/uirXdpFpbPeZQlV6456N" alt=""><figcaption></figcaption></figure> <figure><img src="/files/HWlRppqrbUf7gjsh1qfF" alt=""><figcaption></figcaption></figure></div>

### **High level UX comparison**

<div><figure><img src="/files/wM1bEVfVfa7jSlDNgEI2" alt=""><figcaption></figcaption></figure> <figure><img src="/files/96wdCoz2Y6Nld9QzImdr" alt=""><figcaption></figcaption></figure> <figure><img src="/files/HEKCSnirkxjMENdYTCGy" alt=""><figcaption></figcaption></figure></div>

{% hint style="info" %}
The **Data API** requires you to send the right data directly to slaOS. Other methods use an indexer to process data before sending it to slaOS.
{% endhint %}

### **Data flow & supported sources**

<div><figure><img src="/files/REV7h5bhNsWlPbu3dUC8" alt=""><figcaption></figcaption></figure> <figure><img src="/files/9S8Ph2DJKsDbAOOeWUxT" alt=""><figcaption></figcaption></figure> <figure><img src="/files/wsA1jVXphgvmiTz63wpK" alt=""><figcaption></figcaption></figure></div>

### **Setup complexity & maintenance**&#x20;

<div><figure><img src="/files/VGwJMzjq94nxWTuISCM6" alt=""><figcaption></figcaption></figure> <figure><img src="/files/pepz7knagqpJbURbnjmF" alt=""><figcaption></figcaption></figure> <figure><img src="/files/uXZJhCIdz50w66y8vAAx" alt=""><figcaption></figcaption></figure></div>

{% hint style="info" %}
*Need help picking the right onboarding path?* Contact us at <hello@rated.co> for consultation.
{% endhint %}


# Prerequisites

Data hygiene requirements you need to be aware of before pushing to slaOS

Welcome to slaOS, home to the most flexible computation engine in the service level management space. Our platform is designed to accommodate a wide array of data sources and types, enabling you to build sophisticated computations that truly reflect your service's performance.

### Our Flexibility Promise

The slaOS engine is built to handle:

* Multiple data sources
* Various data types (logs, metrics, events)
* Different granularities (from raw event data to pre-aggregated metrics)
* Diverse key structures

Whether you're dealing with log-level data, metric-level information, event tables, or pre-aggregated statistics, slaOS is equipped to process and analyze it all.

### Requirements

There are a few key requirements for your data, in order to ensure a successful integration with slaOS:

* **Organization Identification**
  * Organization identification is crucial for determining **how your data is grouped and analyzed in slaOS**.
  * Each data point must be associated with a organization identifier.
  * This can be a customer ID, vendor ID, account number, or any unique identifier that distinguishes between your service consumers, integrations, vendors etc.

{% content-ref url="/pages/q4XZrOIxYA2Zyf24YLBm" %}
[Handling organization\_id](/onboarding-your-data/integrations/prometheus/handling-organization_id)
{% endcontent-ref %}

<details>

<summary>Real-world example</summary>

## Example: RPC Provider Service

Consider an RPC provider tracking:

* Request latency per downstream provider
* Overall API availability
* Request volume per provider

Your monitoring tracks:

* provider\_id (e.g., "alchemy", "infura")
* request\_type (e.g., "eth\_call", "eth\_getBalance")
* response\_status ("success", "error", "timeout")

**Provider-Specific Metrics**

```json
{
  "organization_id": "alchemy",
  "key": "rpc_requests",
  "values": {
    "latency": 0.23,
    "success_rate": 0.998,
    "requests": 1000000
  }
}
```

**Service-Wide Metrics** API availability tracked across all providers:

```json
{
  "organization_id": "global_service",
  "key": "api_status",
  "values": {
    "availability": 0.9999,
    "error_rate": 0.001
  }
}
```

This enables:

1. Per-provider latency SLOs (e.g., "Alchemy p95 latency < 250ms")
2. Global availability SLOs (e.g., "API availability > 99.99%")
3. Per-provider capacity planning

The `organization_id` could represent:

* Provider ID (tracking RPC providers)
* Region ID (monitoring geographical performance)
* Network ID (tracking network-specific metrics)
* Method ID (monitoring specific RPC methods)

Best Practices

* Avoid generic IDs (e.g., "default\_provider")
* Use "global\_service" for service-wide metrics
* Keep provider identification consistent
* Document your organization ID schema

</details>

{% hint style="warning" %}
`organization_id` applies to "customers" **for vendors** using slaOS, and conversely to "integrations" or your "vendors" if you are a **consumer** of services, standing up your SLA surface on the platform.
{% endhint %}

* **Timestamp**
  * Every event or metric should include a timestamp. This allows for time-based analysis and tracking of SLIs over time.
* **Consistent Keys**
  * A **key** identifies a unique data stream within **slaOS**. For example, keys like `api_logs` or `etl_logs` represent different types of data streams.&#x20;
  * Consistency within each data type is crucial. Define and stick to a naming convention for your metrics and event types to ensure accurate and efficient analysis.

### Next Steps

Once you've ensured your data meets these prerequisites:

1. Choose your preferred integration method (pre-built integrations, custom connectors direct, or the Data API).
2. Set up your data pipelines to start flowing data into slaOS.
3. Begin defining your Service Level Indicators (SLIs) and Objectives (SLOs) on slaOS.

{% hint style="info" %}
*Need help preparing your data to onboard to slaOS?* Contact us at <hello@rated.co>!
{% endhint %}


# Integrations

Perfect for a hassle-free setup without specific requirements for data locality

<figure><picture><source srcset="/files/rX3YCeYdWT8HehRVQQXh" media="(prefers-color-scheme: dark)"><img src="/files/HT42TyOo4HT7PsyBch16" alt=""></picture><figcaption></figcaption></figure>

## How to Get Started

1. **Sign Up:** Create an account at [app.rated.co](https://app.rated.co).
2. **Select Data Source:** Navigate to the Sources menu and choose your data source (e.g., CloudWatch).
3. **Onboard:** Follow the step-by-step guide to complete the onboarding process.

Integration-based ingestion allows you to collect data from your existing systems and services without modifying your application code.&#x20;

{% hint style="info" %}
This method is ideal if you're already using supported monitoring tools or have specific data sources you want to integrate with slaOS.
{% endhint %}

***

Are you self-hosting and/or want a new integration added to slaOS? Learn how to contribute:

{% content-ref url="/pages/hwHekNlkD4EW3jPgBBn8" %}
[Custom adapters](/onboarding-your-data/custom-adapters)
{% endcontent-ref %}


# Prometheus

## Prometheus Integration Guide

This guide provides comprehensive instructions for integrating your Prometheus metrics with slaOS. This integration enables slaOS to collect and analyze metrics from your Prometheus instances, helping you establish and monitor Service Level Indicators (SLIs).

## Prerequisites

### Required Components

* A running Prometheus instance
* Your slaOS account credentials
* (Optional) Access to configure authentication methods

{% hint style="warning" %}
**Important Note**: Currently, the integration requires an existing Prometheus server. If you only have applications exposing `/metrics` endpoints that need to be scraped, this is not yet supported but is coming soon!&#x20;

Please contact our support team if this is your use case - we're happy to help find alternative solutions and work with you to ensure a smooth onboarding experience when this feature becomes available.
{% endhint %}

## Integration Steps

### Step 1: Authentication Setup

If your Prometheus instance requires authentication or runs with TLS enabled, you'll need to configure the appropriate authentication method. This step is crucial for securing access to your metrics while ensuring slaOS can reliably collect them.

Choose one of the following authentication methods based on your Prometheus setup:

{% tabs %}
{% tab title="Self-hosted" %}
Choose one authentication method

#### **Basic Authentication**

```yaml
prometheus:
  base_url: "http://prometheus:9090"
  auth:
    username: "admin"
    password: "secret"
```

#### **Token Authentication**

```yaml
prometheus:
  base_url: "http://prometheus:9090"
  auth:
    token: "your-secret-token"
```

#### **Certificate Authentication (mTLS)**

```yaml
prometheus:
  base_url: "https://prometheus:9090"
  auth:
    cert_path: "/path/to/client.crt"
    key_path: "/path/to/client.key"
    verify_ssl: true
```

#### Google Cloud

```yaml
prometheus:
  base_url: "https://monitoring.googleapis.com/v1/projects/[PROJECT_ID]/location/global/prometheus"
  auth:
    gcloud_service_account_path: "/path/to/service-account.json"
    gcloud_target_principal: "prometheus-reader@[PROJECT_ID].iam.gserviceaccount.com"
    oauth_scopes:
      - "https://www.googleapis.com/auth/monitoring.read"
      - "https://www.googleapis.com/auth/cloud-platform"
```

Important setup steps:

1. Create a service account with these IAM roles:
   * `roles/monitoring.viewer`
   * `roles/iam.serviceAccountTokenCreator`
   * `roles/iam.serviceAccountUser`
2. Generate and download the service account key file (JSON)
3. Replace:
   * `[PROJECT_ID]` with your actual GCP project ID
   * `/path/to/service-account.json` with the actual path to your downloaded key file
4. Ensure the service account has the required OAuth scopes enabled in your GCP project.

{% hint style="info" %}
For more details check Github templates at [prometheus/auth.md](https://github.com/rated-network/rated-log-indexer/blob/main/templates/inputs/clients/prometheus/auth.md)
{% endhint %}
{% endtab %}

{% tab title="slaOS dashboard" %}
Coming soon!
{% endtab %}
{% endtabs %}

### Step 2: Set up your promQL queries

Set up your PromQL queries for collecting metrics. slaOS validates query correctness during the onboarding process to ensure reliable data collection. For self-hosted deployments, invalid query formats will prevent the indexer from starting.

#### Query Configuration

You can use the full power of PromQL to build your queries. For a comprehensive guide on writing PromQL queries, refer to the [official Prometheus documentation](https://prometheus.io/docs/prometheus/latest/querying/basics/).

{% embed url="<https://prometheus.io/docs/prometheus/latest/querying/basics/>" %}

Here are some common query patterns for monitoring service health:

{% tabs %}
{% tab title="Request rate" %}
Monitor the rate of incoming requests:

```yaml
queries:
  - query: 'sum by (customer_id) (rate(http_requests_total{job="api"}[5m]))'
    step: 
      value: 60
      unit: "s"
    slaos_metric_name: "request_rate"
    organization_identifier: "customer_id"
```

This query:

* Calculates request rate over 5-minute windows
* Groups results by customer\_id
* Returns data points every minute (step)
* Maps to "request\_rate" metric in slaOS
  {% endtab %}

{% tab title="Error Rate" %}
Calculate the ratio of errors to total requests:

```yaml
queries:
  - query: 'sum by (customer_id) (rate(http_errors_total{job="api"}[5m])) / sum by (customer_id) (rate(http_requests_total{job="api"}[5m]))'
    step:
      value: 60
      unit: "s"
    slaos_metric_name: "error_rate"
    organization_identifier: "customer_id"
```

This query:

* Computes error rate as errors/total requests
* Maintains customer-specific error rates
* Provides percentage of failed requests
* Updates every minute
  {% endtab %}

{% tab title="Latency percentiles" %}
Calculate 95th percentile latency from histogram buckets:

```yaml
queries:
  - query: 'histogram_quantile(0.95, sum by (le, customer_id) (rate(http_duration_seconds_bucket{job="api"}[5m])))'
    step:
      value: 60
      unit: "s"
    slaos_metric_name: "p95_latency"
    organization_identifier: "customer_id"
```

This query:

* Uses histogram\_quantile for p95 calculation
* Maintains the 'le' (less than or equal) label required for histograms
* Groups by customer\_id for per-customer latency
* Updates every minute
  {% endtab %}
  {% endtabs %}

#### Query Validation

slaOS performs several validations on your queries:

* Syntax correctness
* Label presence (especially for `organization_identifier`)
* Appropriate use of aggregation operators
* Correct histogram usage
* Valid time windows and steps

If validation fails:

* In cloud slaOS: The onboarding interface will show specific error messages
* In self-hosted slaOS: The indexer will log errors and fail to start

#### Best Practices

1. **Time Windows:** Use appropriate time windows for rate calculations

```yaml
rate(metric[5m])     # Good for high-traffic services
rate(metric[1m])     # May be noisy for low-traffic services
rate(metric[15m])    # Better for low-traffic services
```

2. **Step Selection**

When querying metrics, the step interval determines how frequently data points are sampled. Here are the key points about step configuration:

* We poll Prometheus integrations every 60 seconds (1 minute)
* Step sizes must be ≤ 60 seconds
* Step intervals should evenly divide into 60 seconds to ensure consistent metric sampling

For example, valid step intervals include: 1s, 2s, 3s, 4s, 5s, 6s, 10s, 12s, 15s, 20s, 30s, and 60s.

```yaml
step:  # Good for real-time monitoring
  value: 60
  unit: "s"    
step:  # High resolution but more resource intensive
  value: 15
  unit: "s"    
```

3. **Aggregation:** Include necessary labels in aggregations

```yaml
sum by (customer_id, endpoint) (...)    # Preserves endpoint information
sum by (customer_id) (...)              # More condensed view
```

For more complex queries or specific use cases, consult our support team or refer to the [Prometheus querying documentation](https://prometheus.io/docs/prometheus/latest/querying/basics/).

{% embed url="<https://prometheus.io/docs/prometheus/latest/querying/basics/>" %}

### Step 3: Configuration Setup

{% tabs %}
{% tab title="Self-hosted" %}
Combine the outcomes from Step 1 (Authentication) and Step 2 (Queries) into your main configuration file. Here's an example:

```yaml
yamlCopyinputs:
  - integration: prometheus
    slaos_key: prometheus_metrics
    type: metrics
    prometheus:
      base_url: "http://prometheus:9090"
      # Add your authentication configuration from Step 1 if needed
      auth:
        username: "admin"          # If using basic auth
        password: "secret"         # If using basic auth
        # Or
        token: "your-token"        # If using token auth
        # Or
        cert_path: "/path/to/cert" # If using mTLS
        key_path: "/path/to/key"   # If using mTLS
      # Add your queries from Step 2
      queries:
        - query: 'rate(http_request_duration_seconds_count{job="api"}[5m])'
          step: 
            value: 60
            unit: "s"
          slaos_metric_name: "http_request_rate"
          organization_identifier: "customer_id"
          fallback_org_id: "default_customer"
      # Connection settings
      timeout: 15.0
      pool_connections: 10
      pool_maxsize: 10
      max_parallel_queries: 5
      retry_backoff_factor: 0.1
      max_retries: 3
```

> **Tip**: For the latest configuration examples and templates, check our [GitHub repository](https://github.com/rated-network/rated-log-indexer/blob/main/templates/inputs/clients/prometheus/). We regularly update these templates with best practices and new features.
> {% endtab %}

{% tab title="slaOS dashboard" %}
Coming soon!
{% endtab %}
{% endtabs %}

<details>

<summary>Advanced settings for self-hosted</summary>

When running self-hosted slaOS, you have full control over connection settings. Here are the available parameters with recommended values:

```yaml
prometheus:
  # Request handling
  timeout: 15.0                # Request timeout in seconds
  max_retries: 3              # Maximum retry attempts
  retry_backoff_factor: 0.1   # Delay between retries (exponential backoff)

  # Connection pooling
  pool_connections: 10        # Initial pool size
  pool_maxsize: 10           # Maximum concurrent connections
  max_parallel_queries: 5     # Maximum concurrent queries
```

### Configuration Guidelines

1. **Timeout Settings**

```yaml
prometheus:
  timeout: 15.0    # Default: Good for most cases
  timeout: 30.0    # For complex queries or slower networks
  timeout: 5.0     # For simple queries, fast networks
```

2. **Connection Pool Optimization**

```yaml
# High-traffic setup
prometheus:
  pool_connections: 20
  pool_maxsize: 20
  max_parallel_queries: 10

# Low-traffic setup
prometheus:
  pool_connections: 5
  pool_maxsize: 5
  max_parallel_queries: 3
```

3. **Retry Strategy**

```yaml
# Aggressive retry
prometheus:
  max_retries: 5
  retry_backoff_factor: 0.2

# Conservative retry
prometheus:
  max_retries: 2
  retry_backoff_factor: 0.5
```

</details>

## Frequently Asked Questions (FAQ)

#### Authentication

**Q: Can I use multiple authentication methods simultaneously?** A: No, authentication methods are mutually exclusive. Choose one that best fits your security requirements.

**Q: How often should I rotate credentials?** A: Best practice is to rotate credentials every 90 days or immediately if compromised.

#### Organization Identification

**Q: What happens if the organization identifier is missing?** A: The integration will:

1. Use the `fallback_org_id` if configured
2. Stop with an error if no `fallback_org_id` is provided

**Q: Can I use different organization identifiers for different queries?** A: Yes, each query can specify its own `organization_identifier` and `fallback_org_id`.

#### Metrics and Queries

**Q: How oftQ: How often does slaOS collect metrics?** A: After initial backfilling of historical data, slaOS queries the data source every 60 seconds. The frequency of data points within each 60-second window is determined by the `step` parameter in your query configuration.

**Q: Can I query logs through Prometheus?** A: No, the Prometheus integration only supports metric queries. For log analysis, please use other supported integrations like CloudWatch. We plan to integrate promQL compatible log systems soon. <br>

For any additional questions or issues, please contact the slaOS support team on Slack.


# Handling organization\_id

## Multi-tenant API service sxample

Let's explore common scenarios using a real-world example of a multi-tenant API service. In this example, you're running an API that serves multiple organizations, and you want to monitor various metrics. Some metrics are naturally split by organization (like latency and request volume), while others are collected globally (like error rates).

The `organization_id` in these examples could represent different identifiers depending on your use case:

* `customer_id`: When serving multiple end customers (e.g., SaaS platform)
  * Email service monitoring delivery rates per business account
  * DEX monitoring liquidity provider positions
  * NFT marketplace tracking collection trading volume
* `vendor_id`: When aggregating metrics across different suppliers or partners
  * Marketplace measuring seller performance metrics
  * RPC node provider tracking request volumes
  * Oracle service monitoring price feed updates
* `service_id`: When monitoring multiple internal services or microservices
  * E-commerce tracking checkout service reliability
  * Bridge monitoring cross-chain transfers
  * Smart contract monitoring function calls
* `integration_id`: When tracking metrics for different third-party integrations
  * Payment platform monitoring gateway success rates
  * Multi-chain wallet tracking transaction status
  * DEX aggregator monitoring swap routes

### Scenario 1: Organization-Specific Metrics (Per-Organization Latency)

Context: Your API tracks request latency per organization, which is essential for:

* Monitoring individual organization experience
* Meeting specific SLAs per organization
* Identifying organization-specific performance issues

```prometheus
# Prometheus metrics
# Each request is tagged with organization_id
api_request_latency_seconds{organization_id="org123", endpoint="/api/v1/users"} 0.45
api_request_latency_seconds{organization_id="org456", endpoint="/api/v1/users"} 0.32

# slaOS configuration
queries:
  - query: 'histogram_quantile(0.95, sum by (le, organization_id) (rate(api_request_latency_seconds_bucket[5m])))'
    step: 
      value: 60
      unit: "s"
    slaos_metric_name: "p95_latency"
    organization_identifier: "organization_id"  # Each organization gets their own latency metrics
```

Use Case Examples:

* SaaS Platform: Track response times for each customer's API usage
* Marketplace: Monitor transaction processing times for different vendors
* Microservices: Measure inter-service communication latency
* Integration Platform: Track external API call latencies per integration

### Scenario 2: Service-Wide Metrics (Global Error Rates)

**Context:** Your API tracks error counts globally due to:

* Infrastructure limitations
* Metric collection setup
* No business need to track errors per organization

```prometheus
# Prometheus metrics
# Error counts are only tagged with status code
http_errors_total{status="500"} 10
http_errors_total{status="400"} 25
http_errors_total{status="200"} 1000
```

```yaml
# slaOS configuration
queries:
  - query: 'sum(rate(http_errors_total{status=~"5.."}[5m])) / sum(rate(http_errors_total[5m]))'
    step: 
      value: 60
      unit: "s"
    slaos_metric_name: "error_rate"
    fallback_org_id: "global_service"  # All error metrics go to a default organization
```

In this case:

* Error metrics don't have organization identification
* Using `fallback_org_id` assigns all error rates to a default organization
* Useful for service-wide SLAs or general monitoring
* All organizations reference the same error rate metrics

### Scenario 3: Mixed Metrics (Combined Approach)

```prometheus
# Organization-specific requests
api_requests_total{organization_id="org123", endpoint="/api/v1/users"} 150
api_requests_total{organization_id="org456", endpoint="/api/v1/orders"} 75

# Public endpoint requests (no organization_id)
api_requests_total{endpoint="/public/status"} 50
api_requests_total{endpoint="/health"} 25

# slaOS configuration
queries:
  - query: 'sum by (organization_id) (rate(api_requests_total[5m]))'
    step: 
      value: 60
      unit: "s"
    slaos_metric_name: "request_rate"
    organization_identifier: "organization_id"
    fallback_org_id: "public_endpoints"  # For requests without organization_id
```

#### Best Practices for Mixed Environments

**Consistent Labeling:**

```prometheus
# Good - consistent organization identification
api_latency_seconds{organization_id="org123", ...}
api_requests_total{organization_id="org123", ...}

# Avoid - inconsistent labeling
api_latency_seconds{organization_id="org123", ...}
api_requests_total{client="org123", ...}  # Different label name
```

**Clear Separation:**

```prometheus
queries:
  # Organization-specific latency
  - query: 'histogram_quantile(0.95, sum by (le, organization_id) (rate(api_latency_seconds_bucket[5m])))'
    organization_identifier: "organization_id"
    slaos_metric_name: "org_latency"

  # Global error rates
  - query: 'sum(rate(http_errors_total{status=~"5.."}[5m])) / sum(rate(http_errors_total[5m]))'
    fallback_org_id: "global_service"
    slaos_metric_name: "global_error_rate"
```

**Meaningful Fallback IDs:**

```prometheus
# Descriptive fallback IDs
fallback_org_id: "public_api_endpoints"    # Clear purpose
fallback_org_id: "unauthenticated_users"   # Clear purpose

# Avoid generic fallbacks
fallback_org_id: "default"                 # Too generic
fallback_org_id: "other"                   # Not descriptive
```

Remember:

* Choose the appropriate organization identifier based on your use case
* Not all metrics need to be split by organization
* Use fallback IDs thoughtfully and consistently
* Document your choices for future reference
* Consider future changes in metric collection
* Balance granularity with system complexity


# Privacy and Security

## End-to-End Data Flow with PII Handling

slaOS does not perform any hashing or transformation of identifiers - it works with the data exactly as it exists in your Prometheus metrics. If you have privacy concerns about sensitive data, you'll need to handle the hashing in your systems before the data reaches Prometheus.

{% content-ref url="/pages/Sfc56UyaMrSY8RetDf5a" %}
[Data hashing & transformation](/onboarding-your-data/filters/data-hashing-and-transformation)
{% endcontent-ref %}

Here's how the data flows:

1. **Metrics in Prometheus**

```yaml
# Prometheus metrics (with sensitive data)
api_requests_total{
    customer_id="super_secret_user",  # Sensitive data
    endpoint="/api/v1/users"
} 150
```

2. **PromQL Query Configuration**

```yaml
queries:
  - query: 'sum by (customer_id, endpoint) (rate(api_requests_total[5m]))'
    step: 
      value: 60
      unit: "s"
    slaos_metric_name: "request_rate"
    organization_identifier: "customer_id"
    
# In filters config:
filters:
  version: 1
  fields:
    - name: "customer_id"  # This tells the parser to reference customer_id label
      hash: true           # Hashes customer_id labels

```

3. **Resulting slaOS JSON Payload**

```json
{
  "organization_id": "hashedabc123...",  # Hashed value sent
  "timestamp": "2024-10-30T23:29:00Z",
  "key": "prometheus_metrics",
  "idempotency_key": "4ac1f5c3524c05b379d3a23932756e0f156f17638b528559e62bb06dd4efbe6b",
  "values": {
    "request_rate": 0.5,
    "endpoint": "/api/v1/users"
  }
}
```

## Key Points

* slaOS passes through identifiers exactly as they appear in Prometheus
* No hashing or transformation is performed by slaOS
* If you need to protect sensitive data, handle the hashing in your systems before it reaches Prometheus
* You are responsible for maintaining any mapping between original and hashed identifiers in your secure systems


# CloudWatch

This guide provides step-by-step instructions for integrating your Amazon Web Services (AWS) CloudWatch logs with slaOS. This integration allows slaOS to collect metrics, logs, and other critical data necessary to monitor your AWS environment effectively.

{% hint style="info" %}
The [app.rated.co](https://app.rated.co) interface guides you step-by-step, all the way through to a successful Cloudwatch integration! &#x20;
{% endhint %}

## Prerequisites

Before you begin, ensure you have the following:

* An active AWS account with administrative access
* Access to AWS Identity and Access Management (IAM)
* Your slaOS account credentials

## Integration Steps

### Step 1: Creating an AWS IAM Policy

To enable slaOS to access your CloudWatch logs, you need to create an AWS IAM policy with the necessary permissions.

1. **Log into AWS Management Console:** Navigate to the IAM service.
2. **Create a New Policy:** Use the JSON editor and paste the following policy document:

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Sid": "LogAccess",
         "Effect": "Allow",
         "Action": [
           "logs:FilterLogEvents",
           "logs:DescribeLogGroups"
         ],
         "Resource": "arn:aws:logs:*:*:*"
       }
     ]
   }
   ```
3. **Name the Policy:** Assign a name such as `RatedSLIQueryAccessPolicy`.
4. **Review and Create:** Complete the policy creation process.

### Step 2: Creating an AWS IAM User

Next, create an IAM user to associate with the slaOS integration.

1. **Navigate to IAM Users:** In the IAM console, click on "Users" in the left sidebar, then select "Add user."
2. **Configure User Details:**
   * Choose a username (e.g., `RatedIntegrationUser`).
   * Select "Access key - Programmatic access" for the AWS access type.
3. **Attach the Policy:**
   * On the permissions page, select "Attach existing policies directly."
   * Search for and select the `RatedSLIQueryAccessPolicy` created earlier.
4. **Finalize User Creation:** Review and create the user.

### Step 3: Generating and Managing Access Keys

Once the user is created, generate the access keys necessary for slaOS to access your logs.

1. **Download the Access Keys:** On the "Success" page, download the CSV file containing the access key ID and secret access key.
2. **Missed Download?** If you missed this step, you can generate a new secret access key for the IAM user later via the IAM console.

### Step 4: Submitting keys to slaOS

After generating your AWS access keys, the next step is to add these credentials to slaOS for verification:

{% tabs %}
{% tab title="slaOS dashboard" %}

1. During the onboarding process in the slaOS user interface, you'll be prompted to enter your AWS credentials.
2. Input your AWS Access Key ID and Secret Access Key in the designated fields.

<figure><img src="/files/K48lCFp7wocK78hkgQlC" alt="" width="375"><figcaption><p>slaOS integrations workflow for Cloudwatch</p></figcaption></figure>

3. The slaOS system will automatically verify your credentials to ensure they have the necessary permissions.
4. Depending on your integration needs, slaOS will verify access to logs, metrics, or both.
   {% endtab %}

{% tab title="Self-hosted" %}
If you're using a self-hosted version of slaOS, you'll need to manually add your AWS credentials to the configuration file:

1. Locate your slaOS configuration YAML file.
2. Add the following section to your YAML file, replacing the placeholder values with your actual AWS credentials:

```yaml
cloudwatch:
  region: us-east-1
  aws_access_key_id: AKIA6XXXXXXXXXX
  aws_secret_access_key: 5/XXXXXXXXXXXXXXXXXXXXXXXX
```

{% hint style="info" %}
For more detailed information about CloudWatch configuration in self-hosted environments, refer to the [self-hosted page](/onboarding-your-data/self-hosting) in our documentation. Alternatively, you can find example templates in our [GitHub repository](https://github.com/rated-network/rated-log-indexer).
{% endhint %}
{% endtab %}
{% endtabs %}

### Step 5: Selecting Log Groups and Streams

For slaOS to effectively query and parse your logs, it is essential to define the correct scopes. Scopes determine which parts of your log data will be accessible to slaOS, including the following:

* **Log Groups:** Specify the CloudWatch log groups that should be included.
* **Log Streams:** Define the log streams within each group that contain relevant data. It is not mandatory to specify this.

### Step 6: Using CloudWatch Filter Patterns (*Optional*)

When setting up your CloudWatch logs for slaOS, you may want to use CloudWatch's native `filter_pattern` tool to filter logs. This tool allows you to specify which logs should be included based on your defined patterns.

{% embed url="<https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html>" %}

{% hint style="danger" %}
slaOS does not verify the validity of the `filter_pattern` you provide. You are fully responsible for ensuring that your `filter_pattern` is correctly configured according to CloudWatch's native log filtering rules. Incorrect patterns may lead to missed log data or improper parsing.
{% endhint %}

## Frequently Asked Questions (FAQ)

### Can I restrict access to specific log groups or regions?

**Yes:** You can modify the `Resource` field in the IAM policy. For example:

* To restrict access to a specific region: `"arn:aws:logs:us-west-2:*:*"`
* To restrict access to specific log groups: `"arn:aws:logs:*:*:log-group:/aws/lambda/my-function:*"`

### What happens if I need to rotate my AWS access keys?

Generate new access keys in the AWS IAM console and update them in your slaOS integration settings. Ensure you delete the old keys after confirming the new ones work.

### How often does slaOS collect data from CloudWatch?

slaOS collects data in near real-time, typically with a delay of a few minutes depending on CloudWatch's own latency.

### Is it safe to use the `ingestion_key` in logs?

The `ingestion_key` is not an API key or bearer token and does not provide access to other slaOS functionalities. While it has limited access, it's important to understand its security implications:

{% tabs %}
{% tab title="slaOS-managed" %}
**Don't Worry:** If you're using the slaOS-managed cloud version, security measures are already in place to protect your `ingestion_key`. You don't need to handle these concerns directly.

slaOS manages:

* Built-in rate limiting and anomaly detection
* Isolation of your environment
* Key rotation as needed

You rarely need to handle or log the `ingestion_key` directly, further reducing any risk.
{% endtab %}

{% tab title="Self-hosted" %}
For Self-Hosted slaOS Users:

1. **Potential Risks:**
   * Unauthorized data injection
   * Resource consumption from large data volumes
2. **Security Recommendations:**
   * Treat as a secret; mask or remove from logs
   * Implement rate limiting
   * Monitor ingestion patterns for anomalies

If you suspect your data is being tampered with, you can contact slaOS support to refresh your keys.
{% endtab %}
{% endtabs %}

***

For any additional questions or issues, please contact the slaOS support team on Slack.


# Datadog

This guide provides step-by-step instructions for integrating your Datadog account with slaOS. This integration allows slaOS to collect metrics, logs, and other data from your Datadog account to monitor your services effectively.

{% hint style="info" %}
The [app.rated.co](https://app.rated.co) interface guides you step-by-step, all the way through to a successful Datadog integration! &#x20;
{% endhint %}

## Prerequisites

* An active Datadog account with administrative access
* Your slaOS account credentials

## Integration Steps

### Step 1: Create a Datadog API Key

1. Log in to your Datadog account.
2. Navigate to Organization Settings > API Keys.
3. On "API Keys" page click on "New Key".
4. Give your API key a name (e.g., `slaOS Integration`).
5. Copy the generated API key and store it securely.

### Step 2: Create a Datadog Application Key

1. Still on the Organization Settings click on "Application Keys" and then "New Key".
2. Give your application key a name (e.g., `slaOS App Key`).
3. Under Scope, click "Edit" and add `events_read`. This alows slaOS to read event data from your Datadog account.
4. Copy the generated application key and store it securely.

### Step 3: Provide Integration Details

You'll need to provide the following information to slaOS:

1. Datadog site (e.g., `datadoghq.com` for US1, `datadoghq.eu` for EU, etc.)
2. API Key
3. Application Key

{% tabs %}
{% tab title="slaOS-managed" %}

1. During the onboarding process in the slaOS user interface, you'll be prompted to enter your Datadog secrets.
2. The slaOS system will automatically verify your credentials to ensure they have the necessary permissions.
3. Depending on your integration needs, slaOS will verify access to logs, metrics, or both.
   {% endtab %}

{% tab title="Self-hosted" %}
If you're using a self-hosted version of slaOS, you'll need to manually add your Datadog credentials to the configuration file:

1. Locate your slaOS configuration YAML file.
2. Add the following section to your YAML file, replacing the placeholder values with your actual Datadog credentials:

```yaml
datadog:
    site: datadoghq.com
    api_key: your_datadog_api_key
    app_key: your_datadog_app_key

```

{% hint style="info" %}
For more detailed information about Datadog configuration in self-hosted environments, refer to the [self-hosted page](/onboarding-your-data/self-hosting) in our documentation. Alternatively, you can find example templates in our [GitHub repository](https://github.com/rated-network/rated-log-indexer).
{% endhint %}
{% endtab %}
{% endtabs %}

### Step 4: Configure Log Parsing

To set up effective SLI queries, slaOS needs to understand which parts of your logs are most relevant to your service's performance metrics. Provide the following information:

1. Specific fields from your logs to use in SLI queries.
2. Data type of each field (e.g., string, integer, float, datetime).
3. The field that specifies the user (e.g., id, api\_key) that the log event belongs to.
4. Any necessary transformations for these fields.

## Frequently Asked Questions (FAQ)

### How do I rotate my Datadog API or application keys?

Generate new keys in your Datadog account settings and update them in your slaOS integration settings. Be sure to revoke the old keys after confirming the new ones work.

### What data does slaOS collect from my Datadog account?

slaOS collects event data as specified in your log parsing configuration. It does not collect or access any other data from your Datadog account.

### How often does slaOS collect data from Datadog?

slaOS collects data in near real-time, typically with a delay of a few minutes depending on Datadog's own latency.

### Can I limit the scope of data slaOS can access?

Yes! You can create a limited-scope API key in Datadog with only the necessary permissions. Consult the Datadog documentation for instructions on creating custom API keys:

{% embed url="<https://docs.datadoghq.com/account_management/api-app-keys/>" %}

***

For any additional questions or issues, please contact the slaOS support team on Slack.


# Coming soon

A list of integrations on our roadmap.

<table data-card-size="large" data-column-title-hidden data-view="cards"><thead><tr><th data-type="files">Integration</th><th>Expected</th><th>Status<select><option value="QDEMP6U74QUV" label="In dev" color="blue"></option><option value="nVBjqeDEiLQy" label="Planned" color="blue"></option></select></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><a href="/files/sAAFPy8wxHwJKatofydW">/files/sAAFPy8wxHwJKatofydW</a></td><td>Q4 2024 </td><td><span data-option="nVBjqeDEiLQy">Planned</span></td><td></td></tr><tr><td><a href="/files/cK1CI4OmM0tebGYmqrLs">/files/cK1CI4OmM0tebGYmqrLs</a></td><td>Q4 2024</td><td><span data-option="nVBjqeDEiLQy">Planned</span></td><td></td></tr><tr><td><a href="/files/ugAoU8uCWRp2ZPM3jN1r">/files/ugAoU8uCWRp2ZPM3jN1r</a></td><td>Q4 2024</td><td><span data-option="nVBjqeDEiLQy">Planned</span></td><td></td></tr><tr><td><a href="/files/t81YQhlgNkiBx4LqALma">/files/t81YQhlgNkiBx4LqALma</a></td><td>Q1 2025 </td><td><span data-option="nVBjqeDEiLQy">Planned</span></td><td></td></tr><tr><td><a href="/files/1koVdxqYTPeBBWjhX03P">/files/1koVdxqYTPeBBWjhX03P</a></td><td>Q1 2025</td><td><span data-option="nVBjqeDEiLQy">Planned</span></td><td></td></tr><tr><td><a href="/files/IO9xaCabyW70jvxFiTGO">/files/IO9xaCabyW70jvxFiTGO</a></td><td>Q1 2025 </td><td><span data-option="nVBjqeDEiLQy">Planned</span></td><td></td></tr></tbody></table>


# Self-hosting

Run the slaOS indexer on your own infrastructure

The self-hosted solution allows you to run the slaOS indexer on your own infrastructure, providing greater control over your data. This option is ideal for organizations with strict data locality requirements or those who prefer to manage their own infrastructure.

## System requirements

* Minimum `X` CPU cores, `XGB` RAM
* `XXXGB` storage (scalable based on data volume)
* Network access to your data sources and slaOS API endpoints

## Setting up the self-hosted solution

1. **Download the Docker Image:** Obtain the slaOS indexer from our repository.
2. **Install the Indexer:** Deploy the indexer on your infrastructure, whether it’s Docker, Kubernetes, or a bare-metal environment.
3. **Configure the Indexer:** Modify the configuration file in YAML format to suit your specific data sources and slaOS account details. Here's a sample configuration:

<details>

<summary>Configuration file example</summary>

```yaml
inputs:
  - integration: cloudwatch
    integration_prefix: "cloudwatch_logs_test"
    type: logs
    cloudwatch:
      region: us-east-1
      aws_access_key_id: AKIAXXXXX
      aws_secret_access_key: X/XXX+XXX
      logs_config:
        log_group_name: "/aws/apprunner/prod-rated-api/"
        filter_pattern: '{ $.event = "request_finished" }'
    filters:
      version: 1
      log_format: json_dict
      fields:
        - key: "status_code"
          field_type: "integer"
          path: "status_code"
        - key: "customer_id"
          field_type: "string"
          path: "user.id"
        - key: "path"
          field_type: "string"
          path: "request_route_name"
    offset:
      type: redis
      override_start_from: true
      start_from: 1724803200000
      start_from_type: bigint
      redis:
        host: redis
        port: 6379
        db: 0


output:
  type: "console"
  console:
    verbose: true

secrets:
  use_secrets_manager: false

```

</details>

4. **Start the Indexer:** Launch the indexer and verify data ingestion via the slaOS dashboard.

{% hint style="info" %}
Always refer to the most up-to-date documentation available on our [GitHub](https://github.com/rated-network/rated-log-indexer) repository for detailed setup instructions and best practices.
{% endhint %}


# Configuration yaml

This guide provides a detailed explanation of the configuration YAML file used for the slaOS self-hosted indexer solution. Understanding this configuration is crucial for setting up and customizing your self-hosted indexer.

{% embed url="<https://github.com/rated-network/rated-log-indexer>" %}

## Configuration File Structure

The configuration is organized into three main sections:

1. `inputs`: A list of input configurations
2. `output`: Configuration for the output destination
3. `secrets`: Configuration for secrets management

{% hint style="warning" %}
Our [GitHub repository](https://github.com/rated-network/rated-log-indexer) maintains an extensive collection of up-to-date and thoroughly tested configuration templates. These templates cover all sections of the indexer configuration and include the latest supported integrations.
{% endhint %}

Let's explore each section in detail.

### Section 1: Input

The `inputs` section defines the data sources for your indexer. It is a list of integration objects, you can run more than one input/integration concurrently fully managed.

It specifies which integration to use and the necessary configuration for that integration.

```yaml
inputs:
  - integration: <integration_type>
    slaos_key: <unique_identifier>
    type: <logs_or_metrics>
    <integration_specific_config>
    filters: <optional_filter_config>
    offset: <offset_config>
```

<details>

<summary>Example configuration for Cloudwatch logs</summary>

```
 inputs:
  - integration: cloudwatch
    integration_prefix: "cloudwatch_logs_test"
    type: logs
    cloudwatch:
      region: us-east-1
      aws_access_key_id: AKIAXXXXX
      aws_secret_access_key: X/XX+XXXX
      logs_config:
        log_group_name: "/aws/apprunner/prod-rated-api/32cf02da3ba8495f87ad79806b0521e5/application"
        filter_pattern: '{ $.event = "request_finished" }'
    filters:
      version: 1
      log_format: json_dict
      log_example: { }
      fields:
        - key: "status_code"
          value: "22"
          field_type: "integer"
          path: "status_code"
        - key: "organization_id"
          value: "e6bd1f68367b4eee993f247e7301107a"
          field_type: "string"
          path: "user.id"
        - key: "path"
          value: "operators"
          field_type: "string"
          path: "request_route_name"
    offset:
      type: redis
      override_start_from: true
      start_from: 1724803200000
      start_from_type: bigint
      redis:
        host: redis
        port: 6379
        db: 0
```

Extract from GitHub Repository [input template examples](https://github.com/rated-network/rated-log-indexer/tree/main/templates/inputs).

</details>

**Key components**

* **`integration`**: Specifies the data source (e.g., cloudwatch, `datadog`). This determines which integration-specific configuration is required.
* **`slaos_key`**: A unique identifier for the input. This is used to differentiate data submitted to slaOS when multiple integrations are running.
  * **Example**: If `slaos_key` is set to "*prod\_api\_cloudwatch*", a data point with key "*status\_code*" will be submitted to slaOS as "*prod\_api\_cloudwatch\_status\_code*".
  * **Validation**: Each `slaos_key` must be unique across all inputs to avoid conflicts.
  * **Context**: The `slaos_key` is mandatory when using more than one integration. It prevents conflicts in data submitted to slaOS by prefixing all data points from this input with the specified prefix.
* **`type`**: Specifies "logs" or "metrics". This determines how the input data is processed and which additional configurations (like filters) are required.
* **`filters`**: Configuration for data filtering. This is only applicable and required for log-type inputs. It defines how log data should be parsed and transformed.
* **`offset`**: Configuration for tracking the last processed position in the data stream. This ensures idempotent operation and allows for efficient data processing, especially after interruptions or for backfills.

{% hint style="info" %}
Tested input examples can be found in [inputs template directory](https://github.com/rated-network/rated-log-indexer/tree/main/templates/inputs) on our GitHub repository.
{% endhint %}

#### Filters section

The `filters` section defines how the indexer processes and transforms input data. This is where you specify the log format and define the fields you want to extract. It is only applicable for log-type inputs and is not needed for metrics.

**Structure**

```yaml
filters:
  version: <version_number>
  log_format: <format_type>
  log_example: <example_log_entry>
  fields:
    - key: <field_name>
      path: <json_path>
      field_type: <data_type>
```

**Example**

```yaml
filters:
  version: 1
  log_format: json_dict
  log_example: { "timestamp": "2023-01-01T00:00:00Z", "level": "INFO", "message": "Example log" }
  fields:
    - key: "timestamp"
      path: "timestamp"
      field_type: "timestamp"
    - key: "level"
      path: "level"
      field_type: "string"
      hash: true
    - key: "message"
      path: "message"
      field_type: "string"
```

For a more detailed explanation of how filters work, please refer to:

{% content-ref url="/pages/CjwxFTBSg5t2WiXhkqpB" %}
[Filters](/onboarding-your-data/filters)
{% endcontent-ref %}

#### Offset section

The `offset` section is responsible for tracking the last processed position in the input data stream. This ensures idempotent operation and allows for efficient data processing.

**Structure**

```yaml
offset:
  type: <storage_type>
  override_start_from: <boolean>
  start_from: <start_position>
  start_from_type: <data_type>
  <storage_specific_config>
```

* The `override_start_from` option is particularly useful for backfills, allowing you to specify a starting point for data processing.

**Examples**

{% tabs %}
{% tab title="Redis offset" %}

```yaml
offset:
  type: redis
  override_start_from: true
  start_from: 1724803200000
  start_from_type: bigint
  redis:
    host: redis
    port: 6379
    db: 0
```

{% endtab %}

{% tab title="Postgres offset" %}

```yaml
offset:
  type: postgres
  override_start_from: true
  start_from: 123456789
  start_from_type: bigint
  postgres:
    table_name: offset_tracking
    host: localhost
    port: 5432
    database: postgres
    user: postgres
    password: postgres
```

{% endtab %}

{% tab title="slaOS offset" %}

```yaml
offset:
  type: slaos
  override_start_from: true
  start_from: 123456789
  start_from_type: bigint
  ingestion_id: ingestion-id
    ingestion_key: ingestion-key
    ingestion_url: https://api.rated.co/v1/ingest
    datastream_filter:
      key: datastream_key
      organization_id: customer_one
```

{% hint style="info" %}
The `datastream_filter` is used to identify the offset related to this specific instance of the indexer. The `key` is a required field and corresponds to the `slaos_key` associated with this instance.&#x20;

We also provide an optional filter parameter on `organization_id`. This should only be used if you have multiple instances of the indexer using the same `key`.  A typical example of when this might happen is when indexing metrics for a resource used for particular customer or organization.\
\
For values that have been hashed in the `filters` config, prefix with `hash:` (e.g., `hash:value`).
{% endhint %}
{% endtab %}
{% endtabs %}

{% embed url="<https://github.com/rated-network/rated-log-indexer/tree/main/templates/offset>" %}

### Section 2: Output

The `output` section defines where the processed data should be sent. slaOS supports two output types: `rated` (for sending data to direct ingestion API) and `console` (for debugging purposes).

```yaml
output:
  type: rated
  rated:
    ingestion_id: your_ingestion_id
    ingestion_key: your_ingestion_key
    ingestion_url: https://rated.live/v1/ingest
```

To obtain the `ingestion_id` and `ingestion_key`, you need to create an account on the slaOS platform. Once logged in, navigate to the API management section where you can generate and manage your ingestion credentials.

To use console output for debugging, you can configure it like this:

```yaml
output:
  type: console
  console:
    verbose: true
```

### Section 3: Secrets

The `secrets` section allows you to use a secrets manager for sensitive configuration values.

```yaml
secrets:
  use_secrets_manager: true
  
```

If `use_secrets_manager` is set to `true`, any value in the YAML that starts with "secret:" will be resolved using the specified secrets manager. For example:

```yaml
secrets:
  use_secrets_manager: true
  provider: aws
  aws:
    region: us-west-2
    aws_access_key_id: fake_access_key
    aws_secret_access_key: fake_secret_key
```

Let's break down each part of this configuration:

* `use_secrets_manager: true`: This enables the use of the secrets manager.
* `provider: aws`: This specifies that we're using AWS as our secrets provider.
* `aws`: This section contains the configuration specific to AWS:
  * `region: us-west-2`: The AWS region where your secrets are stored.
  * `aws_access_key_id`: Your AWS access key ID for accessing the secrets manager.
  * `aws_secret_access_key`: Your AWS secret access key for accessing the secrets manager.

<details>

<summary>IAM Policy - using AWS Secrets manager</summary>

If you are self-hosting slaOS and using AWS Secrets Manager to store sensitive information like access keys, you need to configure additional IAM permissions.

1. **Create a Secrets Manager Policy:** Use the following JSON document to create a policy.

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Sid": "SecretsManagerAccess",
         "Effect": "Allow",
         "Action": [
           "secretsmanager:GetSecretValue",
           "secretsmanager:DescribeSecret"
         ],
         "Resource": "arn:aws:secretsmanager:*:*:secret:*"
       }
     ]
   }
   ```
2. **Attach the Policy:** Name the policy `RatedSecretsManagerAccessPolicy` and attach it to the IAM user created for slaOS.

</details>

## Conclusion

Understanding and properly configuring your self-hosted slaOS indexer is key to effectively processing your data. Always refer to the most up-to-date documentation on our GitHub repository for detailed setup instructions and best practices.

If you encounter any issues or have questions about your configuration, don't hesitate to reach out to our support team at [hello@rated.network](emailto:hello@rated.network) or consult the community forums.


# Running locally with Docker

### Prerequisites

* Docker installed and running on your system
* Basic familiarity with YAML configuration
* Terminal/command-line access

### Setup Instructions

#### 1. Pull the Docker Image

First, pull the latest rated-log-indexer image from Docker Hub:

```bash
docker pull ratedlabs/rated-log-indexer
```

#### 2. Configure the Indexer

1. Create a copy of the example configuration file:

   ```bash
   cp rated-config.example.yaml config/rated-config.yaml
   ```
2. Open `rated-config.yaml` in your preferred text editor and modify the settings according to your needs:
   * Configure your desired integrations
   * Set up the output section
   * Adjust any additional parameters

{% hint style="info" %}
Refer to the Configuration Templates section for detailed instructions on configuring specific integrations and outputs.
{% endhint %}

#### 3. Run the Container

Launch the rated-log-indexer container using the following command:

```bash
docker run \
  --name rated-indexer \
  --volume "$(pwd)"/config/rated-config.yaml:/indexer/config/rated-config.yaml \
  --restart unless-stopped \
  ratedlabs/rated-log-indexer
```

This command:

* Mounts your local configuration file into the container
* Runs the container in the foreground
* Automatically removes the container when it stops (`--rm` flag)

### Verification

After starting the container, you should see:

1. Initialization logs
2. Configuration loading confirmation
3. Integration connection status
4. Indexing progress indicators

### Troubleshooting

If you encounter issues:

1. Verify your configuration file syntax
2. Check that all required credentials are properly set
3. Ensure Docker has sufficient permissions to access the mounted configuration file
4. Review the container logs for specific error messages


# Running with Kubernetes (k8s)

This guide explains how to deploy and run the Rated Log Indexer in a Kubernetes environment.

### Prerequisites

* Access to a Kubernetes cluster
* `kubectl` CLI tool installed and configured
* Basic understanding of Kubernetes concepts (ConfigMaps, Deployments)
* Rated Log Indexer credentials and configuration details

### Setup Instructions

#### 1. Prepare Configuration

1. Navigate to the `config` directory where you'll find `rated-configmap.example.yaml`
2. Create your configuration file:

```bash
cp config/rated-configmap.example.yaml config/rated-configmap.yaml
```

3. Modify the configuration file with your specific settings

The example file includes both the ConfigMap for your indexer configuration and the Deployment specification needed for Kubernetes.

#### 2. Deploy to Kubernetes

Apply the configurations to your cluster:

```bash
kubectl apply -f config/rated-configmap.yaml
```

#### 3. Verify Deployment

Check the status of your deployment:

```bash
# Check deployment status
kubectl get deployments rated-log-indexer

# Check pod status
kubectl get pods -l app=rated-log-indexer

# View logs
kubectl logs -l app=rated-log-indexer
```

### Configuration Reference

#### ConfigMap Settings

The ConfigMap contains your Rated Log Indexer configuration in YAML format. Key sections include:

* `inputs`: Configure your data sources
  * `integration`: Specify the integration type (e.g., cloudwatch)
  * `filters`: Define how to process and transform logs
  * `offset`: Configure ingestion tracking and start points
* `output`: Configure where processed data should be sent
* `secrets`: Manage sensitive information

{% content-ref url="/pages/tliP1y9xUtQaJQBYMo72" %}
[Configuration yaml](/onboarding-your-data/self-hosting/configuration-yaml)
{% endcontent-ref %}

#### Deployment Settings

The Deployment configuration defines how the indexer runs in your cluster:

* `replicas`: Number of indexer instances (default: 1)
* `image`: Docker image to use (default: `ratedlabs/rated-log-indexer:latest`)
* `volumeMounts`: Configuration file mounting
* `volumes`: ConfigMap volume definition

{% embed url="<https://hub.docker.com/r/ratedlabs/rated-log-indexer/tags>" %}

### Security Considerations

1. **Sensitive Data**: Consider using Kubernetes Secrets instead of ConfigMap for sensitive values
2. **RBAC**: Ensure appropriate RBAC policies are in place for the indexer pod

### Troubleshooting

#### Common Issues

1. **Pod Startup Failures**

```bash
kubectl describe pod -l app=rated-log-indexer
```

2. **Configuration Issues**

```bash
# View ConfigMap
kubectl get configmap indexer-config -o yaml

# Check container logs
kubectl logs -l app=rated-log-indexer
```

3. **Resource Constraints**

```bash
kubectl top pod -l app=rated-log-indexer
```

### Maintenance

#### Updating Configuration

1. Update the ConfigMap:

```bash
kubectl apply -f config/rated-configmap.yaml
```

2. Restart the pods:

```bash
kubectl rollout restart deployment rated-log-indexer
```

#### Version Updates

To update the indexer version:

```bash
kubectl set image deployment/rated-log-indexer indexer=ratedlabs/rated-log-indexer:new-version
```

### Best Practices

1. Always use version tags for the Docker image instead of `latest`
2. Implement appropriate resource requests and limits
3. Set up monitoring and alerting
4. Regularly backup your configuration
5. Use namespaces to isolate the indexer deployment
6. Implement liveness and readiness probes


# Data API

Ideal for applications that can emit metrics and logs directly or for custom monitoring

This guide provides detailed information on using the slaOS direct data ingestion API (Data API). It covers authentication, request format, field descriptions, and best practices for submitting data to slaOS.

{% hint style="info" %}
*Need help troubleshooting the Data API?* Contact us at <hello@rated.co> for consultation.
{% endhint %}

## Ingestion Endpoint

To send events to slaOS, you need to use the following endpoint:

<pre><code><strong>https://api.rated.co/v1/ingest/{ingestion_id}/{ingestion_key}
</strong></code></pre>

### **Understanding `ingestion_id` and `ingestion_key`**

* **`ingestion_id`**: A unique identifier for your slaOS project. This value is specific to your organization and is used to identify the source of the data being ingested.
* **`ingestion_key`**: A secret key that is also specific to your organization and tied to your data ingestion activities. This key works in tandem with the `ingestion_id` to authenticate your data submissions.

To find the **Ingestion Key** and **ID** in the UI, navigate to **Settings** and then select **General (Organization)**. You can access this by going to this [link](https://app.rated.co/settings/general).&#x20;

{% hint style="warning" %}
It’s important to note that the `ingestion_key` is **not** an API key or bearer token—it does not provide access to other slaOS functionalities and cannot be used to retrieve or manipulate data outside of the ingestion endpoint.
{% endhint %}

### **Additional security Considerations**

1. **Refreshing the Ingestion Key**: You can refresh your ingestion key through the slaOS UI if you suspect it has been compromised (Settings -> General)
2. **HTTPS**: Always use HTTPS to encrypt data in transit.

## Request Format

The API accepts JSON payloads. Here's an example of a valid request:

{% tabs %}
{% tab title="Single event" %}

```json
{
  "organization_id": "cust_12345",
  "key": "api_requests",
  "timestamp": "2024-08-15T10:30:45Z",
  "values": {
    "status_code": 200,
    "response_time": 0.145
  },
  "idempotency_key": "req_abc123"
}
```

{% endtab %}

{% tab title="Batch event" %}

<pre class="language-json"><code class="lang-json">[
<strong>  {
</strong>    "organization_id": "cust_12345",
    "key": "api_requests",
    "timestamp": "2024-08-15T10:30:45Z",
    "values": {
      "status_code": 200,
      "response_time": 0.145
    },
    "idempotency_key": "req_abc123"
  },
  {
    "organization_id": "cust_12345",
    "key": "api_requests",
    "timestamp": "2024-08-15T10:31:45Z",
    "values": {
      "status_code": 200,
      "response_time": 0.45
    },
    "idempotency_key": "req_def456"
  }
]
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The API accepts JSON payloads where the body can include either a single event or a list of events.
{% endhint %}

### Field Descriptions

1. **organization\_id** (*string*, required)
   * Unique identifier for the **customer** or **vendor** associated with this event.&#x20;
   * See [Prerequisites](/onboarding-your-data/prerequisites) for a refresher of the different uses of `organization_id`.
2. **key** (*string*, required)
   * A unique identifier for the type of event or metric being recorded.
   * This is not a service name, but rather a metric identifier. You can have multiple metrics for a single service, product, or project.
   * Example: "api\_requests", "database\_queries", "order\_processing"
3. **timestamp** (*string*, required)
   * The time the event occurred.
   * Accepted formats:
     * ISO 8601: `YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]`
     * Unix timestamp (as a string)
4. **values** (*object*, required)
   * Key-value pairs representing the metrics for this event.
   * Keys are metric names, values are the corresponding measurements.
   * Value types are dynamically derived from the first payload sent under the same `key`.  However, only timestamps, strings, floats, and integers are supported.
5. **idempotency\_key** (*string*, optional)
   * Idempotency key, a unique identifier for this specific event.
   * Used for deduplication if the same event is sent multiple times.

### Limitations

* The total size of each event payload should not exceed 200KB.
* There are no specific restrictions on the number or types of key/value pairs in the `values` object.

## Ingestion endpoint example&#x20;

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST https://your-slaos-domain.com/v1/ingest/61dcde60-f40a-4a55-a303-911f2c2c4def/n3K9y3NiaOXVnw6deLQ5AQ \
     -H 'Content-Type: application/json' \
     -d '{
       "organization_id": "cust_12345",
       "key": "api_requests",
       "timestamp": "'"$(date -u +"%Y-%m-%dT%H:%M:%SZ")"'",
       "values": {
         "status_code": 200,
         "response_time": 0.145
       },
       "local_identifier": "req_abc123"
     }'
```

{% endtab %}

{% tab title="Python" %}

```bash
import httpx
import json
from datetime import datetime

url = "https://your-slaos-domain.com/v1/ingest/your-ingestion-id/your-ingestion-key"
payload = {
    "organization_id": "cust_12345",
    "key": "api_requests",
    "timestamp": datetime.utcnow().isoformat() + "Z",
    "values": {
        "status_code": 200,
        "response_time": 0.145
    },
    "local_identifier": "req_abc123"
}

headers = {"Content-Type": "application/json"}

with httpx.Client() as client:
    response = client.post(url, json=payload, headers=headers)
    print(f"Status Code: {response.status_code}")
    print(f"Response: {response.text}")
```

{% endtab %}

{% tab title="TS/JS" %}

```typescript
import fetch from 'node-fetch';

const url = 'https://your-slaos-domain.com/v1/ingest/your-ingestion-id/your-ingestion-key';
const payload = {
    organization_id: 'cust_12345',
    key: 'api_requests',
    timestamp: new Date().toISOString(),
    values: {
        status_code: 200,
        response_time: 0.145
    },
    local_identifier: 'req_abc123'
};

const headers = { 'Content-Type': 'application/json' };

fetch(url, {
    method: 'POST',
    body: JSON.stringify(payload),
    headers: headers
})
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}
{% endtabs %}

## Best Practices and Considerations

1. **Consistency in `key` usage**: Use consistent `key` values for similar types of events to ensure proper aggregation and analysis in slaOS.
2. **Timestamp accuracy**: Ensure that the `timestamp` is as accurate as possible to the time the event occurred.
3. **Deduplication**: Use the `local_identifier` field to prevent duplicate event processing if you're unsure about the success of a previous submission.


# Example implementation

This guide will walk you through the process of instrumenting your application to send API latency metrics to slaOS using the direct ingestion API. We'll provide code examples in JSON-compatible formats and cover best practices to ensure efficient and reliable data submission.

## **Building an SLA tracking API Uptime and Latency**

To make things more concrete we will use the examples of sending relevant data to slaOS, in order to build an **Uptime** and a **Latency** **SLA**, drawing from logs that are emitted by your application directly to slaOS (without the use of any integrations).

<details>

<summary>Sample log message</summary>

```bash
{
    "event": "request_finished",
    "request_route_name": "/v0/eth/operators/{operator_id}/apr",
    "request_headers": {
        "host": "api.rated.network",
        "user-agent": "undici",
        "accept": "*/*",
        "accept-encoding": "br, gzip, deflate",
        "accept-language": "*",
        "authorization": "Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.******.***Y48gQ",
        "content-type": "application/json",
        "sec-fetch-mode": "cors",
        "x-envoy-expected-rq-timeout-ms": "120000",
        "x-envoy-external-address": "45.88.222.59",
        "x-forwarded-for": "45.88.222.59",
        "x-forwarded-proto": "https",
        "x-rated-network": "mainnet",
        "x-request-id": "0cc0a428-a3bc-435c-9bcb-d0aa57511185"
    },
    "request_query_params": {
        "window": "7d",
        "idType": "withdrawalAddress"
    },
    "peer_ip": "40.86.210.59",
    "status_code": 200,
    "request_method": "GET",
    "cache_hit": true,
    "request_path": "/v0/eth/operators/0xcd615270ab3a7a3a262a4e49935d002278c76b78/apr",
    "content_length": 244,
    "request_id": "0cc0a428-a3bc-435c-9bcb-d0aa5751176",
    "user": {
        "id": "bb856d6a365946459ad04816fb70aj6d",
        "org": null
    },
    "org": {
        "id": "531ccc57c17a4b418236931e96fb8047",
        "company_name": "ACME Corporation",
        "pricing_tier": "growth"
    },
    "token": {
        "id": "4fc60598816b4db78644c511d2a8l9c7",
        "expires_at": "2024-12-30T16:35:24.602333+00:00"
    },
    "took": 0.03523564338684082,
    "level": "info",
    "logger": "rated.api",
    "timestamp": 1719931770.556692
}
```

</details>

### **Uptime SLA**

* The SLI that we would like to extract here would be the `status_code` returned for each log event produced from the `request_finished` event type.
* The SLO we generate here would count each none 5xx `status_code` as a good outcome for uptime, which will be divided over the total number of events to produce the measured objective.
* The SLA we can create here for each customer would require a threshold set on the SLO, i.e >= 99.5% uptime.

{% hint style="info" %}
The configuration of SLIs, SLOs and SLAs happens within the slaOS UI. This step is solely focused on getting the right data, in the right format, in slaOS
{% endhint %}

### **Latency SLA**

* The SLI that we would like to extract here would be the `took` returned for each log event produced from the `request_finished` event type.
* The SLO we generate would count each request with a `request_duration` of under 200ms as a good outcome for latency, which will be divided over the total number of events.
* The SLA we can create here for each customer would require a threshold set on the SLO, i.e > 95% of requests return with a latency of <0.2 seconds.

{% hint style="info" %}
The configuration of SLIs, SLOs and SLAs happens within the slaOS UI. This step is solely focused on getting the right data, in the right format, in slaOS
{% endhint %}

## Define a payload structure

We can see that for each log event, we can extract both the `status_code`, `took`, `organization_id` and `timestamp`. We can structure our event payload like this:

```bash
{
  "organization_id": "531ccc57c17a4b418236935e96fb8049",
  "timestamp": "2024-07-02T12:34:56Z",
  "values": {
    "took": 0.03523564338684082,
    "status_code": 200
  },
  "key": "rated_api",
}
```

## Pushing events with a worker

Now that an event payload structure has been chosen, we can use a worker to deliver these events from your application to slaOS using the direct ingestion API.

#### SlaOSWorker Implementation

Here's a sample implementation of a worker that can batch and send events to slaOS:

{% tabs %}
{% tab title="Python" %}

```python
import requests
import json
import time
from threading import Lock

class SlaOSWorker:
    def __init__(self, host, ingestion_id, ingestion_key, max_retries=3, retry_delay=5):
        self.ingestion_url = f"https://{host}/v1/ingest/{ingestion_id}/{ingestion_key}"
        self.lock = Lock()
        self.max_retries = max_retries
        self.retry_delay = retry_delay

    def add_event(self, event):
        event = self._add_local_identifier(event)
        self._send_event(event)

    def _add_idempotency_key(self, event):
        # Adding a unique identifier to avoid duplicate processing
        event['idempotency_key'] = f"{event['organization_id']}:{event['timestamp']}:{hash(json.dumps(event['values']))}"
        return event

    def _send_event(self, event):
        retries = 0
        while retries < self.max_retries:
            try:
                response = requests.post(
                    self.ingestion_url,
                    json=event,
                    headers={'Content-Type': 'application/json'}
                )
                response.raise_for_status()
                print(f"Successfully sent event to slaOS")
                return
            except requests.RequestException as e:
                print(f"Error sending event to slaOS: {e}. Retrying {retries + 1}/{self.max_retries}...")
                retries += 1
                time.sleep(self.retry_delay)
        print(f"Failed to send event after {self.max_retries} retries.")

```

{% endtab %}

{% tab title="TS/JS" %}

```typescript
import axios, { AxiosError } from 'axios';

interface Event {
  organization_id: string;
  timestamp: string;
  values: Record<string, any>;
  idempotency_key?: string;
}

class SlaOSWorker {
  private ingestionUrl: string;
  private maxRetries: number;
  private retryDelay: number;

  constructor(
    host: string,
    ingestionId: string,
    ingestionKey: string,
    maxRetries: number = 3,
    retryDelay: number = 5000
  ) {
    this.ingestionUrl = `https://${host}/v1/ingest/${ingestionId}/${ingestionKey}`;
    this.maxRetries = maxRetries;
    this.retryDelay = retryDelay;
  }

  async addEvent(event: SlaOSEvent): Promise<void> {
    const eventWithKey = this.addIdempotencyKey(event);
    await this.sendEvent(eventWithKey);
  }

  private addIdempotencyKey(event: SlaOSEvent): SlaOSEvent {
    return {
      ...event,
      idempotency_key: `${event.organization_id}:${event.timestamp}:${this.hashObject(event.values)}`
    };
  }

  private hashObject(obj: Record<string, any>): string {
    return Buffer.from(JSON.stringify(obj)).toString('base64');
  }

  private async sendEvent(event: SlaOSEvent): Promise<void> {
    let retries = 0;
    while (retries < this.maxRetries) {
      try {
        await axios.post(this.ingestionUrl, event, {
          headers: { 'Content-Type': 'application/json' }
        });
        console.log('Successfully sent event to slaOS');
        return;
      } catch (error) {
        const axiosError = error as AxiosError;
        console.error(`Error sending event to slaOS: ${axiosError.message}. Retrying ${retries + 1}/${this.maxRetries}...`);
        retries++;
        await this.delay(this.retryDelay);
      }
    }
    console.error(`Failed to send event after ${this.maxRetries} retries.`);
  }

  private delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

export default SlaOSWorker;
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The `idempotency_key` can be added to each event to prevent duplicate processing of the same event. You can either pass a key generated on our end. If we don't receive a `idempotency_key`, we generate a unique string based on the `organization_id`, `timestamp`, and the hashed contents of the `values`. This identifier is crucial in avoiding the reprocessing of identical events.
{% endhint %}

#### Usage in Your Application

To integrate this worker into your application:

1. **Initialize the Worker**: Begin by creating an instance of `SlaOSWorker` with your specific `slaOS` host, `ingestion ID`, and `ingestion key`.
2. **Send Events**: Whenever an event occurs in your application that you want to send to `slaOS`, simply call `worker.add_event(event_data)` with the relevant event data.

{% tabs %}
{% tab title="Python" %}

```python
worker = SlaOSWorker(
    host="your-slaos-host.com",
    ingestion_id="your-ingestion-id",
    ingestion_key="your-ingestion-key"
)

# In your application code, add events as they occur
worker.add_event({
    "organization_id": "531ccc57c17a4b418236935e96fb8049",
    "timestamp": "2024-07-02T12:34:56Z",
    "values": {
        "took": 0.03523564338684082,
        "status_code": 200
    },
    "key": "rated_api"
})
```

{% endtab %}

{% tab title="TS/JS" %}

```typescript
import SlaOSWorker from './SlaOSWorker';

// Instantiate the SlaOSWorker
const worker = new SlaOSWorker(
    "your-slaos-host.com",
    "your-ingestion-id",
    "your-ingestion-key"
);

// In your application code, add events as they occur
async function sendEvent() {
    try {
        await worker.addEvent({
            organization_id: "531ccc57c17a4b418236935e96fb8049",
            timestamp: "2024-07-02T12:34:56Z",
            values: {
                took: 0.03523564338684082,
                status_code: 200
            },
            key: "rated_api"
        });
        console.log("Event sent successfully");
    } catch (error) {
        console.error("Error sending event:", error);
    }
}

// Call the function to send the event
sendEvent();
```

{% endtab %}
{% endtabs %}

And voila! We now have a worker delivering events to slaOS :sparkles::sparkles::sparkles:


# Filters

How slaOS applies filters to parse and process log data

This guide explains how slaOS applies filters to parse and process log data. We'll cover key concepts and provide practical examples to illustrate how log parsing works in slaOS.

## Log formats

slaOS supports both structured (JSON) and unstructured (raw text) log formats.

{% hint style="info" %}
Please note that unstructured logs are processed using regex to extract relevant features.
{% endhint %}

## **Field Types**

slaOS supports the following field types:

* `timestamp` : For date and time information
* `integer`: For whole numbers
* `float`: For decimal numbers
* `string`: For text data

## Example: Parsing API Key Metric Usage Logs

In this example, we'll demonstrate how to effectively parse JSON logs containing an application API usage metrics using slaOS. Imagine you're building an SLA (Service Level Agreement) for an API that tracks critical metrics such as units consumed, latency, API paths per customer IDs.&#x20;

For simplicity, we'll assume the logs are in a JSON-compatible format. Here's an example of such a log entry:

```json
{
  "timestamp": "2024-08-15T10:30:45Z",
  "customer": {
    "id": "cust_12345"
  },
  "api_call": {
    "latency": 120,
    "credits_used": 5,
    "path": "/v1/process",
    "method": "POST"
  },
  "response": {
    "status_code": 200
  }
}
```

### **Step 1: Define the log pattern**

To effectively parse your API key usage logs, you need to define a pattern that highlights the relevant fields you want to track based on your log structure. Below is an example of a pattern definition tailored to the log structure above,

Each field definition consists of:

* **Key**: The name of the field in the parsed output
* **Field Type**: One of the supported field types (`timestamp`, `integer`, `float`, or `string`)
* **Format** (*optional*): For timestamp fields, specifies how to parse the date/time string
* **Path**: The path to the field in the nested JSON structure

```json
{
  "version": 1,
  "log_format": "json_dict",
  "fields": [
    {
      "key": "timestamp",
      "field_type": "timestamp",
      "format": "%Y-%m-%dT%H:%M:%SZ",
      "path": "timestamp"
    },
    {
      "key": "customer_id",
      "field_type": "string",
      "path": "customer.id"
    },
    {
      "key": "latency",
      "field_type": "integer",
      "path": "api_call.latency"
    },
    {
      "key": "credits_used",
      "field_type": "integer",
      "path": "api_call.credits_used"
    },
    {
      "key": "path",
      "field_type": "string",
      "path": "api_call.path"
    },
    {
      "key": "method",
      "field_type": "string",
      "path": "api_call.method"
    },
    {
      "key": "api_status_code",
      "field_type": "integer",
      "path": "response.status_code"
    }
  ]
}
```

This pattern provides slaOS with clear instructions on how to interpret and extract the necessary data from your JSON logs, ensuring that each critical metric is accurately captured.

### **Step 2: Set Up the Parser**

Once you’ve defined the log pattern, the next step is to set up the parser in slaOS by providing this pattern definition. While the exact setup process may vary depending on your specific integration, the underlying concept remains the same: you’re telling slaOS, "This is how my logs are structured, and here’s how to interpret each field."

<details>

<summary>Adding patterns using the <code>rated-parser</code> Python library</summary>

```python
from rated_parser import LogParser

log_parser = LogParser()

# Define your log pattern
log_pattern = {
    "version": 1,
    "log_format": "json_dict",
    "fields": [
        {"key": "timestamp", "field_type": "timestamp", "format": "%Y-%m-%dT%H:%M:%SZ", "path": "timestamp"},
        {"key": "customer_id", "field_type": "string", "path": "customer.id"},
        {"key": "latency", "field_type": "integer", "path": "api_call.latency"},
        {"key": "credits_used", "field_type": "integer", "path": "api_call.credits_used"},
        {"key": "path", "field_type": "string", "path": "api_call.path"},
        {"key": "method", "field_type": "string", "path": "api_call.method"},
        {"key": "status_code", "field_type": "integer", "path": "response.status_code"}
    ]
}

# Configure the parser with the defined pattern
log_parser.add_patter(log_pattern)
```

</details>

### **Step 3: Parse the Log Entry**

After setting up the parser, slaOS processes your log entries according to the defined pattern, converting and extracting each field into a structured format. Here’s how the parsed output might look:

```json
{
  "timestamp": "2024-08-15 10:30:45",
  "customer_id": "cust_12345",
  "latency": 120,
  "credits_used": 5,
  "path": "/v1/process",
  "method": "POST",
  "api_status_code": 200
}
```

Notice how the timestamp has been standardized, and all fields have been accurately extracted based on their specified paths and types. This structured output is now ready for further analysis, reporting, or intheretegration into your monitoring tools.

<details>

<summary>Parsing logs using the <code>rated-parser</code> Python library</summary>

```python
# Example log entry
log_entry = {
    "timestamp": "2024-08-15T10:30:45Z",
    "customer": {"id": "cust_12345"},
    "api_call": {"latency": 120, "credits_used": 5, "path": "/v1/data/upload", "method": "POST"},
    "response": {"status_code": 200}
}

# Parse the log entry
parsed_log = log_parser.parse_log(log_entry, version=1)
print(parsed_log)
```

</details>

## Notes on DateTime Formats

When defining timestamp fields, it's crucial to use the correct `datetime` format string that matches the format of your log timestamps. These format strings tell the system exactly how to interpret the date and time information in your logs. Here are some examples of datetime format strings that can be used to accurately parse different timestamp formats:

| Format String              | Example Timestamp                 |
| -------------------------- | --------------------------------- |
| `%Y-%m-%dT%H:%M:%S.%fZ`    | `2023-07-25T14:30:45.678901Z`     |
| `%d/%b/%Y:%H:%M:%S %z`     | `25/Jul/2023:14:30:45 +0000`      |
| `%a %b %d %H:%M:%S %Y`     | `Tue Jul 25 14:30:45 2023`        |
| `%A, %d-%b-%y %H:%M:%S %Z` | `Tuesday, 25-Jul-23 14:30:45 UTC` |
| `%Y%m%d%H%M%S`             | `20230725143045`                  |

Each of these format strings is designed to match specific timestamp layouts, allowing the system to correctly parse and convert the raw timestamp data into a standardized format for processing and analysis.


# Open source log parsing library

We’re excited to share that the code for our parsing library has been open-sourced! It’s available as a module on PyPI under the name **rated-parser**. You can use this library to parse logs in your own projects, leveraging the same robust parsing capabilities that slaOS provides.

Simply install the package using pip:

```bash
pip install rated-parser
```

With `rated-parser`, you can easily parse both structured and unstructured log data, define custom patterns, and extract relevant features—just like slaOS does.

{% embed url="<https://github.com/rated-network/rated-parser>" %}


# Data hashing & transformation

## Overview

The `rated-parser` library provides powerful data processing capabilities with built-in privacy features to help you handle sensitive data responsibly. This guide explains how to use these features while maintaining GDPR compliance.

## Field Processing Options

#### Basic Field Definition

Every field in your metrics is defined by a `key` that maps to the corresponding value in your data. For example:

```json
{
  "user_email": "john@example.com",
  "request_count": 150,
  "response_time_ms": 250
}
```

## Privacy Protection Options

### **1. Encryption**

Use encryption when you need to retrieve the original value later (e.g., for debugging or customer support).

**Example Use Cases:**

* User identifiers
* Email addresses
* IP addresses
* Session IDs

```json
{
  "version": 1,
  "fields": [
    {
      "key": "user_email",
      "encryption": true
    }
  ]
}
```

When processed, the email becomes an encrypted string that can only be decrypted with your encryption key:

```json
{
  "user_email": "AES256.cbc.f7d9a1b2..."
}
```

### **2. Hashing**

Use hashing when you need to track metrics without storing the original value. Hashed values cannot be reversed.

Our implementation uses:

* Algorithm: SHA-256
* Encoding: UTF-8
* Output Format: Hexadecimal digest (64 characters)

These specifications ensure consistent hash generation across different systems. The code implementation is:

```python
def hash_value(value):
    return sha256(str(value).encode()).hexdigest()
```

**Example Use Cases:**

* Organization IDs for analytics
* Device IDs for unique user counting
* Transaction IDs for deduplication

```json
{
  "version": 1,
  "fields": [
    {
      "key": "organization_id",
      "hash": true
    }
  ]
}
```

Results in:

```json
{
  "organization_id": "sha256.8f4e8d9c..."
}
```

## Data Transformations

### **1. Expression Transformations**

Use expressions when you need to modify values using simple mathematical or string operations.

**Example Use Cases:**

* Converting units (bytes to MB, seconds to milliseconds)
* Normalizing string formats
* Basic calculations

```json
{
  "version": 1,
  "fields": [
    {
      "key": "memory_usage",
      "transformation": "value / (1024 * 1024)",
      "transformation_type": "expression"
    }
  ]
}
```

This transforms memory usage from bytes to MB:

```json
Input:  { "memory_usage": 1048576 }
Output: { "memory_usage": 1.0 }
```

### **2. Function Transformations**

Use predefined functions for more complex transformations.

**Example Use Cases:**

* Duration string parsing
* HTTP status code categorization
* String normalization

```json
{
  "version": 1,
  "fields": [
    {
      "key": "duration",
      "transformation": "duration_to_ms",
      "transformation_type": "function"
    }
  ]
}
```

This converts duration strings to milliseconds:

```json
Input:  { "duration": "1.5s" }
Output: { "duration": 1500.0 }
```

## Built-in Safety Features

1. **Field Protection:**
   * Cannot combine encryption and hashing on the same field
   * Automatic validation of transformation expressions
   * Protection against injection attacks
2. **Transformation Safety:**
   * Restricted to safe mathematical operations
   * Limited to approved string methods
   * No access to system functions or dangerous operations

## Example Implementation

Here's a complete example showing different types of field processing:

```json
{
  "version": 1,
  "fields": [
    {
      "key": "user_id",
      "encryption": true
    },
    {
      "key": "organization_id",
      "hash": true
    },
    {
      "key": "response_time",
      "transformation": "value * 1000",
      "transformation_type": "expression"
    },
    {
      "key": "status_code",
      "transformation": "status_class",
      "transformation_type": "function"
    }
  ]
}
```

Input data:

```json
{
  "user_id": "user_123",
  "organization_id": "org_456",
  "response_time": 0.45,
  "status_code": 404
}
```

Output data:

```json
{
  "user_id": "AES256.cbc.a1b2c3...",
  "organization_id": "sha256.d4e5f6...",
  "response_time": 450.0,
  "status_code": "4xx"
}
```

This processed data is now ready for storage or analysis while maintaining privacy and compliance requirements.


# Rated Exporter SDK

A source available library that simplifies collecting metrics and logs from your monitoring tools

## What is the Rated Exporter SDK?

The Rated Exporter SDK is our source available library that simplifies collecting metrics and logs from your monitoring tools. Instead of writing different code for each monitoring source, you can use one consistent interface to fetch data from any supported monitoring system.

{% embed url="<https://github.com/rated-network/rated-exporter-sdk>" %}

## Monitoring Sources We Support

### Infrastructure & Cloud

* Prometheus
* AWS CloudWatch (soon)
* Google Cloud Monitoring (soon)
* Azure Monitor (soon)

### Application Performance

* Datadog (soon)
* New Relic (soon)

## Why Use Rated SDK?

### Simplified Data Collection

* One consistent way to fetch data from any monitoring source
* No need to learn multiple APIs
* Same error handling across all sources

### Error Handling Made Easy

Instead of dealing with different errors from each monitoring source, we provide:

* Standardized error types
* Automatic retries for common issues
* Clear error messages

***

*The Rated SDK: Your bridge to reliable monitoring data.*


# Custom adapters

slaOS third party plugins and integrations

If you have a unique data source or integration need, you can build a custom adapter for the slaOS indexer. Our open-source indexer architecture allows for easy extension.

## To build a custom adapter

1. Fork the slaOS indexer repository
2. Implement the adapter interface (documentation provided in the repo)
3. Test your adapter with sample data
4. Submit a pull request for review and inclusion in the main slaOS project

{% embed url="<https://github.com/rated-network/rated-log-indexer/tree/main>" %}

## Best practices for custom adapters:

* Follow the provided code style and documentation guidelines
* Implement robust error handling and logging
* Provide clear configuration options for users
* Include unit and integration tests

To maintain the highest standards of quality and reliability for our users, we carefully review all submissions to ensure they meet these guidelines. Adherence to these practices is essential for the acceptance and integration of custom adapters into the slaOS ecosystem.

If you're building a custom integration and need guidance or have any questions, please don't hesitate to reach out to our support team at <hello@rated.co>. We're here to help ensure your integration is successful and meets our quality standards.


# Authentication

To enable users to programatically perform CRUD operations on organizations and SLIs, Os and As we have implemented m2m (machine to machine) authentication. You need to be authenticated in order to access it, i.e. by logging into slaOS on the frontend.&#x20;

## Create token flow

Once logged in, use the javascript provided below to create the token. You can copy and paste this javascript in the browser console and run it.&#x20;

```javascript
(fetch(`${window.location.protocol}//${window.location.host}/api/slaos/v1/users/m2m-token`, {method: 'GET'}).then(response => response.json()).then(json => json["jwt"]).then(console.log))();
```

<figure><img src="/files/QBz3NbGuTYIPviie9BGq" alt=""><figcaption><p>generating the token via browser console</p></figcaption></figure>

This token can be used to access the slaOS APIs programmatically. On our end, the machine will be identified with the id of the user that obtained the token.

{% hint style="info" %}
Note that the token has an expiry date of one year.&#x20;
{% endhint %}

The token is then added  in the API request headers with the value `Authorization: Bearer <token>`

Your token carries many privileges, so be sure to keep them secure! Do not share your token in publicly accessible areas such as GitHub, client-side code, and so forth.

All API requests must be made over [HTTPS](http://en.wikipedia.org/wiki/HTTP_Secure). Calls made over plain HTTP will fail. API requests without authentication will also fail.

{% tabs %}
{% tab title="curl" %}

<pre class="language-java"><code class="lang-java"><strong>#Authenticated Request
</strong>curl -v -X 'POST' \
'https://api.rated.co/v1/slos/' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer &#x3C;YOUR-TOKEN-HERE>'
-d '{
  "name": "Uptime percentage SLO",
  "description": "Uptime percentage must be greater than 99.9% for the calendar month",
  "service_level_indicator_id": "string",
  "time_window_type": "calendar",
  "time_window_value": "1",
  "time_window_unit": "month",
  "target_value": "99.9",
  "target_unit": "percentage",
  "interval": 86400,
  "on_missing_interval": "exclude",
  "benchmark_operator": "ge",
  "benchmark_value": "50000"
}'
</code></pre>

{% endtab %}

{% tab %}

```python
import requests

# api endpoint
url = "https://api.rated.co/v1/slos/"

# headers with authorization
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <YOUR-TOKEN-HERE>",
}

# data payload
data = {
    "name": "Uptime percentage SLO",
    "description": "Uptime percentage must be greater than 99.9% for the calendar month",
    "service_level_indicator_id": "string",
    "time_window_type": "calendar",
    "time_window_value": "1",
    "time_window_unit": "month",
    "target_value": "99.9",
    "target_unit": "percentage",
    "interval": 86400,
    "on_missing_interval": "exclude",
    "benchmark_operator": "ge",
    "benchmark_value": "50000",
}

# send post request
response = requests.post(url, headers=headers, json=data)

# print response
print(response.status_code)
print(response.json())

```

{% endtab %}
{% endtabs %}


# Pagination

All top-level API resources have support for bulk fetches through API methods that respond with a list. These list API methods share a common structure and accept, at a minimum, the following two parameters: `limit` and `offset`.

## Pagination limits and page size

slaOS API uses offset based pagination through the `limit` and `offset` parameters. Both parameters accept an existing object ID value (see below) and return objects in chronological order. The `limit` parameter specifies how many records to fetch per page. The `offset` parameter indicates where to start fetching data or how many records to skip, defining the initial position within the list.

See details on the parameters below [👇](https://emojipedia.org/backhand-index-pointing-down)

| Parameters | Description                                                                                                                                   |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| limit      | Limit specifies how many records to fetch per page. Default value is 10.                                                                      |
| offset     | Offset indicates where to start fetching data or how many records to skip, defining the initial position within the list. Default value is 0. |

In the response, you will get the total number of items (`total`) which signifies how many results of data we have for the requested information.

## Example

For example, if you call  `GET https://api.rated.co/v1/slis/` you will get all the SLIs that are currently defined on your workspace.

<details>

<summary>Example of a paginated response</summary>

```json
{
  "total": 100,
  "results": [
    {
      "id": "string",
      "name": "string",
      "type": "value",
      "description": "string",
      "unit_of_measure": "string",
      "queries": {
        "additionalProp1": {
          "select": "string",
          "where": "string",
          "from": "string",
          "limit": 0
        },
        "additionalProp2": {
          "select": "string",
          "where": "string",
          "from": "string",
          "limit": 0
        },
        "additionalProp3": {
          "select": "string",
          "where": "string",
          "from": "string",
          "limit": 0
        }
      },
      "formula": "string",
      "created_at": "2024-12-09T11:08:25.973Z",
      "updated_at": "2024-12-09T11:08:25.973Z"
    }
  ],
  "next": "https://endpoint?limit=100&offset=0",
  "previous": "https://endpoint?limit=100&offset=100"
}
```

</details>

Depending on the request, you can also get more than one page of results. You can navigate between these pages using the `previous` and `next` URLs. Just use the URL in `next` to continue fetching the rest of the data. You will also get a url in `previous` as you navigate throught pages 2,3,4... and so on. When there's no more data left, the API will stop giving you the next link and show `next: null`.<br>


# API Reference

{% hint style="info" %}
You can access our API's Swagger documentation via [api.rated.co/docs](https://api.rated.co/docs#/)

Remember to use the token generated as outlined in[Authentication](/api-beta/authentication) in the header of all your requests.
{% endhint %}

Detailed docs coming soon :incoming\_envelope:


# Tutorials

How to build SLI's, O's and A's, customer dashboards and more

In this section, we'll guide you through the the process of defining SLIs, SLOs, and SLAs alongside launching SLA Portals.&#x20;

<table data-column-title-hidden data-view="cards"><thead><tr><th></th><th data-hidden></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Build a SLI</strong></td><td></td><td></td><td><a href="/pages/iHax8U9OsWGOfx4uqsUN">/pages/iHax8U9OsWGOfx4uqsUN</a></td><td><a href="/files/S9P8cUqBVCSZxV24gCKr">/files/S9P8cUqBVCSZxV24gCKr</a></td></tr><tr><td><strong>Build a SLO</strong></td><td></td><td></td><td><a href="/pages/B6n9KgkhQbnARW1MIQN5">/pages/B6n9KgkhQbnARW1MIQN5</a></td><td><a href="/files/I0s9OfkAcicDIBGSArQO">/files/I0s9OfkAcicDIBGSArQO</a></td></tr><tr><td><strong>Create an Organization</strong></td><td></td><td></td><td><a href="/pages/Vdhh0Fl0pmpOGb8vV5Ho">/pages/Vdhh0Fl0pmpOGb8vV5Ho</a></td><td><a href="/files/v5FWvMOqkA4RHJ9P9iWC">/files/v5FWvMOqkA4RHJ9P9iWC</a></td></tr><tr><td><strong>Build a SLA</strong></td><td></td><td></td><td><a href="/pages/S3vWdZu2tlAsweKEu8t9">/pages/S3vWdZu2tlAsweKEu8t9</a></td><td><a href="/files/eL1JHqEgQ5OQja2gfozp">/files/eL1JHqEgQ5OQja2gfozp</a></td></tr><tr><td><strong>Configure a SLA Portal</strong></td><td></td><td></td><td><a href="/pages/FEElrk4GQ01WqsVIKcGR">/pages/FEElrk4GQ01WqsVIKcGR</a></td><td><a href="/files/dWFgMwsKpP9LpVjIQfXY">/files/dWFgMwsKpP9LpVjIQfXY</a></td></tr></tbody></table>


# Build a SLI

This guide walks you through creating a Service Level Indicator (SLI) in slaOS

SLIs are key metrics that measure specific aspects of your service's performance and reliability. By following these steps, you'll learn to configure effective SLIs to monitor your service quality.

{% hint style="info" %}
Before writing a SLI query, the engine asks you to state whether you are defining a Value SLI (e.g. latency, MTTD) or a Percentage SLI (e.g. uptime, error rate). It does so to allow for maximum flexibility in terms of the Objective (SLO) you get to define later, as the two streams demand different treatment to produce error free results.
{% endhint %}

## Create a Value SLI

Follow these steps to create a Value Service Level Indicator (SLI):

1. Find and click on "Indicators" in the side navigation bar
2. Click the "+ New SLI" button to open the Create SLI modal
3. Choose "Value" as the type of SLI you'll be building
4. **Choose a metric query, aggregator, and filter**
   1. <mark style="color:orange;">**Allowed aggregators**</mark>**:** `COUNT`, `SUM`, `MAX`, `MIN`, `AVG`

      `n/a` is also an acceptable input; this will output an array of metrics without any aggregation
   2. <mark style="color:orange;">**You can create multiple queries**</mark> by clicking "+ New Query" and add a formula in the formula box to define the relationship between them.&#x20;
   3. <mark style="color:orange;">**Operators allowed on the formula builder**</mark>: `*` , `/`, `+`, `-` , `<` , `>` , `<=` , `>=,` `=` , `!=`
5. Provide a clear, descriptive name for your SLI and a description to explain its purpose and function.
6. Click the "Save" button to create your new Value SLI.

### Examples

{% tabs %}
{% tab title="List of Latencies" %}
**QUERY**

**A: SELECT** {`n/a`} {`latency_metric`} **FROM** {`key`} **WHERE** {`status_code < 500`}

Unit `ms`

Example implementation 👇

<figure><img src="/files/sS4izqoFcuoXHymkkpPF" alt=""><figcaption></figcaption></figure>

This SLI will output a stream of latencies like `{121,90,48,291,44,29,90,81...}`` ``seconds`
{% endtab %}

{% tab title="Average Latency" %}
**QUERY**

**A: SELECT** {`AVG`} {`latency_metric`} **FROM** {`key`} **WHERE** {`status_code < 500`}

Unit `ms`

Example Implementation 👇

<figure><img src="/files/fJn2XngCokZBTHNVJBov" alt=""><figcaption></figcaption></figure>

This SLI will output a the average latency of all the latencies sent within a period. For example, if the latencies sent were `{121,90,48,291,44,29,90,81} seconds`, the output of which would be 99.25 seconds.
{% endtab %}

{% tab title="Data Freshness" %}
**QUERY**

**A: SELECT** {`n/a`} {`external_timestamp_metric`} **FROM** {`key1`}&#x20;

**B: SELECT** {`n/a`} {`internal_timestamp_metric`} **FROM** {`key2`}&#x20;

Unit `epochs`

Formula: `A - B`

Example implementation 👇

<figure><img src="/files/ce7fGN47VlxJJgO9xxk4" alt=""><figcaption></figcaption></figure>

This SLI will output a stream of integers like `{2,5,1,1,2,1,1,3,...} epochs`.
{% endtab %}

{% tab title="Average Data Freshness" %}
**QUERY**

**A: SELECT** {`AVG`} {`external_timestamp_metric`} **FROM** {`key1`}&#x20;

**B: SELECT** {`AVG`} {`internal_timestamp_metric`} **FROM** {`key2`}&#x20;

Formula: `A - B`

Unit `epochs`

Example implementation 👇

<figure><img src="/files/3UcgUYIepcSLTnFFsHCl" alt=""><figcaption></figcaption></figure>

This SLI will output the average data freshness within a period. For example, if the `external_timestamp` averages to `1.2 epochs` and the `internal_timestamp` averages out to `1 epoch`, the SLI will output `0.2 epochs`.
{% endtab %}
{% endtabs %}

## Create a Percentage SLI

Follow these steps to create a Percentage Service Level Indicator (SLI):

1. Find and click on "Indicators" in the side navigation bar
2. Click the "+ New SLI" button to open the Create SLI modal
3. Choose "Percentage" as the type of SLI you'll be building
4. **Choose a metric query, aggregator, and filter**
   1. <mark style="color:orange;">**Allowed aggregators**</mark>**:** `COUNT`, `SUM`, `MAX`, `MIN`, `AVG`

      `n/a` is also an acceptable input; this will output an array of metrics without any aggregation
   2. <mark style="color:orange;">**You can create multiple queries**</mark> by clicking "+ New Query" and add a formula in the formula box to define the relationship between them
   3. <mark style="color:orange;">**Operators allowed on the formula builder**</mark>: `*` , `/`, `+`, `-` , `<` , `>` , `<=` , `>=,` `=` , `!=`
5. Provide a clear, descriptive name for your SLI and a description to explain its purpose and function
6. Click the "Save" button to create your new Percentage SLI

### Examples

{% tabs %}
{% tab title="Defining Uptime on slaOS" %}
**QUERY**

**A: SELECT** {`count`} {`*`} **FROM** {`key1`}  **WHERE** {`status_code < 500`}

**B: SELECT** {`count`} {`*`} **FROM** {`key2`}&#x20;

Formula : `A/B`

Example implementation 👇

<figure><img src="/files/kwIqabM4nRcXPRNvCq3R" alt=""><figcaption></figcaption></figure>

The SLI will output a ratio, where the numerator counts all the events where the status code is less than 500 and the denominator is all events.&#x20;
{% endtab %}

{% tab title="Pre-aggregated Uptime" %}
**QUERY**

**A: SELECT** {`n/a`} {`uptime_metric`} **FROM** {`key`} &#x20;

Example implementation 👇

<figure><img src="/files/bQSX1q0GV5NAABYh6YJA" alt=""><figcaption></figcaption></figure>

The SLI will output the average of the uptime metric over a time period. For example, if the uptime metric is passed hourly to slaOS as `{0.9998, 0.9992, 0.9892, 0.4819, 0.9999, 0.9759}`, the SLI output will be `0.90765` or `90.965%`
{% endtab %}

{% tab title="Error Rate" %}
**QUERY**

**A: SELECT** {`count`} {`*`} **FROM** {`key1`}  **WHERE** {`status_code >= 500`}

**B: SELECT** {`count`} {`*`} **FROM** {`key2`}&#x20;

Formula : `A/B`

Example implementation 👇

<figure><img src="/files/PwsoulEEZZBTkylzdSS8" alt=""><figcaption></figcaption></figure>

The SLI will output a ratio, where the numerator counts all the events where the status code is more than 500 and the denominator is all events.&#x20;
{% endtab %}
{% endtabs %}

<br>


# Build a SLO

This tutorial guides you through creating a Service Level Objective (SLO) in slaOS

SLOs set specific, measurable targets for your service's performance based on SLIs. Learn how to configure SLOs to establish clear reliability goals for your service.

## Event vs Interval based SLOs

SLOs can be categorized into two main types: `Event-based` and `Interval-based`. Understanding the difference is crucial for effective service reliability management.

### Event-based SLOs

* **Definition**: Measure the success rate of discrete, countable occurrences.
* **Example**: "99.9% of API requests should will be served successfully in a rolling 7d window"
* **Characteristics**:
  * Based on individual events (such as requests, transactions etc)
  * Often used for request/response systems
  * Typically measured as a ratio of successful events to total events

### Interval-based SLOs

* **Definition**: Measure the proportion of time a service meets a specific criterion.
* **Example**: "99% of all 10-minute intervals in a month will have latency less than 100ms "
* **Characteristics**:
  * Based on continuous monitoring over time periods
  * Often used for availability or uptime metrics
  * Measured as a percentage of time the service meets the defined criteria

Select the SLO type that best fits your service and reliability goals. The choice between event-based and interval-based SLOs is both a technical and business decision. We recommend tech and business stakeholders collaboratively evaluate both options, test them on the slaOS UI before finalizing.&#x20;

{% hint style="info" %}
To learn more about event and interval based SLOs, we highly recommend a read of [Google Cloud's Observability Handbook](https://cloud.google.com/stackdriver/docs/solutions/slo-monitoring#:~:text=A%20request%2Dbased%20SLO%20is,goal%20for%20the%20compliance%20period.)!
{% endhint %}

### Best practice for raw data points (not pre-aggregated):

These are individual data points like status codes, latencies, or timestamps that haven't been aggregated before ingestion into slaOS.

**For Value SLIs (e.g., latency):**

* **Recommendation:** Use event-based SLOs
* **Rationale:** Each latency measurement is a discrete event. Event-based SLOs allow you to set objectives like "99% of requests should have a latency < 100ms."

**For Percentage SLIs (e.g., status codes for uptime):**

* **Recommendation:** Use interval-based SLOs
* **Rationale:** Uptime is typically measured over time periods. Interval-based SLOs allow objectives like "The service should be up 99.9% of the time over a month."

### Best practice for pre-aggregated metrics

These are metrics that have been aggregated before ingestion, such as average latency or hourly uptime.

1. **For Value SLIs (e.g., average latency):**
   * Both event-based and interval-based can work, depending on your business goals
   * Event-based example: "99% of hourly average latencies should be < 100ms"
   * Interval-based example: "In 99% of 10-minute intervals, the average latency should be < 100ms"
   * Choose based on whether you care more about overall performance (event-based) or consistent performance over time (interval-based)
2. **For Percentage SLIs (e.g., hourly uptime):**
   * Again, both approaches can work
   * Event-based example: "The average of hourly uptime measurements over a calendar month should be ≥ 99.5%"
   * Interval-based example: "All daily (24hr intervals) average uptime measurements over a calendar month should be > 99.5%"
   * Choose based on whether you want to allow some fluctuation (event-based) or ensure consistent performance every day (interval-based)

{% hint style="info" %}
*Need help defining your SLOs?* Contact us at <hello@rated.co> for consultation.
{% endhint %}

## Create an Event based SLO

Follow these steps to create a Event Service Level Objective (SLO):

1. Find and click on "Objectives" in the side navigation bar
2. Click the "+ New SLO" button to open the Create SLO modal
3. Click on the dropdown to select from your list of active SLIs
4. Choose "Event" as the type of SLO you'll be building
5. Depending on the type of SLI you’ve chosen:
   1. **If your SLI is a value SLI**, you will need to set a benchmark against which each “event” in the SLI will be compared against. To set a benchmark, you will select an operator and the benchmark value
      1. <mark style="color:orange;">**Allowed operators:**</mark> `>`, `<`, `>=`, `<=`, `=`
      2. <mark style="color:orange;">**Allowed benchmark types:**</mark> `numeric`, `boolean`
   2. **If your SLI is a percentage SLI**, you will need to set an aggregator for your SLI which will be applied to all events within a period.&#x20;
      1. <mark style="color:orange;">**Allowed aggregators:**</mark> `AVG`, `MIN`, `MAX`, `COUNT`, `SUM`, `PERCENTILE`
6. Select the compliance period and target. Click “Continue”.
7. A name and description will be auto filled for your SLO based on your configuration
8. Click the "Save" button to create your new event SLO

### Examples

{% tabs %}
{% tab title="Event SLO for Value SLI" %}
For the example implementation, we’ll create an Event SLO with a Latency SLI. This SLO specifies that, over a calendar month, 99.9% of successful requests must have a latency under 1 second.

1. Find and click on "Objectives" in the side navigation bar
2. Click the "+ New SLO" button to open the Create SLO modal
3. Select Latency as the SLI and choose Event SLO
4. Set the operator as `≤` and benchmark as `1 second`
5. Set the time window type as `Calendar`, period as `Monthly` and Service target as `≥ 99.9%`
6. The SLO will  get the following name: `Latency above 99.9%` and description `Event based calculation over a calendar period of 1 month` via the autofill feature
7. Click "Save"

<figure><img src="/files/xlTSLxVu1e27yMBcX46l" alt=""><figcaption><p>Event based Latency SLO </p></figcaption></figure>
{% endtab %}

{% tab title="Event SLO for Percentage SLI" %}
For the example implementation, we’ll create an Event SLO with a Uptime SLI. This SLO specifies that, over a calendar month, the average uptime will be greater than 99.95%.

* Find and click on "Objectives" in the side navigation bar
* Click the "+ New SLO" button to open the Create SLO modal
* Select Uptime as the SLI and choose Event SLO
* Set the aggregator as `AVG`
* Set the time window type as `Calendar`, period as `Monthly` and Service target as `≥ 99.9%`
* The SLO will  get the following name: `Uptime above 99.95%` and description `Event based calculation over a calendar period of 1 month` via the autofill feature
* Click "Save"

<figure><img src="/files/NCA1vOto5aYDD7zNEMuX" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

## Create an Interval based SLO

Follow these steps to create an Interval Service Level Objective (SLO):

1. Find and click on "Objectives" in the side navigation bar
2. Click the "+ New SLO" button to open the Create SLO modal
3. Click on the dropdown to select from your list of active SLIs
4. Choose "Interval" as the type of SLO you'll be building
5. Configure your interval behavior. This includes:&#x20;
   1. The size of each intervals. You can choose a minimum size of 1min and a maximum size of 24h.
   2. How we should treat intervals where no events were received. This can happen when your service is undergoing planned maintenance or during off peak hours. You can either choose to treat those intervals as `GOOD` meaning service was good, `BAD` meaning service was down/misbehaving or `EXCLUDE` meaning the interval won't be considered as there was nothing to consider.
   3. The aggregation function that you'll want to apply on the interval&#x20;
      1. <mark style="color:orange;">**Allowed aggregators:**</mark> `AVG`, `MIN`, `MAX`, `COUNT`, `SUM`, `PERCENTILE`
   4. The benchmark each intervals' aggregated result will be compared against
      1. <mark style="color:orange;">**Allowed operators:**</mark> `>`, `<`, `>=`, `<=`, `=`
      2. <mark style="color:orange;">**Allowed benchmark types:**</mark> `numeric`, `boolean`
6. Select the compliance period and target. Click “Continue”.
7. A name and description will be auto filled for your SLO based on your configuration
8. Click the "Save" button to create your new interval SLO

### Examples

{% tabs %}
{% tab title="Interval SLO for value SLI" %}
For the example implementation, we’ll create an Interval SLO with a Latency SLI. This SLO specifies that, over a rolling 28d window, 99.5% of all 10 min intervals will have p99 latency less than or equal to 1 second.

* Find and click on "Objectives" in the side navigation bar
* Click the "+ New SLO" button to open the Create SLO modal
* Select `Latency` as the SLI and choose Interval SLO
* Set the interval size as `10min` and empty interval behavior as `Exclude`
* Choose `p99` as the aggregation function
* Set the operator as `≤` and benchmark as `1 second`
* Set the time window type as `Rolling`, period as `28days` and Service target as `≥ 99.5%`
* The SLO will  get the following name: `Latency above 99.5%` and description `Calculation every 10 min over a rolling period of 28 days` via the autofill feature
* Click "Save"

<figure><img src="/files/uDhmFLAYH88NIhnoxpTO" alt=""><figcaption><p>Interval SLO for Latency SLI</p></figcaption></figure>
{% endtab %}

{% tab title="Interval SLO for Interval SLI" %}
For the example implementation, we’ll create an Interval SLO with a Uptime SLI. This SLO specifies that, over a calendar month, 99% of all 24 hour intervals will have AVG uptime of 99.95% or more.

* Find and click on "Objectives" in the side navigation bar
* Click the "+ New SLO" button to open the Create SLO modal
* Select `Uptime` as the SLI and choose Interval SLO
* Set the interval size as `24hr` and empty interval behavior as `Good`
* Choose `AVG` as the aggregation function
* Set the operator as `≥` and benchmark as `99.95%`
* Set the time window type as `Calendar`, period as `Monthly` and Service target as `≥ 99%`
* The SLO will  get the following name: `Uptime above 99%` and description `Calculation every 24 hours over a calendar period of 1 month` via the autofill feature
* Click "Save"

<figure><img src="/files/7L8eXsOhp4yO2BcOUYr0" alt=""><figcaption><p>Interval SLO for Uptime SLI</p></figcaption></figure>
{% endtab %}
{% endtabs %}


# Create an Organization

Learn how to set up and manage org accounts

Organization accounts are core to slaOS to manage SLAs effectively, and provide tailored dashboards for each org, whether this is a customer of yours or a vendor you would like to align your views with.&#x20;

Besides providing a real time view of performance commitments,  having org-specific data at your fingertips when issues arise allows for quicker diagnosis and resolution, minimizing downtime and maintaining high satisfaction levels.&#x20;

The following guide will walk you through the process of creating and managing your orgs on slaOS.

## Create an Organization

Follow these steps to create an org on slaOS:

1. Find and click on "Organizations" in the side navigation bar
2. Click the "+ Add Organization" button to open the Add Organization modal
3. Give your customer a recognisable name. This is usually their official entity name
4. From the dropdown, select the `organization_id` that you have sent to us via the ingestion URL. These mappings are crucial for the accurate computation of SLA statuses per organization.
5. Click the "Save" button to create your new org on slaOS

### Example

{% tabs %}
{% tab title="Acme Corporation" %}
For the example implementation, we will be creating an org called Acme Corporation.

1. Find and click on "Organization" in the side navigation bar
2. Name the org `Acme Corporation`
3. Input Acme's organizatiom ID as `ACME Corp`. Note that this is the organization ID that was sent to the ingestion URL.
4. Click "Save"

<figure><img src="/files/laZRABQzvPg22tFw44ub" alt="" width="374"><figcaption><p>Creating customer on the slaOS UI</p></figcaption></figure>
{% endtab %}
{% endtabs %}


# Build a SLA

Follow this guide to create a Service Level Agreement (SLA) in slaOS.

SLAs are formal commitments between a customer and a vendor about a

&#x20;service's reliability. This tutorial will show you how to configure a SLA  on a per organization basis.

{% hint style="info" %}
Note: You must have an Organization and SLO defined before you can create an SLA. To learn how to create an org, you can head to [Create an Organization](/how-tos/tutorials/create-an-organization) and to learn how to create a SLO, head to [Build a SLO](/how-tos/tutorials/build-a-slo).
{% endhint %}

## Create an SLA

Follow these steps to create a Service Level Agreement (SLA):

1. Find and click on "Agreements" in the side navigation bar. Click the "+ New SLA" button to open the Create SLO modal. Alternatively, you can also click on the "Create SLA" button permanently located on the top navigation bar.
2. Click on the dropdown to select from your list of active Orgs. You can also add a new Org directly from the SLA modal by giving it a name and ID.
3. Define the SLA duration by setting a Start Date and End Date. For ease, we have provided presets that'll accurately help you set durations like a week, month, quarter and year.
4. Using the dropdown, select the SLOs that you want to capture under your SLA. Note that you can choose multiple SLOs within a SLA.

{% hint style="warning" %}
Each SLO comes with it's own set of SLIs, compliance period and target. We calculate these individually per organization and perform an aggregation to qualify whether or not a SLA is in breach.
{% endhint %}

5. A name and description will be auto filled for your SLA based on it's SLO configuration
6. Click the "Save" button to create your new SLA

### Example

{% tabs %}
{% tab title="DRPC's SLA" %}
For the example implementation, we will be creating a SLA for DRPC with two SLOs, Availability and Latency

1. Click "Create SLA" on the top navigation
2. We will select "DRPC" as the organization
3. Set Jul 2024 -> Jul 2025 as the duration of the SLA
4. Select Availability and Latency SLOs that were created previously
5. The SLA will  get the following name: `SLA for DRPC` and description `Cloudflare Gateway Availability Rate above 99% and Cloudflare Gateway Latency under 30ms [P90] will be evaluated over 1 year` via the autofill feature. \
   \
   Note: You can also edit the autofilled name and description.

<figure><img src="/files/tHCEdkYuwnRmhp60G2Sj" alt=""><figcaption><p>Availability and Latency SLA for DRPC</p></figcaption></figure>
{% endtab %}
{% endtabs %}


# Configure a SLA Portal

This tutorial walks you through configuring a SLA Portal in slaOS.

As a vendor,  in this page you will learn to customize and set up a dedicated dashboard that provides your customers with real-time insights into your service's performance and SLA compliance.

{% hint style="warning" %}
Brand customization for SLA portals is not yet available in the slaOS UI. Contact us at <hello@rated.co> or via your dedicated Slack channel for configuration.
{% endhint %}

## Enabling a SLA Portal

1. Find and click "Organizations" on the side navigation
2. Select the org you would like to enable the SLA portal for
3. Turn on the toggle to Activate<br>

   <figure><img src="/files/Km4Wozq5ZE3sK2Kc1ivw" alt=""><figcaption><p>SLA portal for DRPC</p></figcaption></figure>
4. You can now visit the URL mentioned in step 3 to view your active SLA portal.

### **Example SLA Portal 👇**

<figure><img src="/files/QhE99IbIijzBow1MRVKr" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
The SLA Portal URL is a unique, static URL created per org. You can share this with your integrations or embed it behind a call to action on your own product to help your customers track their SLAs with you.
{% endhint %}

## Disabling a SLA Portal

1. Find and click "Organizations" on the side navigation
2. Select the org you would like to enable the SLA portal for
3. Turn off the toggle to deactivate<br>

   <figure><img src="/files/BNAvpfCg1369NqUgCMny" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Once deactivated, a SLA Portal URL becomes inaccessible. We recommend keeping your customers (or vendors) with access informed before deactivating the portal.
{% endhint %}


# Guides

Best practices, tips & tricks, common issues and more

`[COMING SOON]`


# Glossary

Terms and diction you need to be aware of to make the most of slaOS

`[COMING SOON]`


# Terms of Service

Last updated: September 17, 2024

## 1. Introduction

Welcome to slaOS by Rated. By accessing or using our Service, you agree to be bound by these Terms of Service (‘Terms’). Please read them carefully. These Terms govern your access to and use of the Service. They establish a legal agreement between you and Rated Labs Ltd regarding the use of slaOS by Rated.

In these Terms:

* ‘Company’ means Rated Labs Ltd.
* ‘Service’ means the software product slaOS by Rated provided by the Company.
* ‘User’ means any individual or entity accessing or using the Service.
* ‘Terms’ refers to this Terms of Service agreement.

These Terms govern your access to and use of the Service. They establish a legal agreement between you and Rated Labs Ltd regarding the use of slaOS by Rated

## 2. Description of the Service

slaOS by Rated is a software product provided by Rated Labs Ltd that allows users to send their own data to our system. Users can submit data in the form of metrics or raw logs through our available data API or via the different integrations we support. We process and store this data in our database to produce outcomes based on the Service Level Agreement (SLA) logic that users define within the product. This enables users to transform their data and instantiate various business workflows based on the processed results.

## 3. User Accounts

Users can create an account by visiting[ auth.rated.co](https://auth.rated.co). To register, you must:

* Provide your email address.
* Generate a strong, unique password.
* Provide accurate, complete, and current information about your business.
* Promptly update your account information whenever necessary.

This Service is intended for business users. By creating an account with us, you represent and warrant that you are acting on behalf of a business entity.

You are responsible for maintaining the confidentiality of your account credentials and for all activities that occur under your account. Please notify us immediately of any unauthorized use of your account or any other security breaches.

## 4. User Obligations and Acceptable Use

By using slaOS by Rated, you agree to:

* Comply with all applicable laws and regulations while using the Service.
* Provide accurate and lawful data: Ensure that all data you submit is accurate, complete, and does not violate any laws or third-party rights.
* Use the Service responsibly: Avoid any actions that could harm, disable, overburden, or impair the Service or interfere with any other party’s use of the Service.
* Respect intellectual property rights: Do not upload, share, or distribute content that infringes upon the intellectual property rights of others.
* Maintain confidentiality: Do not disclose any confidential information obtained through the Service without prior written consent.

You agree not to:

* Use the Service for any unlawful or unauthorized purposes.
* Attempt to gain unauthorized access to any part of the Service or its related systems or networks.
* Transmit any viruses, malware, or other harmful code through the Service.
* Engage in any activity that could interfere with or disrupt the integrity or performance of the Service.

Failure to comply with these obligations may result in suspension or termination of your access to the Service.

## 5. Data Privacy and Confidentiality

We are committed to keeping your data confidential and secure. We will not disclose your data to any third parties without your explicit consent. We will not use your data for any purpose other than executing the core functionality of the Service.

All data you provide is processed and stored securely in our database using industry-standard security measures to protect against unauthorized access, alteration, disclosure, or destruction.

Upon termination of services, we will delete all your data from our systems in a secure manner.

Your data remains your property at all times. You have the right to access, modify, or request deletion of your data by contacting us.

We comply with all applicable data protection laws and regulations, including the UK GDPR.

## 6. Monitoring of Use

We monitor how our Service is accessed and used, including through analytics code within our Service. We also collect basic information about a user as part of the account creation process as set out in our Privacy Policy.

To ensure that our Service is being used in accordance with our Terms, we track the use of the Service at a user level. The data we collect through this monitoring allows us to link the information with a User and the Service.

## 7. Intellectual Property Rights

All intellectual property rights in the Service, including the software, design, graphics, and all related materials, are owned by Rated Labs Ltd or our licensors. We grant you a limited, non-exclusive, non-transferable, and revocable license to access and use the Service solely for your internal business purposes in accordance with these Terms.

You agree not to:

* Copy, modify, reproduce, distribute, or create derivative works from any part of the Service.
* Reverse engineer, decompile, or attempt to extract the source code of the software.
* Remove, alter, or obscure any proprietary notices or labels on the Service.

All trademarks, logos, and service marks displayed on the Service are the property of their respective owners. Nothing in these Terms grants you any right or license to use any of these trademarks without the prior written permission of the owner.

Your data remains your property. These Terms do not grant us any rights to your data except for the limited rights necessary to provide the Service.

## 8. Limitation of Liability

Except as expressly stated in these Terms:

The Company shall not in any circumstances have any liability for any losses or damages which may be suffered by the Customer (or any person claiming under or through the Customer) or Customer Users, whether the same are suffered directly or indirectly or are immediate or consequential, and whether the same arise in contract, tort (including negligence) or otherwise howsoever, which fall within any of the following categories:

* special damage even if the Company was aware of the circumstances in which such special damage could arise;
* loss of profits;
* loss of anticipated savings;
* &#x20;loss of business opportunity;
* loss of goodwill;
* loss or corruption of data,

provided that this section shall not prevent claims for loss of or damage to the Customer's tangible property that fall within the liability limits set out below or any other claims for direct financial loss that are not excluded by any of the categories above.

The total liability of the Company, whether in contract, tort (including negligence) or otherwise and whether in connection with this Agreement or any collateral contract, shall in no circumstances exceed a sum equal to the total Fees paid by the Customer during the \[1] month preceding the date on which the claim arose.

## 9. Indemnity

Upon utilising our Services, you agree to indemnify, defend, and hold harmless the Company, its shareholders, directors, officers, employees, representatives, agents, subcontractors, and licensors from and against all third-party claims, damages, costs, expenses, and legal actions, including reasonable attorneys' fees and court costs, that arise out of or result from your misuse of our Services or your violation of these Terms.

## 10. Term and Termination

You may terminate your account at any time by discontinuing use of the Service and notifying us. Upon termination, you will no longer have access to your account or any features of the Service.

We reserve the right to suspend or terminate your access to the Service at any time, with or without prior notice, if we determine that you have violated these Terms or for any other reason at our sole discretion.

Upon termination of your account:

* All rights granted to you under these Terms will immediately cease.
* We will delete all your data from our systems in a secure manner.
* Any provisions of these Terms that by their nature should survive termination will remain in effect (such as intellectual property rights and limitation of liability).

## 11. Changes to the Terms

We reserve the right to revise, update, amend, or modify these Terms at any time. We will post the updated Terms on our websites. We will also email you via the email address supplied as part of the sign-up process to notify you of material changes to these Terms. We encourage you to review these Terms periodically to ensure you are aware of any changes. By continuing to use the Services after these changes take effect, you agree to be bound by the revised Terms.&#x20;

## 12. Governing Law and Dispute Resolution

These Terms of Service and any disputes or claims arising out of or in connection with them or their subject matter shall be governed by and construed in accordance with the laws of England and Wales.

You agree that the courts of England and Wales shall have exclusive jurisdiction to settle any dispute or claim arising out of or in connection with these Terms or their subject matter.

## 13. Privacy Policy

We are committed to protecting your privacy.

Our[ Privacy Policy](https://legal.rated.network/privacy/privacy-notice), incorporated herein by reference, governs the collection, processing, storage and transfer of your personal data. By using our API Services, you acknowledge that you have read, understood, and agree to the terms of our Privacy Policy.

Our Privacy Policy also describes your choices regarding our use of your personal data and how you can access, update, and manage this information. We encourage you to periodically review our Privacy Policy to stay informed about our privacy practices.

## 14. Severability

Should any provision, or part thereof, within these Terms be found to be unlawful, void, or unenforceable, such provision will be considered severable from these Terms and will not affect the validity and enforceability of the remaining provisions. The remainder of the Terms will remain valid and enforceable to the fullest extent permitted by law.

## 15. Entire Agreement

These Terms of Service constitute the entire agreement between you and Rated Labs Ltd regarding your use of slaOS by Rated and supersede any prior agreements or understandings.

## 16. Waiver

The failure of either party to enforce any right or provision of these Terms will not be deemed a waiver of those rights.

## 17. Assignment

You may not assign or transfer your rights or obligations under these Terms without our prior written consent. We may assign or transfer our rights and obligations under these Terms without restriction.

## 18. Force Majeure

We shall not be liable for any failure or delay in performing our obligations under these Terms due to circumstances beyond our reasonable control, including but not limited to acts of God, war, terrorism, riots, embargoes, governmental actions, fire, floods, accidents, or network infrastructure failures.

## 19. Contact us

The Terms outlined herein are subject to change at our discretion to align with evolving industry standards or best practices.

If you have any questions or comments about these Terms or wish to complain, please get in touch with us at <hello@rated.co>


# Contributor License Agreement

Rated's open source projects Contributor License Agreement (CLA)

## Human-Friendly Summary

This is a human-readable summary of (and not a substitute for) the full agreement. It highlights some key terms of the Contributor License Agreement (CLA). It has no legal value, and you should carefully review all the terms of the actual CLA before agreeing.

* **Grant of Copyright License:** You give Rated Labs permission to use your copyrighted work in commercial products.
* **Grant of Patent License:** If your contributed work uses a patent, you grant Rated Labs a license to use that patent, including within commercial products. You also confirm that you have the permission to grant this license.
* **No Warranty or Support Obligations:** By making a contribution, you are not obligated to provide support for it, nor are you providing any warranties or assurances about its performance.

The CLA does not change the terms of the underlying license used by our software. You are still free to use our projects within your own projects or businesses, republish modified source code, and more, subject to the terms of the project's license. Please refer to the appropriate license for the project you're contributing to for more information.

## Why Require a CLA?

Agreeing to a CLA explicitly states that you are entitled to provide a contribution, that you cannot withdraw permission to use your contribution at a later date, and that Rated Labs has permission to use your contribution in our commercial products.

This removes any ambiguities or uncertainties caused by not having a CLA and allows users and customers to confidently adopt our projects. At the same time, the CLA ensures that all contributions to our open-source projects are licensed under the project's respective open-source license.

Requiring a CLA is a common and well-accepted practice in open source. Major open-source projects require CLAs, such as Apache Software Foundation (ASF) projects, React (Facebook), Go (Google) , Python, Django, and more. Each of these projects remains licensed under permissive open-source licenses such as MIT, Apache, BSD, and others.

## Signing the CLA

By opening a pull request (PR) to any of our open-source projects, you declare that you have read, understood, and agree to the terms of our Contributor License Agreement (CLA). Submitting a PR signifies your acceptance of the CLA without the need for a separate signature.

You only need to agree to the CLA once. Future contributions to any of our projects will not require you to agree again.

## Legal Terms and Agreement

To clarify the intellectual property license granted with contributions from any person or entity, Rated Labs ("Rated") must have a Contributor License Agreement ("CLA") on file that has been agreed to by each contributor, indicating agreement to the license terms below. This license does not change your rights to use your own contributions for any other purpose.

You accept and agree to the following terms and conditions for your present and future contributions submitted to Rated. Except for the license granted herein to Rated and recipients of software distributed by Rated, you reserve all rights, title, and interest in and to your contributions.

### **1. Definitions**

"**You**" or "**Your**" refers to the copyright owner or legal entity authorized by the copyright owner entering into this agreement with Rated. For legal entities, the entity making a contribution and all other entities that control, are controlled by, or are under common control with that entity are considered a single contributor. For this definition, "**control**" means:

1. the direct or indirect power to direct or manage such entity, whether by contract or otherwise;
2. ownership of fifty percent (50%) or more of the outstanding shares; or
3. beneficial ownership of such entity.

"**Contribution**" means any original work of authorship, including any modifications or additions to an existing work, that is or has been intentionally submitted by you to Rated for inclusion in, or documentation of, any of the products owned or managed by Rated (the "**Work**"). For this definition, "**submitted**" means any form of electronic, verbal, or written communication sent to Rated or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems managed by, or on behalf of, Rated for discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by you as "**Not a Contribution**."

### **2. Grant of Copyright License**

Subject to the terms and conditions of this agreement, you hereby grant to Rated and to recipients of software distributed by Rated a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute your contributions and such derivative works.

### **3. Grant of Patent License**

Subject to the terms and conditions of this agreement, you hereby grant to Rated and to recipients of software distributed by Rated a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work. This license applies only to those patent claims licensable by you that are necessarily infringed by your contribution(s) alone or by combination of your contribution(s) with the Work to which such contribution(s) was submitted. If any entity institutes patent litigation against you or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your contribution or the Work to which you have contributed constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this agreement for that contribution or Work shall terminate as of the date such litigation is filed.

### **4. Representations**

You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create, including your contributions, you represent that:

1. you have received permission to make contributions on behalf of that employer;
2. your employer has waived such rights for all your contributions to Rated; or
3. your employer has executed a separate Corporate CLA with Rated.

### **5. Original Creation**

You represent that each of your contributions is your original creation. You also represent that your contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and that are associated with any part of your contributions.

### **6. No Support or Warranties**

You are not expected to provide support for your contributions, except as you desire. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, you provide your contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.

### **7. Third-Party Works**

Should you wish to submit work that is not your original creation, you may submit it to Rated separately from any contribution. Identify the complete details of its source and any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously mark the work as "Submitted on behalf of a third-party: \[named here]."

### **8. Notification of Changes**

You agree to notify Rated of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect.

<br>


# Privacy Notice

Last updated: September 17, 2024

*Rated Labs is committed to protecting your privacy. This Privacy Notice ("Notice"), together with our website terms of use and any other documents referred to in it, sets out the types of personal information we collect, how we collect and process that information, who we share it with in relation to the services we provide and certain rights and options that you have in this respect.*

Rated Labs owns and operates this website <https://rated.co> (“site”).

#### **Who is responsible for your personal data?** <a href="#who-is-responsible-for-your-personal-data" id="who-is-responsible-for-your-personal-data"></a>

Rated Labs is responsible for your personal data. Rated Labs comprises Rated Labs Limited (a limited company incorporated in England & Wales, registered number 14036060) (referred to as "Rated Labs" or "we" or "our"). For the purposes of applicable data protection law (in particular, the General Data Protection Regulation (EU) 2016/679 (the "GDPR") as applicable as part of UK domestic law by virtue of section 3 of the European Union (Withdrawal) Act 2018 and as amended by the Data Protection, Privacy and Electronic Communications (Amendments etc) (EU Exit) Regulations 2019 (as amended) (“UK GDPR”)), your data will be controlled by the Rated Labs as the independent data controller of your personal data. This Notice applies to all sites that operate under Rated Labs sites.

#### **Personal data we collect** <a href="#personal-data-we-collect" id="personal-data-we-collect"></a>

We (might) collect and process the following personal data from you, where these apply:

* **Identity and Contact Data**, including your name, email address, and other personal data concerning your preferences relevant to our services.
* **Profile and Usage Data**, including user credentials, passwords to Rated Labs websites or password protected platforms or services, your preferences in receiving marketing information from us, your communication preferences and information about how you use our websites(s), including the services you viewed or searched for, page response times, download errors, length of visits and page interaction information (such as scrolling, clicks, and mouse-overs). To learn more about our use of cookies or similar technology please see the “What cookies do we use and what information do they collect?” section below.
* **Technical Data**, including information collected during your visits to our website(s), the Internet Protocol (IP) address, login data, browser type and version, device type, time zone setting, browser plug-in types and versions, operating system and platform. To learn more about our use of cookies or similar technology please see the “What cookies do we use and what information do they collect?” section below.

#### **Information about other people** <a href="#information-about-other-people" id="information-about-other-people"></a>

If you provide information to us about any person other than yourself, your employees, counterparties, your advisers or your suppliers, you must ensure that they understand how their information will be used, and that they have given their permission for you to disclose it to us and for you to allow us, and our outsourced service providers, to use it.

#### **How do we collect your personal data?** <a href="#how-do-we-collect-your-personal-data" id="how-do-we-collect-your-personal-data"></a>

The circumstances in which we can collect personal data about you include:

* when you or your organisation use our services or use any of our online services;
* when you or your organisation offer to provide, or provides, services to us;
* when you correspond with us by email or other electronic means, or in writing, or when you provide other information directly to us, including in conversation with our staff;
* when you or your organisation browse, complete a form or make an enquiry or otherwise interact on our website or other online platforms;
* when you attend our events or sign up to receive information from us;
* We may use cookies on our website and to provide the services. Cookies are tiny data files placed on your device that contain a unique identifier that identify your browser. Cookies allow us to collect information about you as a user, to improve our platform, store preferences and settings, and help with sign-in. While you can manage cookies in your Account’s preferences setting, if you disable cookies, you may not be able to use or access some or all of the Services.
* Our web pages may contain electronic images known as web beacons (also called single- pixel gifs) that we use to help deliver cookies on our websites and to count users who have visited those websites. We may also include web beacons in our promotional email messages or newsletters to determine whether and when you open and act on them. When we talk about cookies in this Notice, this term includes these similar technologies.

#### **What cookies do we use and what information do they collect?** <a href="#what-cookies-do-we-use-and-what-information-do-they-collect" id="what-cookies-do-we-use-and-what-information-do-they-collect"></a>

* **Necessary cookies:** these cookies are required to enable core functionality. Without these cookies, services you have asked for cannot be provided. If you disable these cookies certain parts of the Services will not function for you.
* **Analytics cookies:** these cookies help us improve or optimise the experience we provide. They allow us to measure how visitors interact with the Services and we use this information to improve the user experience and performance of our website and the Services. These cookies are used to collect technical information such as the number of pages visited, which parts of our website are clicked on and the length of time between clicks.
* **Functional cookies:** We may use cookies that are not essential but enable various helpful features on the Site. For example, these cookies collect information about your interaction with services provided on the Site.

We keep information collected from cookies for a maximum of 6 months.

#### **If you fail to provide personal data** <a href="#if-you-fail-to-provide-personal-data" id="if-you-fail-to-provide-personal-data"></a>

Where we need to collect personal data by law or in order to process your instructions or perform a contract we have with you and you fail to provide that data when requested, we may not be able to carry out your instructions or perform the contract we have or are trying to enter into with you. In this case, we may have to cancel our engagement or contract you have with us, but we will notify you if this is the case at the time.

#### How will we use your personal data? <a href="#how-will-we-use-your-personal-data" id="how-will-we-use-your-personal-data"></a>

We use your personal data only for the following purposes:

* To fulfil a contract, or take steps linked to a contract, with you or your organisation. This includes:
  * to register you as a user of Rated Labs and grant you access to the Rated APIs via the site; and
  * to provide and administer services as instructed by you or your organisation.
* As required by Rated Labs to conduct our business and pursue our legitimate interests, in particular:
  * to administer and manage our relationship with you, including accounting, auditing, and taking other steps linked to the performance of our business relationship including identifying persons authorised to represent our customers, suppliers or service providers;
  * to analyse and improve our services and communications, monitor user numbers and to monitor compliance with our policies and standards;
  * to protect the security of our communications and other systems and to prevent and detect security threats, frauds or other criminal or malicious activities;
  * to exercise or defend our legal rights or to comply with court orders;
  * to communicate with you to keep you up-to-date on the latest developments, announcements, and other information about our services and solutions (including briefings, newsletters and other information), events and initiatives;
  * to send you details of client surveys, marketing campaigns, market analysis, or other promotional activities; and
  * to collect information about your preferences to personalise and improve the quality of our communications with you.
* For purposes required by law, including maintaining records, compliance checks or screening and recording (e.g. fraud and crime prevention and detection, trade sanctions and embargo laws). This can include making records of our communications with you for compliance purposes.
* With your consent, we may use your data to manage your email subscriptions, improve the relevance of our website, send you periodic marketing communications about the services we provide, invite you to participate in contests, promotions, surveys or other features of the services and to improve the relevance of our advertising.

We will not use your personal data for taking any automated decisions affecting or creating profiles other than as described above.

#### Disclosure of your personal data <a href="#disclosure-of-your-personal-data" id="disclosure-of-your-personal-data"></a>

We may share your personal data, in the following circumstances:

* with our affiliates for the purposes of providing you with our services as described in this Notice;
* with third parties including certain service providers we have retained in connection with the services we provide;
* on a confidential basis with third parties for the purposes of collecting your feedback on the company’s service provision, to help us measure our performance and to improve and promote our services;
* with courts, law enforcement authorities, regulators, government officials or attorneys or other parties where it is reasonably necessary for the establishment, exercise or defence of a legal or equitable claim, or for the purposes of a confidential alternative dispute resolution process;
* with service providers who we engage within or outside of Rated Labs, domestically or abroad, e.g. shared service centres, to process personal data for any of the purposes listed above on our behalf and in accordance with our instructions only; and
* if we sell or buy any business or assets, in which case we may disclose your personal data to the prospective seller or buyer of such business or assets to whom we assign or novate any of our rights and obligations.

#### Information we transfer <a href="#information-we-transfer" id="information-we-transfer"></a>

When we transfer your information to other countries, we will use, share and safeguard that information as described in this Notice. To provide our services, we may transfer the personal information we collect to countries outside of the EEA and UK which do not provide the same level of data protection as the country in which you reside and are not recognised by the European Commission or UK Information Commissioner as providing an adequate level of data protection. We only transfer personal information to these countries when it is necessary for the services we provide you, or it is necessary for the establishment, exercise or defence of legal claims or subject to safeguards that assure the protection of your personal information, such as European Commission approved standard contractual clauses or the Information Commissioner approved International Data Transfer Agreement or Addendum.

Rated Labs ensures a level of data protection at least as protective as that required in the European Economic Area and United Kingdom.

For further information, including obtaining a copy of the documents used to protect your information, please contact us on <hello@rated.co>.

#### Security of your personal data <a href="#security-of-your-personal-data" id="security-of-your-personal-data"></a>

We have put in place appropriate security measures to prevent your personal data from being accidentally lost, used or accessed in an unauthorised way, altered or disclosed. We have also put in place procedures to deal with any suspected personal data breach and will notify you and any applicable regulator of a breach where we are legally required to do so.

#### Updating personal data about you <a href="#updating-personal-data-about-you" id="updating-personal-data-about-you"></a>

If any of the personal data that you have provided to us changes, for example if you change your email address or if you wish to cancel any request you have made of us, or if you become aware we have any inaccurate personal data about you, please let us know by sending an email to <hello@rated.co>. We will not be responsible for any losses arising from any inaccurate, inauthentic, deficient or incomplete personal data that you provide to us.

#### Your Rights <a href="#your-rights" id="your-rights"></a>

You have various rights with respect to our use of your personal data:

* Access: You have the right to request a copy of the personal data that we hold about you. There are exceptions to this right, so that access may be denied if, for example, making the information available to you would reveal personal data about another person, or if we are legally prevented from disclosing such information. You are entitled to see the personal data held about you. If you wish to do this, please contact us using the contact details provided below.
* Accuracy: We aim to keep your personal data accurate, current, and complete. We encourage you to contact us to let us know if any of your personal data is not accurate or changes, so that we can keep your personal data up-to-date.
* Objecting: In certain circumstances, you also have the right to object to processing of your personal data and to ask us to block, erase and restrict your personal data. If you would like us to stop using your personal data, please contact us.
* Porting: You have the right to request that some of your personal data is provided to you, or to another data controller, in a commonly used, machine-readable format.
* Erasure: You have the right to ask us to erase your personal data when the personal data is no longer necessary for the purposes for which it was collected, or when, among other things, your personal data have been unlawfully processed.
* Complaints: If you believe that your data protection rights may have been breached, you have the right to lodge a complaint with the applicable supervisory authority, or to seek a remedy through the courts.

You may, at any time, exercise any of the above rights, by contacting <hello@rated.co>.

#### Right to withdraw consent <a href="#right-to-withdraw-consent" id="right-to-withdraw-consent"></a>

If you have provided your consent to the collection, processing and transfer of your personal data, you have the right to fully or partly withdraw your consent. Once we have received notification that you have withdrawn your consent, we will no longer process your information for the purpose(s) to which you originally consented unless there is another legal ground for the processing.

To opt-out of receiving our marketing communications t please follow the opt-out links on any marketing message sent to you or contact <hello@rated.co>. Opting out of receiving marketing communications will not affect the processing of personal data for the provision of our services.

#### How long we keep your personal data <a href="#how-long-we-keep-your-personal-data" id="how-long-we-keep-your-personal-data"></a>

We will only retain your personal data for as long as necessary to fulfil the purposes we collected it for, including for the purposes of satisfying any legal, accounting, or reporting requirements and, where required for Rated Labs to assert or defend against legal claims, until the end of the relevant retention period or until the claims in question have been settled. If you want to learn more about our specific retention periods for your personal data established in our retention policy you may contact us at <hello@rated.co>. Upon expiry of the applicable retention period we will securely destroy your personal data in accordance with applicable laws and regulations.

#### Changes to our Privacy Notice <a href="#changes-to-our-privacy-notice" id="changes-to-our-privacy-notice"></a>

We reserve the right to update and change this Notice from time to time in order to reflect any changes to the way in which we process your personal data or changing legal requirements. Any changes we may make to our Notice in the future will be posted on this page and, where appropriate, notified to you by email. Please check back frequently to see any updates or changes to our Notice.

#### Contact Details <a href="#contact-details" id="contact-details"></a>

Questions, comments and requests regarding this Notice are welcomed and should be addressed to <hello@rated.co>, or send a letter to Rated Labs Limited, 12 New Fetter Lane, London EC4A 1JP.


