> ## Documentation Index
> Fetch the complete documentation index at: https://chainpatrol.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Organization Metrics

> Get metrics for your organization with optional date range and brand filtering. Organization is determined from your API key.

## Overview

Retrieve security metrics for your organization, including threat detections, blocked assets, takedowns, and more. This endpoint provides comprehensive analytics about your organization's security posture. The organization is automatically inferred from your API key.

## Quick Start

### Authentication

Include your API key in the `X-API-KEY` header:

```bash theme={null}
X-API-KEY: your_api_key_here
```

### Example Request

<CodeGroup>
  ```typescript TypeScript theme={null}
  const response = await fetch(
    "https://app.chainpatrol.io/api/v2/organization/metrics?startDate=2024-01-01T00:00:00Z&endDate=2024-12-31T23:59:59Z",
    {
      method: "GET",
      headers: {
        "X-API-KEY": "YOUR_API_KEY_HERE",
      },
    }
  );

  const data = await response.json();
  console.log(data.metrics);
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://app.chainpatrol.io/api/v2/organization/metrics?startDate=2024-01-01T00:00:00Z&endDate=2024-12-31T23:59:59Z",
    {
      method: "GET",
      headers: {
        "X-API-KEY": "YOUR_API_KEY_HERE",
      },
    }
  );

  const data = await response.json();
  console.log(data.metrics);
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://app.chainpatrol.io/api/v2/organization/metrics",
      headers={
          "X-API-KEY": "YOUR_API_KEY_HERE",
      },
      params={
          "startDate": "2024-01-01T00:00:00Z",
          "endDate": "2024-12-31T23:59:59Z",
      },
  )

  data = response.json()
  print(data["metrics"])
  ```

  ```bash cURL theme={null}
  curl -X GET 'https://app.chainpatrol.io/api/v2/organization/metrics?startDate=2024-01-01T00:00:00Z&endDate=2024-12-31T23:59:59Z' \
    -H 'X-API-KEY: YOUR_API_KEY_HERE'
  ```
</CodeGroup>

## Query Parameters

| Parameter | Type   | Required | Description                                                                              |
| --------- | ------ | -------- | ---------------------------------------------------------------------------------------- |
| brandSlug | string | No       | Filter metrics by specific brand. Requires brands-metrics feature flag.                  |
| startDate | string | No       | Start date for metrics (ISO 8601 format). Defaults to beginning of time if not provided. |
| endDate   | string | No       | End date for metrics (ISO 8601 format). Defaults to current date if not provided.        |

## Response

### Success Response

```json theme={null}
{
  "metrics": {
    "reports": 150,
    "newThreats": 245,
    "threatsWatchlisted": 18,
    "takedownsFiled": 45,
    "takedownsCompleted": 32,
    "domainThreats": 120,
    "twitterThreats": 40,
    "telegramThreats": 25,
    "otherThreats": 60
  },
  "blockedByType": [
    {
      "type": "URL",
      "count": 120
    },
    {
      "type": "ADDRESS",
      "count": 85
    },
    {
      "type": "TWITTER",
      "count": 40
    }
  ],
  "blockedByDay": [
    {
      "date": "2024-01-15",
      "count": 12
    },
    {
      "date": "2024-01-16",
      "count": 8
    }
  ]
}
```

### Response Fields

| Field                      | Type   | Description                                                  |
| -------------------------- | ------ | ------------------------------------------------------------ |
| metrics                    | object | Metrics object containing all security statistics            |
| metrics.reports            | number | Total number of reports filed                                |
| metrics.newThreats         | number | Number of new threats blocked                                |
| metrics.threatsWatchlisted | number | Number of threats watchlisted (0 for brand-filtered queries) |
| metrics.takedownsFiled     | number | Total number of takedown requests filed                      |
| metrics.takedownsCompleted | number | Total number of takedowns successfully completed             |
| metrics.domainThreats      | number | Number of URL/domain threats blocked                         |
| metrics.twitterThreats     | number | Number of Twitter threats blocked                            |
| metrics.telegramThreats    | number | Number of Telegram threats blocked                           |
| metrics.otherThreats       | number | Number of other asset type threats blocked                   |
| blockedByType              | array  | Breakdown of blocked threats by asset type                   |
| blockedByType\[].type      | string | Type of asset (URL, ADDRESS, TWITTER, etc.)                  |
| blockedByType\[].count     | number | Number of threats blocked for this asset type                |
| blockedByDay               | array  | Time series data showing threats blocked per day             |
| blockedByDay\[].date       | string | Date in YYYY-MM-DD format                                    |
| blockedByDay\[].count      | number | Number of threats blocked on this date                       |

## Metric Types

### Organization-Level Metrics (Default)

When no `brandSlug` is provided, returns organization-wide metrics:

* Aggregates all proposals, reports, and takedowns for the organization
* Includes threats with status BLOCKED, APPROVED, and AUTO\_APPROVED
* Date filtering applies to `createdAt` timestamps
* Includes all brands under the organization

### Brand-Level Metrics (Optional)

When `brandSlug` is provided (requires brands-metrics feature flag):

* Filters metrics to specific brand via review history
* Queries asset status history to find brand-specific blocked threats
* Uses status history table with brand reviews
* Date filtering for takedowns uses `updatedAt` timestamps
* **Note:** `threatsWatchlisted` always returns 0 for brand-scoped queries

## Use Cases

### Get All-Time Metrics

Retrieve metrics for your organization's entire history:

```typescript theme={null}
const response = await fetch(
  "https://app.chainpatrol.io/api/v2/organization/metrics",
  {
    headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
  }
);

const { metrics, blockedByType, blockedByDay } = await response.json();
console.log(`Total new threats: ${metrics.newThreats}`);
console.log(`Blocked by type:`, blockedByType);
```

### Get Brand-Specific Metrics

Retrieve metrics filtered to a specific brand:

```typescript theme={null}
const response = await fetch(
  "https://app.chainpatrol.io/api/v2/organization/metrics?brandSlug=my-brand",
  {
    headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
  }
);

const { metrics } = await response.json();
console.log(`Brand threats blocked: ${metrics.newThreats}`);
```

### Get Monthly Metrics

```typescript theme={null}
async function getMonthlyMetrics(year: number, month: number) {
  const startDate = new Date(year, month - 1, 1);
  const endDate = new Date(year, month, 0, 23, 59, 59);

  const response = await fetch(
    `https://app.chainpatrol.io/api/v2/organization/metrics?startDate=${startDate.toISOString()}&endDate=${endDate.toISOString()}`,
    {
      headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
    }
  );

  const { metrics } = await response.json();
  return metrics;
}

// Get metrics for January 2024
const janMetrics = await getMonthlyMetrics(2024, 1);
console.log("January 2024 metrics:", janMetrics);
```

### Compare Time Periods

```typescript theme={null}
async function compareMetrics(period1Start: string, period1End: string, period2Start: string, period2End: string) {
  const [period1Response, period2Response] = await Promise.all([
    fetch(
      `https://app.chainpatrol.io/api/v2/organization/metrics?startDate=${period1Start}&endDate=${period1End}`,
      { headers: { "X-API-KEY": "YOUR_API_KEY_HERE" } }
    ),
    fetch(
      `https://app.chainpatrol.io/api/v2/organization/metrics?startDate=${period2Start}&endDate=${period2End}`,
      { headers: { "X-API-KEY": "YOUR_API_KEY_HERE" } }
    ),
  ]);

  const period1 = await period1Response.json();
  const period2 = await period2Response.json();

  const change = {
    reportsCount: period2.metrics.reportsCount - period1.metrics.reportsCount,
    threatsBlocked: period2.metrics.threatsBlockedCount - period1.metrics.threatsBlockedCount,
    detections: period2.metrics.totalDetections - period1.metrics.totalDetections,
  };

  console.log("Period-over-period change:", change);
  return change;
}
```

### Analyze Threat Distribution

```typescript theme={null}
async function analyzeThreats() {
  const response = await fetch(
    "https://app.chainpatrol.io/api/v2/organization/metrics",
    {
      headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
    }
  );

  const { metrics, blockedByType } = await response.json();

  // Calculate percentages by asset type
  const total = metrics.newThreats;
  const distribution = blockedByType.map((item) => ({
    type: item.type,
    count: item.count,
    percentage: ((item.count / total) * 100).toFixed(2),
  }));

  console.log("Threat distribution:", distribution);
  return distribution;
}
```

### Visualize Threats Over Time

```typescript theme={null}
async function getThreatsTimeSeries(days: number = 30) {
  const endDate = new Date();
  const startDate = new Date();
  startDate.setDate(startDate.getDate() - days);

  const response = await fetch(
    `https://app.chainpatrol.io/api/v2/organization/metrics?startDate=${startDate.toISOString()}&endDate=${endDate.toISOString()}`,
    {
      headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
    }
  );

  const { blockedByDay } = await response.json();

  // Use blockedByDay for time series visualization
  console.log("Threats per day:", blockedByDay);
  return blockedByDay;
}
```

### Generate Security Dashboard

```typescript theme={null}
async function generateDashboard(days: number = 30) {
  const endDate = new Date();
  const startDate = new Date();
  startDate.setDate(startDate.getDate() - days);

  const response = await fetch(
    `https://app.chainpatrol.io/api/v2/organization/metrics?startDate=${startDate.toISOString()}&endDate=${endDate.toISOString()}`,
    {
      headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
    }
  );

  const { metrics } = await response.json();

  const { metrics, blockedByType } = await response.json();

  const dashboard = {
    period: `Last ${days} days`,
    summary: {
      totalReports: metrics.reports,
      newThreats: metrics.newThreats,
      threatsWatchlisted: metrics.threatsWatchlisted,
      takedownSuccessRate: 
        metrics.takedownsFiled > 0
          ? ((metrics.takedownsCompleted / metrics.takedownsFiled) * 100).toFixed(1) + "%"
          : "N/A",
      breakdown: {
        domains: metrics.domainThreats,
        twitter: metrics.twitterThreats,
        telegram: metrics.telegramThreats,
        other: metrics.otherThreats,
      }
    },
    topThreats: blockedByType
      .sort((a, b) => b.count - a.count)
      .slice(0, 3),
  };

  return dashboard;
}

// Usage
const dashboard = await generateDashboard(30);
console.log("Security Dashboard:", dashboard);
```

### Export Metrics Report

```typescript theme={null}
async function exportMetricsReport(startDate: string, endDate: string) {
  const response = await fetch(
    `https://app.chainpatrol.io/api/v2/organization/metrics?startDate=${startDate}&endDate=${endDate}`,
    {
      headers: { "X-API-KEY": "YOUR_API_KEY_HERE" },
    }
  );

  const { metrics } = await response.json();

  const { metrics, blockedByType } = await response.json();

  const report = `
Security Metrics Report
Period: ${startDate} to ${endDate}
Generated: ${new Date().toISOString()}

Overview:
- Reports Filed: ${metrics.reports}
- New Threats Blocked: ${metrics.newThreats}
- Threats Watchlisted: ${metrics.threatsWatchlisted}
- Domain Threats: ${metrics.domainThreats}
- Twitter Threats: ${metrics.twitterThreats}
- Telegram Threats: ${metrics.telegramThreats}
- Other Threats: ${metrics.otherThreats}

Takedowns:
- Filed: ${metrics.takedownsFiled}
- Completed: ${metrics.takedownsCompleted}
- Success Rate: ${metrics.takedownsFiled > 0 ? ((metrics.takedownsCompleted / metrics.takedownsFiled) * 100).toFixed(1) : 0}%

Threats by Asset Type:
${blockedByType
  .map((item) => `- ${item.type}: ${item.count}`)
  .join("\n")}
  `;

  return report;
}
```

## Error Responses

### 401 Unauthorized

Returned when the API key is missing, invalid, or doesn't have organization access:

```json theme={null}
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "API key with organization access required"
  }
}
```

### 400 Bad Request

Returned when query parameters are invalid:

```json theme={null}
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Invalid date format. Use ISO 8601 format."
  }
}
```

### 404 Not Found

Returned when brand slug is not found or doesn't belong to your organization:

```json theme={null}
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Brand not found"
  }
}
```

## Best Practices

### Date Ranges

* Always use ISO 8601 format for dates: `YYYY-MM-DDTHH:mm:ss.sssZ`
* Include timezone information (typically UTC with `Z` suffix)
* Omit both dates to get all-time metrics
* Use consistent date ranges when comparing periods

### Performance

* Cache metrics data with appropriate TTL (e.g., 1 hour for dashboards)
* Use date filters to query specific time periods rather than filtering client-side
* Consider scheduling periodic metric snapshots for historical tracking

### Analysis

* Compare metrics across different time periods to identify trends
* Monitor the takedown success rate to assess enforcement effectiveness
* Track threats by asset type to understand attack patterns

## Notes

* Organization is automatically determined from your API key
* All timestamps are in ISO 8601 format with UTC timezone
* If no date range is provided, all-time metrics are returned
* Metrics are calculated in real-time based on the specified date range
* The `blockedByType` array includes all asset types that have blocked threats
* The `blockedByDay` array provides time series data for visualization
* Brand filtering requires the brands-metrics feature flag
* All queries exclude soft-deleted records
* Date ranges are inclusive
* For brand-filtered queries, `threatsWatchlisted` always returns 0
* Date filtering for takedowns uses different timestamps for brand vs organization queries


## OpenAPI

````yaml GET /organization/metrics
openapi: 3.0.3
info:
  title: ChainPatrol External API - OpenAPI 3.0
  description: ChainPatrol External API documentation
  version: 2.0.0
servers:
  - url: https://app.chainpatrol.io/api/v2
security: []
tags:
  - name: asset
  - name: report
externalDocs:
  url: https://chainpatrol.com/docs
paths:
  /organization/metrics:
    get:
      tags:
        - organization
      summary: Get organization metrics
      description: >-
        Get metrics for your organization with optional date range and brand
        filtering. Organization is determined from your API key.
      operationId: organizationMetricsGet
      parameters:
        - in: query
          name: brandSlug
          schema:
            type: string
        - in: query
          name: startDate
          schema:
            type: string
        - in: query
          name: endDate
          schema:
            type: string
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  metrics:
                    type: object
                    properties:
                      reports:
                        type: number
                      newThreats:
                        type: number
                      threatsWatchlisted:
                        type: number
                      takedownsFiled:
                        type: number
                      takedownsCompleted:
                        type: number
                      domainThreats:
                        type: number
                      twitterThreats:
                        type: number
                      telegramThreats:
                        type: number
                      otherThreats:
                        type: number
                    required:
                      - reports
                      - newThreats
                      - threatsWatchlisted
                      - takedownsFiled
                      - takedownsCompleted
                      - domainThreats
                      - twitterThreats
                      - telegramThreats
                      - otherThreats
                  blockedByType:
                    type: array
                    items:
                      type: object
                      properties:
                        type:
                          type: string
                        count:
                          type: number
                      required:
                        - type
                        - count
                  blockedByDay:
                    type: array
                    items:
                      type: object
                      properties:
                        date:
                          type: string
                        count:
                          type: number
                      required:
                        - date
                        - count
                required:
                  - metrics
                  - blockedByType
                  - blockedByDay
        '400':
          description: Invalid input data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.BAD_REQUEST'
        '401':
          description: Authorization not provided
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.UNAUTHORIZED'
        '403':
          description: Insufficient access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.FORBIDDEN'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.NOT_FOUND'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.INTERNAL_SERVER_ERROR'
      security:
        - ApiKey: []
components:
  schemas:
    error.BAD_REQUEST:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Invalid input data
        code:
          type: string
          description: The error code
          example: BAD_REQUEST
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Invalid input data error (400)
      description: The error information
      example:
        code: BAD_REQUEST
        message: Invalid input data
        issues: []
    error.UNAUTHORIZED:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Authorization not provided
        code:
          type: string
          description: The error code
          example: UNAUTHORIZED
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Authorization not provided error (401)
      description: The error information
      example:
        code: UNAUTHORIZED
        message: Authorization not provided
        issues: []
    error.FORBIDDEN:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Insufficient access
        code:
          type: string
          description: The error code
          example: FORBIDDEN
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Insufficient access error (403)
      description: The error information
      example:
        code: FORBIDDEN
        message: Insufficient access
        issues: []
    error.NOT_FOUND:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Not found
        code:
          type: string
          description: The error code
          example: NOT_FOUND
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Not found error (404)
      description: The error information
      example:
        code: NOT_FOUND
        message: Not found
        issues: []
    error.INTERNAL_SERVER_ERROR:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Internal server error
        code:
          type: string
          description: The error code
          example: INTERNAL_SERVER_ERROR
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Internal server error error (500)
      description: The error information
      example:
        code: INTERNAL_SERVER_ERROR
        message: Internal server error
        issues: []
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-KEY
      description: >-
        Your API key. This is required by most endpoints to access our API
        programatically. Reach out to us at
        [support@chainpatrol.io](mailto:support@chainpatrol.io?subject=Re:%20API%20Key%20for%20SDK&body=Company:%20%0AName:%20%0APurpose:%20)
        to get an API key for your use.

````