Stats

The stats endpoints back the scores dashboard in the Vindex portal. Use them to pull averages, trends, and individual score records into your own dashboards and data warehouse.

Overall average

GET/portal/scores/summary

All-time average overall_score across every ticket scored for your company, along with the total number of scored tickets that contributed.

200 OK
response
{
  "overall_average": 6.4,
  "total_scored": 312
}

Returns overall_average: null and total_scored: 0 when no tickets have been scored yet.

Average over time

GET/portal/scores/chart

Time-series data grouped by day (for ranges up to 90 days) or week (beyond 90 days). Ask for any combination of the seven dimensions: overall, independent, negotiable, valuable, estimable, small, testable.

query
GET /portal/scores/chart
  ?from=2026-01-01
  &to=2026-04-01
  &dimensions=overall,testable
200 OK
response
{
  "dimensions": ["overall", "testable"],
  "data_points": [
    { "date": "2026-01-01", "overall": 6.2, "testable": 5.1, "count": 14 },
    { "date": "2026-01-02", "overall": 6.4, "testable": 5.6, "count": 22 }
  ]
}
  • from and to are ISO 8601 dates. Default range: last 30 days. Maximum: 365 days.
  • • Unknown dimension values return 422.
  • count is the number of tickets contributing to that bucket.

List scored tickets

GET/portal/scores

Paginated list of score records, most recent first. Useful for building your own worklist or feeding a BI pipeline.

query
GET /portal/scores?skip=0&limit=25
200 OK
response
{
  "items": [
    {
      "_id": "661e2...",
      "customer_id": "acme_jira_8f2c",
      "ticket": {
        "id": "PROJ-101",
        "key": "PROJ-101",
        "title": "As a site admin I want..."
      },
      "invest_scores": {
        "independent": 6, "negotiable": 5, "valuable": 7,
        "estimable": 4, "small": 5, "testable": 4
      },
      "overall_score": 5.2,
      "created_at": "2026-04-16T09:12:08Z"
    }
  ],
  "total": 312,
  "skip": 0,
  "limit": 25
}

The list response omits context_used, model_metadata, processing_metadata, and webhook. Fetch a single score to see the full record.

Fetch a single score

GET/portal/scores/{id}

Full score document including per-dimension context, recommendations, the model used, and the webhook delivery status. model_metadata.temperature is always omitted from the response.

200 OK
response
{
  "_id": "661e2...",
  "job_id": "b1f9...",
  "customer_id": "acme_jira_8f2c",
  "ticket": { "id": "PROJ-101", "key": "PROJ-101", "title": "...", "snapshot_at": "..." },
  "invest_scores": { "independent": 6, "negotiable": 5, "valuable": 7, "estimable": 4, "small": 5, "testable": 4 },
  "overall_score": 5.2,
  "top_recommendations": [ "Add acceptance criteria...", "Split the export..." ],
  "context_used": { "testable": [ "No acceptance criteria section present" ] },
  "model_metadata": { "provider": "openai", "model_name": "gpt-4o" },
  "processing_metadata": { "started_at": "...", "completed_at": "...", "duration_ms": 4821.4 },
  "webhook": { "url": "https://...", "status": "delivered", "status_code": 200, "retry_count": 0, "response_time_ms": 312.5, "error": null },
  "created_at": "2026-04-16T09:12:08Z"
}

If the score doesn't exist or belongs to a different company, 404 Not Found is returned. Vindex never reveals records across company boundaries.

Admin endpoints

Vindex Admins have the same endpoints under /admin/scores/* with global visibility and an optional customer_id filter. Per-company averages are also exposed at /admin/companies/{company_id}/score.

Continue reading