Evaluate
Submit work for INVEST scoring. Choose a synchronous call that returns the score inline, or an asynchronous submit that delivers the score to a webhook. A separate CSV flow powers the public evaluator.
Choosing a method
| Method | Endpoint | Returns | Use when |
|---|---|---|---|
| Synchronous | POST /v1/score | 200 with the score inline | You can hold the connection open — scripts, CI gates, request/response tooling. |
| Asynchronous | POST /api/v1/evaluate/{source} | 202 + webhook callback | Event-driven integrations like the Jira Forge app, or high-volume back-pressure-friendly scoring. |
Synchronous scoring
/v1/scoreSubmit a single ticket and receive the completed INVEST score in the same response. Authenticate with the bearer token issued to your account when your integration is provisioned. This is the call the CSV evaluator makes per row.
Authorization: Bearer <your_api_key>
Content-Type: application/json{
"ticket_id": "PROJ-101",
"customer_id": "acme_jira_8f2c",
"ticket_data": {
"key": "PROJ-101",
"summary": "As a site admin I want to export user activity",
"description": "Full description of the story...",
"acceptance_criteria": "Given a signed-in admin, when..."
},
"context_items": [],
"system_type": "adam"
}{
"job_id": "b1f9...",
"overall_score": 5.2,
"individual_scores": {
"independent": 6,
"negotiable": 5,
"valuable": 7,
"estimable": 4,
"small": 5,
"testable": 4
},
"recommendations": [
"Add acceptance criteria that describe the observable outcome.",
"Split the export into per-entity stories to reduce scope."
]
}- • system_type selects the scoring profile. Use
“adam”for the default INVEST rubric. Custom profiles can be provisioned on request. - •
individual_scorescarries the six INVEST dimensions, each scored 0–10.overall_scoreis the aggregate out of 10. - • Only
summaryis strictly required insideticket_data; the other fields improve scoring accuracy when present.
Asynchronous scoring
/api/v1/evaluate/{source}Fire-and-forget evaluation for event-driven integrations. {source} is your integration channel — e.g. jiraforge. The request authenticates with the per-installation shared secret in the X-Vindex-Secret header. Vindex acknowledges immediately and POSTs the completed score to your registered callback URL.
X-Vindex-Secret: <per-install shared secret>
Content-Type: application/json{
"cloudId": "<Jira Cloud ID>",
"issue": {
"key": "PROJ-101",
"fields": {
"summary": "As a user, I want to...",
"description": { "...": "ADF or plain text" },
"issuetype": { "name": "Story" }
}
}
}{
"status": "queued",
"requestId": "req_abc123"
}The completed score is delivered to your webhook as a structured payload — see the callbacks reference for the shape, signature verification, and retry behaviour.
| Status | Meaning |
|---|---|
| 202 | Accepted and queued for scoring. |
| 401 | Unknown installation — triggers re-registration. |
| 403 | Shared secret mismatch. |
| 429 | Rate limited — retry after the window. |
| 503 | Scoring engine temporarily unavailable. |
Rate limits
| Endpoint | Limit | Window |
|---|---|---|
| POST /v1/score | 60 requests | 1 minute |
| POST /api/v1/evaluate/{source} | 60 requests | 1 minute |
| POST /evaluate/upload | 10 requests | 1 hour (per IP) |
| POST /evaluate/score | 5 requests | 1 hour (per IP) |
| GET /evaluate/results/{session_id} | 60 requests | 1 minute |
Responses that exceed the limit return 429 Too Many Requests with a Retry-After header.
