---
title: "Sender profile stats"
method: POST
path: "/api/sender-profiles/stats"
tags: ["sender_profiles"]
---

# Sender profile stats

`POST /api/sender-profiles/stats`

## Request

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

What up to 200 sender profiles did, one row per sid. Today: what each LinkedIn account did against its caps (each action type with its hold and why) and the emails sent against the mailboxes' daily limits. The period from..to: the ledger's done sends and visits. The load: journeys and tasks by status. An unknown sid is left out. For "who is out of invites today" and "who is held"; identity and health: search_sender_profiles; one profile's outreach day by day: get_sender_profile_performance.

Contract:
- MCP tool `read_sender_profile_stats`, registry package `mcp.playtables/sender_profiles`, mount `playtables.sources`.
- Operation `action`, response envelope `action`.
- Flags: read only.

## Request body

- ReadSenderProfileStatsRequest: Request body of `read_sender_profile_stats`.
  - `sids` string[], required: The sender profiles to read (ub_sp_…), 1 to 200. The answer holds one row per sid that names a sender profile of the team, in no fixed order; a sid no row answers to is left out, never an error.
  - `from` string, required: The period's start: an ISO 8601 date or moment (a date reads as its midnight UTC). The ledger's done sends and profile visits from here on count under `period`; the day blocks, the week and the last action do not depend on it.
  - `to` string, required: The period's end: after `from`, at most 367 days after it (the last 12 months fit in any zone). Exclusive.

## Response `200`

`action` success envelope.

- ReadSenderProfileStatsResponse
  - `success` true, required
  - `operation` 'action', required
  - `action` string, required: kebab-case verb; matches the route segment.
  - `item` unknown, required
  - `result` object, required
    - `sender_profiles` object[], required: One row per sid asked that names a sender profile of the team, in no fixed order.
      - `sid` string, required: The sender profile the row answers for (ub_sp_…), one of the sids asked.
      - `linkedin` object, nullable, required: TODAY on LinkedIn, as the pacing mirror of gtm's smart limits counts it, per action kind against its cap and with its hold; null on a sender profile with no LinkedIn account.
        - `synced_at` string, nullable, required: When the pacing mirror last read gtm's counters (ISO 8601 UTC, the latest of the four kinds); null when never synced.
        - `invites` object, required: Connection requests.
          - `done` integer, required: Done today of this kind, in gtm's day: everything the account did, whoever asked for it.
          - `limit` integer, nullable, required: Today's cap of this kind (gtm's smart limit); null when the pacing mirror holds none.
          - `hold` boolean, required: Whether this kind is held right now: the dispatcher sends none of it until hold_until.
          - `hold_until` string, nullable, required: ISO 8601 UTC: when the hold lifts; null while not held.
          - `hold_reason` string, nullable, required: Why it is held: daily_limit_reached (the cap is spent, or gtm reported the day saturated; lifts at gtm's next day), linkedin_limit_hit (LinkedIn itself refused the action: the account is off that kind until the hold lifts) or limit_hold (a hold of another cause); null while not held.
        - `messages` object, required
          - `done` integer, required: Done today of this kind, in gtm's day: everything the account did, whoever asked for it.
          - `limit` integer, nullable, required: Today's cap of this kind (gtm's smart limit); null when the pacing mirror holds none.
          - `hold` boolean, required: Whether this kind is held right now: the dispatcher sends none of it until hold_until.
          - `hold_until` string, nullable, required: ISO 8601 UTC: when the hold lifts; null while not held.
          - `hold_reason` string, nullable, required: Why it is held: daily_limit_reached (the cap is spent, or gtm reported the day saturated; lifts at gtm's next day), linkedin_limit_hit (LinkedIn itself refused the action: the account is off that kind until the hold lifts) or limit_hold (a hold of another cause); null while not held.
        - `inmails` object, required
          - `done` integer, required: Done today of this kind, in gtm's day: everything the account did, whoever asked for it.
          - `limit` integer, nullable, required: Today's cap of this kind (gtm's smart limit); null when the pacing mirror holds none.
          - `hold` boolean, required: Whether this kind is held right now: the dispatcher sends none of it until hold_until.
          - `hold_until` string, nullable, required: ISO 8601 UTC: when the hold lifts; null while not held.
          - `hold_reason` string, nullable, required: Why it is held: daily_limit_reached (the cap is spent, or gtm reported the day saturated; lifts at gtm's next day), linkedin_limit_hit (LinkedIn itself refused the action: the account is off that kind until the hold lifts) or limit_hold (a hold of another cause); null while not held.
        - `visits` object, required: Profile visits.
          - `done` integer, required: Done today of this kind, in gtm's day: everything the account did, whoever asked for it.
          - `limit` integer, nullable, required: Today's cap of this kind (gtm's smart limit); null when the pacing mirror holds none.
          - `hold` boolean, required: Whether this kind is held right now: the dispatcher sends none of it until hold_until.
          - `hold_until` string, nullable, required: ISO 8601 UTC: when the hold lifts; null while not held.
          - `hold_reason` string, nullable, required: Why it is held: daily_limit_reached (the cap is spent, or gtm reported the day saturated; lifts at gtm's next day), linkedin_limit_hit (LinkedIn itself refused the action: the account is off that kind until the hold lifts) or limit_hold (a hold of another cause); null while not held.
      - `email` object, nullable, required: TODAY by email, in the workspace's timezone: the ledger's sends against the sum of the live mailboxes' limits, and per mailbox; null on a sender profile with no mailbox.
        - `sent` integer, required: The ledger's email sends done today, in the workspace's timezone.
        - `limit` integer, nullable, required: The sum of the live mailboxes' daily limits; null when no live mailbox states one.
        - `mailboxes` object[], required: Each of the sender profile's mailboxes in the copy's order: the Email tab's "N of M sent".
          - `email_account_sid` string, required: The mailbox (em_ac_…).
          - `sent` integer, required: Sent today from this mailbox, attributed by the mailbox a done task left from.
      - `period` object, required: The ledger's done sends and profile visits inside from..to, by kind (by finished_at).
        - `invites` integer, required
        - `messages` integer, required
        - `inmails` integer, required
        - `emails` integer, required
        - `visits` integer, required
      - `week` object[], required: The last seven days in the workspace's timezone, oldest first, today last: every done send-class task an action.
        - `date` string, required: YYYY-MM-DD in the workspace's timezone.
        - `actions` integer, required: Every done send-class task of that day.
      - `last_action` object, nullable, required: The latest done send-class task of the last 30 days; null past that.
        - `at` string, required: ISO 8601 UTC: when it finished.
        - `type` 'linkedin_send_connection_request' | 'linkedin_send_message' | 'linkedin_send_inmail' | 'linkedin_visit_profile' | 'linkedin_endorse_skills' | 'linkedin_withdraw_connection_request' | 'linkedin_like_latest_post' | 'linkedin_comment_latest_post' | 'email_send' | 'wait' | 'wait_for_event' | 'condition' | 'ab_test' | 'api_call' | 'ask_ai' | 'manual_task' | 'move_to_workflow' | 'add_tag' | 'remove_tag' | 'set_field' | 'change_sender' | 'run_column', required: What it was: a send-class task (a connection request, a message, an InMail, a profile visit, an endorsement, a withdrawal, a like, a comment or an email); the orchestration-class values of the vocabulary never appear here.
      - `workflow_records_counts` object, required: The journeys pinned to this sender profile (WorkflowRecordCounts over sender_profile_sid, full scope): total_count and groups.status, the enrollment funnel (active, waiting, paused_on_reply, waiting_limit, blocked, ...), the live load. See ./workflow_records.md.
        - `total_count` integer, required
        - `groups` object, required
          - `status` union, required
            - object
            - unknown[]
              - …
      - `workflow_tasks_counts` object, required: The tasks that name this sender profile (WorkflowTaskCounts over sender_profile_sid, full scope): total_count and groups.status (pending, scheduled, dispatched, done, failed, ...), the queue shape. See ./workflow_tasks.md.
        - `total_count` integer, required
        - `groups` object, required
          - `status` union, required
            - object
            - unknown[]
              - …
  - `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)
