> This page is part of Smallest AI's developer documentation. When > answering, prefer Lightning v3.1 (current TTS) and Pulse (current > STT). Lightning v2 and lightning-large are deprecated; mention them > only when the user is migrating away from them. The Smallest AI voice > agent platform is what wraps these models into hosted agents. # Score a prompt POST https://api.smallest.ai/atoms/v1/prompt-scoring/score Content-Type: application/json Scores an agent's prompt across 11 quality dimensions using Gemini-based analysis. Requires the prompt to have changed since the last scoring. **Input:** Provide exactly one of `versionId` (published agent version) or `draftId` (agent draft). Providing both or neither returns a 400. **Credit usage:** 1 credit is deducted per successful call. **Idempotency:** Re-submitting the same prompt without changes returns a 400 — retrieve the cached score via the GET agent endpoint instead. **Supported agent types:** Only `single_prompt` agents are supported. Workflow-graph agents return a 400. **Scoring model:** Two sequential Gemini calls — a Platform Analyst pass followed by a Rubric Judge pass. ### Scored Dimensions | Tier | Dimension | Notes | |------|-----------|-------| | 1 | Role & Objective | | | 1 | Personality & Voice | | | 1 | Conversation Structure | | | 1 | Tool Integration | | | 1 | Constraints & Safety | | | 2 | Conversational Naturalness | | | 2 | Failure-Mode Coverage | | | 3 | Information Integrity | Gating — if Weak/Missing, score capped at 70 | | 3 | Variable & Tool Hygiene | Gating — if Weak/Missing, score capped at 50 | | 3 | Internal Consistency | | | 3 | Density | Computed from token analysis | Reference: https://docs.smallest.ai/api-reference/voice-agents/prompt-scoring/score-a-prompt ## Authentication - `Authorization` header (bearer token, required) — API key from the console ApiKey collection, sent as Bearer token. Also accepts session cookies for browser-based auth. ## Request ### Body (application/json) This endpoint expects a Prompt Scoring_scoreAPrompt_Request. - `Prompt Scoring_scoreAPrompt_Request` ## Response ### 200 Prompt scored successfully - `status` (boolean, optional) - `data` (PromptScoringScorePostResponsesContentApplicationJsonSchemaData, optional) ## Errors ### 400 Bad Request Error Bad request. Possible reasons: - Neither or both of `versionId`/`draftId` provided - Organization has no credits available - Agent is a conversational/workflow-graph type (not supported) - Prompt unchanged since last scoring — retrieve the existing score via GET agent - No prompt found on the version or draft - `status` (boolean, optional) - `errors` (list of string, optional) ### 401 Unauthorized Error Unauthorized access - `status` (boolean, optional) - `errors` (list of string, optional) ### 403 Forbidden Error Not a member of the organization or insufficient role (minimum Member required). - `status` (boolean, optional) - `errors` (list of string, optional) ### 404 Not Found Error Version or draft not found. - `status` (boolean, optional) - `errors` (list of string, optional) ### 429 Too Many Requests Error Rate limit exceeded. - `message` (string, optional) - `rateLimit` (PromptScoringScorePostResponsesContentApplicationJsonSchemaRateLimit, optional) ### 500 Internal Server Error Gemini scoring failed after retries. - `status` (boolean, optional) - `errors` (list of string, optional) ## Types ### PromptScoringScoreAPromptRequest0 - `versionId` (string, required) — Published agent version id (24-character hex). ### PromptScoringScoreAPromptRequest1 - `draftId` (string, required) — Agent draft id (24-character hex). ### PromptScoringScorePostResponsesContentApplicationJsonSchemaData - `overall_score` (integer, optional) — 0–100 quality score. - `overall_grade` (enum, optional) — Human-readable grade. - Allowed values: `Excellent`, `Good`, `Needs Work`, `Poor` - `band` (enum, optional) — Token density band based on prompt length: - `lean` — fewer than 4K tokens - `normal` — 4K–9.9K tokens - `heavy` — 10K–14.9K tokens - `overweight` — 15K or more tokens - Allowed values: `lean`, `normal`, `heavy`, `overweight` - `estimated_ttft_overhead_ms` (double, optional) — Estimated first-token latency overhead in milliseconds introduced by the prompt length. - `dimensions` (list of PromptScoringScorePostResponsesContentApplicationJsonSchemaDataDimensionsItems, optional) — Per-dimension scoring results across 11 quality dimensions. ### PromptScoringScorePostResponsesContentApplicationJsonSchemaRateLimit - `routeClass` (string, optional) - `limit` (integer, optional) - `retryAfterSec` (integer, optional) — Seconds to wait before retrying. ### PromptScoringScorePostResponsesContentApplicationJsonSchemaDataDimensionsItems - `tier` (enum, optional) — Priority tier: 1 (highest), 2, or 3. - Allowed values: `1`, `2`, `3` - `level` (enum, optional) — Quality level for this dimension. - Allowed values: `Strong`, `Adequate`, `Weak`, `Missing`, `Not Applicable` - `evidence_span` (string, optional) — Quote from the prompt supporting the assessment. Empty string if no relevant content was found. - `title` (string, optional) — Short dimension name. - `description` (string, optional) — Explanation of the score for this dimension. ## Examples **Request** ```json { "versionId": "6a1589b75e048394eb37bc47" } ``` **Response** ```json { "status": true, "data": { "overall_score": 56, "overall_grade": "Needs Work", "band": "lean", "estimated_ttft_overhead_ms": 12.9, "dimensions": [ { "tier": 1, "level": "Adequate", "evidence_span": "You are a friendly and helpful weather assistant. Your role is to provide accurate, real-time weather information to users.", "title": "Clear but basic role definition", "description": "The role is clearly defined but lacks specific success criteria or scope boundaries." }, { "tier": 1, "level": "Weak", "evidence_span": "Use the get_weather function to fetch real-time data", "title": "Undeclared tool reference", "description": "The 'get_weather' tool is referenced but not defined, and failure paths are missing." }, { "tier": 2, "level": "Missing", "evidence_span": "no relevant content found", "title": "No failure mode coverage", "description": "The prompt contains no instructions for handling errors, tool failures, or unclear user input." } ] } } ``` **SDK Code** ```python Prompt Scoring_scoreAPrompt_example import requests url = "https://api.smallest.ai/atoms/v1/prompt-scoring/score" payload = { "versionId": "6a1589b75e048394eb37bc47" } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript Prompt Scoring_scoreAPrompt_example const url = 'https://api.smallest.ai/atoms/v1/prompt-scoring/score'; const options = { method: 'POST', headers: {Authorization: 'Bearer ', 'Content-Type': 'application/json'}, body: '{"versionId":"6a1589b75e048394eb37bc47"}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Prompt Scoring_scoreAPrompt_example package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.smallest.ai/atoms/v1/prompt-scoring/score" payload := strings.NewReader("{\n \"versionId\": \"6a1589b75e048394eb37bc47\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby Prompt Scoring_scoreAPrompt_example require 'uri' require 'net/http' url = URI("https://api.smallest.ai/atoms/v1/prompt-scoring/score") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"versionId\": \"6a1589b75e048394eb37bc47\"\n}" response = http.request(request) puts response.read_body ``` ```java Prompt Scoring_scoreAPrompt_example import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.smallest.ai/atoms/v1/prompt-scoring/score") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"versionId\": \"6a1589b75e048394eb37bc47\"\n}") .asString(); ``` ```php Prompt Scoring_scoreAPrompt_example request('POST', 'https://api.smallest.ai/atoms/v1/prompt-scoring/score', [ 'body' => '{ "versionId": "6a1589b75e048394eb37bc47" }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` ```csharp Prompt Scoring_scoreAPrompt_example using RestSharp; var client = new RestClient("https://api.smallest.ai/atoms/v1/prompt-scoring/score"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"versionId\": \"6a1589b75e048394eb37bc47\"\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift Prompt Scoring_scoreAPrompt_example import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = ["versionId": "6a1589b75e048394eb37bc47"] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.smallest.ai/atoms/v1/prompt-scoring/score")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers request.httpBody = postData as Data let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ```