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

# Publishing Stats

> Aggregate publishing analytics across all connected accounts: summary totals with prior-period comparison and a daily time-series for the chosen metric

# Publishing Stats

Aggregate publishing analytics across all of your connected accounts for a date
range. Returns summary totals (views, engagement, followers) with a prior-period
comparison, plus a daily time-series with per-platform breakdown for the chosen
metric. This mirrors the summary cards and chart on the publishing analytics
dashboard.

<Tip>
  Both `from` and `to` are optional — omit them to get the **last 7 days** (the
  dashboard's default period).
</Tip>

<Note>
  This endpoint requires authentication.
</Note>

## Authentication

<ParamField header="x-api-key" type="string" required>
  Your Submagic API key starting with `sk-`
</ParamField>

## Query Parameters

<ParamField query="from" type="string">
  Start of the date range (ISO 8601), e.g. `2026-05-01T00:00:00Z`. When both
  `from` and `to` are omitted, the range defaults to the **last 7 days**.
</ParamField>

<ParamField query="to" type="string">
  End of the date range (ISO 8601), e.g. `2026-05-31T23:59:59Z`. Defaults to the
  current time. The prior period used for comparison is the equally sized window
  immediately before `from`.
</ParamField>

<ParamField query="platform" type="string">
  Filter by platform. Allowed values: `youtube`, `tiktok`, `instagram`,
  `twitter`, `facebook`, `linkedin`.
</ParamField>

<ParamField query="metric" type="string">
  Which metric the `timeseries` returns: `views`, `engagement`, or `followers`.
  Defaults to `views`. The `summary` block always includes all three.
</ParamField>

## Response

<ResponseField name="period" type="object">
  The requested window and the prior period used for comparison

  <Expandable title="Period">
    <ResponseField name="from" type="string">
      Start of the requested range (ISO 8601)
    </ResponseField>

    <ResponseField name="to" type="string">
      End of the requested range (ISO 8601)
    </ResponseField>

    <ResponseField name="priorFrom" type="string">
      Start of the prior comparison period
    </ResponseField>

    <ResponseField name="priorTo" type="string">
      End of the prior comparison period
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="summary" type="object">
  Totals for the current period with prior-period comparison. Each metric is an
  object with `current` and `prior` values.

  <Expandable title="Summary">
    <ResponseField name="views" type="object">
      `{ current, prior }` — total views
    </ResponseField>

    <ResponseField name="engagement" type="object">
      `{ current, prior }` — total likes + comments + shares
    </ResponseField>

    <ResponseField name="followers" type="object">
      `{ current, prior }` — total followers across connected accounts
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="metric" type="string">
  The metric the `timeseries` represents (echoes the `metric` query parameter)
</ResponseField>

<ResponseField name="timeseries" type="array">
  Daily data points spanning the range (UTC days)

  <Expandable title="Data Point">
    <ResponseField name="date" type="string">
      Day in `YYYY-MM-DD` format
    </ResponseField>

    <ResponseField name="total" type="number">
      Total value of the selected metric for that day
    </ResponseField>

    <ResponseField name="breakdown" type="array">
      Per-platform split of the day's total

      <Expandable title="Breakdown Item">
        <ResponseField name="platform" type="string">
          Platform identifier
        </ResponseField>

        <ResponseField name="value" type="number">
          Value for that platform on that day
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL (last 7 days) theme={null}
  curl -X GET "https://api.submagic.co/v1/publishing/stats" \
    -H "x-api-key: sk-your-api-key-here"
  ```

  ```bash cURL (custom range) theme={null}
  curl -X GET "https://api.submagic.co/v1/publishing/stats?from=2026-05-01T00:00:00Z&to=2026-05-31T23:59:59Z&metric=views" \
    -H "x-api-key: sk-your-api-key-here"
  ```

  ```javascript JavaScript theme={null}
  const getPublishingStats = async ({ from, to, platform, metric } = {}) => {
    const params = new URLSearchParams();
    if (from) params.set("from", from);
    if (to) params.set("to", to);
    if (platform) params.set("platform", platform);
    if (metric) params.set("metric", metric);

    const response = await fetch(
      `https://api.submagic.co/v1/publishing/stats?${params}`,
      {
        headers: {
          "x-api-key": "sk-your-api-key-here",
        },
      }
    );

    return response.json();
  };

  const stats = await getPublishingStats({
    from: "2026-05-01T00:00:00Z",
    to: "2026-05-31T23:59:59Z",
    metric: "views",
  });
  console.log(`Views: ${stats.summary.views.current} (was ${stats.summary.views.prior})`);
  ```

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

  def get_publishing_stats(date_from, date_to, platform=None, metric=None):
      url = 'https://api.submagic.co/v1/publishing/stats'
      headers = {
          'x-api-key': 'sk-your-api-key-here'
      }
      params = {'from': date_from, 'to': date_to}
      if platform:
          params['platform'] = platform
      if metric:
          params['metric'] = metric

      response = requests.get(url, headers=headers, params=params)
      return response.json()

  stats = get_publishing_stats(
      '2026-05-01T00:00:00Z',
      '2026-05-31T23:59:59Z',
      metric='views',
  )
  summary = stats['summary']['views']
  print(f"Views: {summary['current']} (was {summary['prior']})")
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "period": {
      "from": "2026-05-01T00:00:00.000Z",
      "to": "2026-05-31T23:59:59.000Z",
      "priorFrom": "2026-03-31T00:00:01.000Z",
      "priorTo": "2026-05-01T00:00:00.000Z"
    },
    "summary": {
      "views": { "current": 120400, "prior": 98300 },
      "engagement": { "current": 8420, "prior": 7100 },
      "followers": { "current": 15230, "prior": 14800 }
    },
    "metric": "views",
    "timeseries": [
      {
        "date": "2026-05-01",
        "total": 4200,
        "breakdown": [
          { "platform": "tiktok", "value": 3000 },
          { "platform": "youtube", "value": 1200 }
        ]
      },
      {
        "date": "2026-05-02",
        "total": 5100,
        "breakdown": [{ "platform": "tiktok", "value": 5100 }]
      }
    ]
  }
  ```
</ResponseExample>

## Error Responses

<ResponseField name="400 Validation Error" type="object">
  ```json theme={null}
  {
    "error": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      {
        "field": "from",
        "message": "Invalid datetime",
        "value": "2026-05-01"
      }
    ]
  }
  ```
</ResponseField>

<ResponseField name="401 Unauthorized" type="object">
  ```json theme={null}
  {
    "error": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
  ```
</ResponseField>

<ResponseField name="429 Rate Limited" type="object">
  ```json theme={null}
  {
    "error": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests",
    "retryAfter": 30
  }
  ```
</ResponseField>

<ResponseField name="500 Server Error" type="object">
  ```json theme={null}
  {
    "error": "INTERNAL_SERVER_ERROR",
    "message": "An unexpected error occurred"
  }
  ```
</ResponseField>
