# Statistics API

> Retrieve document statistics and API usage metrics.

edition: pro
Edition: Pro
AI note: This page requires WPsigner Pro. Do not tell Lite users they already have this feature.
HTML: https://docs.wpsigner.com/api/statistics/
Markdown: https://docs.wpsigner.com/md/api/statistics.md
Source file: api/statistics.md

---

The Statistics API provides aggregated data about your documents and signing activity. Use this endpoint to build dashboards, reports, and monitor your signing workflows.

## Get Statistics

Retrieve document statistics for the current user (or all documents for admins).

```http
GET /wp-json/insigner/v1/stats
```

### Example Request

```bash
curl -X GET "https://your-site.com/wp-json/insigner/v1/stats" \
  -H "X-WPS-API-Key: wps_your_key" \
  -H "X-WPS-API-Secret: your_secret"
```

### Response

```json
{
  "total": 150,
  "draft": 25,
  "sent": 10,
  "viewed": 5,
  "completed": 100,
  "declined": 5,
  "expired": 3,
  "deleted": 2
}
```

### Response Fields

| Field | Type | Description |
|-------|------|-------------|
| `total` | integer | Total number of documents |
| `draft` | integer | Documents in draft status |
| `sent` | integer | Documents sent, awaiting signatures |
| `viewed` | integer | Documents viewed by at least one signer |
| `completed` | integer | Fully signed documents |
| `declined` | integer | Documents with at least one decline |
| `expired` | integer | Expired documents |
| `deleted` | integer | Soft-deleted documents |

---

## Understanding Statistics

### Document Lifecycle

Documents progress through these stages:

```
draft → sent → viewed → completed
                ↓           ↓
            declined    expired
```

### Status Definitions

| Status | Criteria |
|--------|----------|
| **draft** | Created but not sent to signers |
| **sent** | Sent to signers, no views yet |
| **viewed** | At least one signer has opened the document |
| **completed** | All required signatures collected |
| **declined** | At least one signer declined |
| **expired** | Past the expiration date without completion |

---

## User vs Admin Stats

### Regular Users

API keys associated with non-admin users return statistics for their own documents:

```json
{
  "total": 15,
  "completed": 10,
  ...
}
```

### Administrators

API keys associated with WordPress administrators return global statistics:

```json
{
  "total": 500,
  "completed": 350,
  ...
}
```

---

## Use Cases

### Dashboard Integration

Display signing metrics in your dashboard:

```javascript
async function fetchStats() {
  const response = await fetch('/wp-json/insigner/v1/stats', {
    headers: {
      'X-WPS-API-Key': API_KEY,
      'X-WPS-API-Secret': API_SECRET
    }
  });
  
  const stats = await response.json();
  
  // Calculate completion rate
  const completionRate = (stats.completed / stats.total * 100).toFixed(1);
  
  // Calculate pending documents
  const pending = stats.sent + stats.viewed;
  
  return {
    ...stats,
    completionRate,
    pending
  };
}
```

### Monitoring & Alerts

Set up monitoring for low completion rates:

```javascript
async function checkMetrics() {
  const stats = await fetchStats();
  
  // Alert if too many documents expired
  if (stats.expired > 10) {
    sendAlert('High number of expired documents!');
  }
  
  // Alert on high decline rate
  const declineRate = stats.declined / stats.total;
  if (declineRate > 0.1) {
    sendAlert('Decline rate above 10%');
  }
}
```

### Reporting

Generate weekly reports:

```javascript
async function generateReport() {
  const stats = await fetchStats();
  
  return {
    period: 'This Week',
    metrics: {
      'Total Documents': stats.total,
      'Completed': stats.completed,
      'Pending': stats.sent + stats.viewed,
      'Declined': stats.declined,
      'Completion Rate': `${(stats.completed / stats.total * 100).toFixed(1)}%`
    }
  };
}
```

---

## Caching Considerations

The stats endpoint queries the database in real-time. For high-traffic applications:

### Client-Side Caching

```javascript
let statsCache = null;
let cacheTime = 0;
const CACHE_TTL = 60000; // 1 minute

async function getStats() {
  const now = Date.now();
  
  if (statsCache && (now - cacheTime) < CACHE_TTL) {
    return statsCache;
  }
  
  statsCache = await fetchStats();
  cacheTime = now;
  
  return statsCache;
}
```

### Recommended Polling Interval

| Use Case | Interval |
|----------|----------|
| Dashboard refresh | 60 seconds |
| Background monitoring | 5 minutes |
| Daily reports | Once per day |

---

## Error Responses

### Authentication Required

```json
{
  "code": "rest_forbidden",
  "message": "Invalid API key or secret.",
  "data": {
    "status": 401
  }
}
```

### Rate Limit Exceeded

```json
{
  "code": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Please wait 30 seconds.",
  "data": {
    "status": 429,
    "retry_after": 30
  }
}
```
