---
title: "Data sources metrics"
method: POST
path: "/api/data-sources/metrics"
tags: ["data_sources"]
---

# Data sources metrics

`POST /api/data-sources/metrics`

## Request

- Base URL: `https://beta.getsales.io/playtables/v1`
- URL: `https://beta.getsales.io/playtables/v1/api/data-sources/metrics`
- Auth: HTTP bearer and API key in header `Team-SID`

The import funnel across data sources: items_collected, promoted, duplicate, stoplisted, disqualified, failed, promotion_rate, last_collected_at over the filtered sources' items in a period (on items.created_at; the filter scopes source rows). group_by status | type | object_type adds groups[] per value: the promotion rate per source type is group_by type. aggregated.counts are source-row counts. One source's live funnel: get_data_source with data_source_items_counts; not the activity feed.

Contract:
- MCP tool `get_data_sources_metrics`, registry package `mcp.playtables/data_sources`, mount `playtables.sources`.
- Operation `metrics`, response envelope `metrics`.
- Flags: read only.

## Request body

- GetDataSourcesMetricsRequest: Request body of `get_data_sources_metrics`.
  - `filter` object: Scopes the rows the metrics are computed over: the search filter operators. Omit for all rows.
    - `sid` object: Prefix-validated ds_sc_ sid(s).
      - `eq` string: Data source sid (ds_sc_…).
      - `in` string[]
    - `playtable_sid` object: Sources feeding table X; is_null:true = orphaned by playtable deletion.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `type` object: The kind tabs of the sources page: ai_search | sender_search | post_engagement | find_people | csv | webhook.
      - `eq` 'ai_search' | 'sender_search' | 'post_engagement' | 'find_people' | 'csv' | 'webhook'
      - `in` string[]
    - `object_type` object: What the source brings: people | company.
      - `eq` 'people' | 'company'
      - `in` string[]
    - `sender_profile_sid` object: Sources run by a given sender profile (ub_sp_…); is_null:true = everything the platform pool or a file feeds.
      - `eq` string
      - `in` string[]
      - `is_null` boolean
    - `status` object
      - `eq` 'draft' | 'active' | 'paused' | 'completed' | 'failed'
      - `ne` 'draft' | 'active' | 'paused' | 'completed' | 'failed'
      - `in` string[]
      - `nin` string[]
    - `q` string: Free text over name only (MySQL LIKE, infix).
    - `next_collect_at` object: Due/overdue scans; ISO 8601. is_null:true = clock-less (csv, webhook, and a bus-served sender search).
      - `gte` string
      - `lte` string
      - `is_null` boolean
    - `created_at` object: ISO 8601 range; combine bounds in one object.
      - `gte` string
      - `lte` string
      - `gt` string
      - `lt` string
    - `deleted_at` object: Default scope is { is_null: true } (live rows).
      - `gte` string
      - `lte` string
      - `is_null` boolean
  - `period` object, required: Required. {from, to} ISO 8601 UTC, half-open: compute the window from the date the client knows (the last 7 days = today minus 7 to now), never from a read. Bounds the funnel by data_source_items.created_at; filter (incl. created_at) scopes source rows.
    - `from` string, required: ISO 8601 UTC window start (inclusive).
    - `to` string, required: ISO 8601 UTC window end (exclusive); must be >= from.
  - `group_by` 'status' | 'type' | 'object_type': Single axis - adds groups[] with per-value counts + metrics. Cap 500 groups.

## Response `200`

`metrics` success envelope.

- GetDataSourcesMetricsResponse
  - `success` true, required
  - `operation` 'metrics', required
  - `metrics` object, required
    - `filter` union: Echo of the request DataSourceSearchFilter (PHP empty map serialises as []).
      - object
      - unknown[]
        - unknown
    - `period` object, required
      - `from` string, required
      - `to` string, required
    - `aggregated` object, required
      - `counts` object, required
        - `total_count` integer, required: Source rows matching the filter scope.
        - `groups` object, required
          - `status` union, required
            - object
            - unknown[]
              - …
          - `type` union, required
            - object
            - unknown[]
              - …
          - `object_type` union, required
            - object
            - unknown[]
              - …
      - `metrics` object, required
        - `items_collected` integer, required: Items created within [period.from, period.to), sources in filter scope.
        - `items_promoted` integer, required: Items whose terminal transition to promoted fell in the period.
        - `items_duplicate` integer, required: Items resolved duplicate in the period (identity ladder matched a live object).
        - `items_stoplisted` integer, required: Items blocked by a stoplist match in the period.
        - `items_disqualified` integer, required: Items the source gate turned away in the period (2026-10-13).
        - `items_failed` integer, required: Items whose promotion errored in the period.
        - `promotion_rate` number, nullable, required: items_promoted / items_collected; null when items_collected is 0.
        - `last_collected_at` string, nullable, required: MAX(items.created_at) in scope - freshest ingestion; ISO 8601 UTC, null if none.
    - `groups` object[]: Present only when group_by was set - one entry per axis value. Cap 500 groups → 422.
      - `key` string, required: Value of the group_by axis (a status / type / object_type value).
      - `counts` object, required
        - `total_count` integer, required: Source rows matching the filter scope.
        - `groups` object, required
          - `status` union, required
            - object
            - unknown[]
              - …
          - `type` union, required
            - object
            - unknown[]
              - …
          - `object_type` union, required
            - object
            - unknown[]
              - …
      - `metrics` object, required
        - `items_collected` integer, required: Items created within [period.from, period.to), sources in filter scope.
        - `items_promoted` integer, required: Items whose terminal transition to promoted fell in the period.
        - `items_duplicate` integer, required: Items resolved duplicate in the period (identity ladder matched a live object).
        - `items_stoplisted` integer, required: Items blocked by a stoplist match in the period.
        - `items_disqualified` integer, required: Items the source gate turned away in the period (2026-10-13).
        - `items_failed` integer, required: Items whose promotion errored in the period.
        - `promotion_rate` number, nullable, required: items_promoted / items_collected; null when items_collected is 0.
        - `last_collected_at` string, nullable, required: MAX(items.created_at) in scope - freshest ingestion; ISO 8601 UTC, null if none.
  - `applied_filters` object
  - `meta` object, required
    - `trace_id` string, required: UUID v7; same 128-bit value as the X-Trace-Id header.
    - `span_id` string, required: 16 hex chars, root span of this request.
    - `timestamp` string, required: ISO 8601 UTC (Y-m-dTH:i:sZ), response time.
    - `duration_ms` integer, required: Server-side wall clock.
    - `team_sid` string, nullable: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends.
    - `actor_type` string, nullable: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends.

## Other responses

- `4XX`: MCP error envelope. `error.code` is one of validation_failed, nothing_to_update, not_found, relation_not_found, invalid_transition, limit_exceeded, payment_required, duplicate_rejected, conflict, delete_blocked, unauthorized, forbidden, rate_limited, not_implemented.
- `5XX`: MCP error envelope with `error.code` internal_error or service_unavailable.

---

[API](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-playtables.md) - [All operations](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-playtables/llms.txt) - [OpenAPI document](https://skmtc.dev/getsales/apis/getsales-public-contract-gs-service-playtables/revisions/aa394506515d?raw)
