Read the receipt of one request — its model, tokens and cost in DA — and send feedback on an answer.
Every model answer carries an X-Generation-Id header, and the same handle in its body's id. Pass it to /v1/generation to read what the request cost. All three routes are free.
The Go client has no generations resource, so call the endpoints directly with net/http.
req, _ := http.NewRequest("GET",
"https://opendunes.com/v1/generation?id="+url.QueryEscape(generationID), nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPENDUNES_API_KEY"))
resp, err := http.DefaultClient.Do(req)
// resp body: { "data": { "id", "model", "tokens_prompt", "tokens_completion", "total_cost", "latency", … } }
// total_cost is in DAgenerationID is the id of the answer, or its X-Generation-Id header. You read only your own account's receipts; any other id is a 404.
A request that made a file — a picture, a voice, a clip — names it at /v1/generation/content:
req, _ := http.NewRequest("GET",
"https://opendunes.com/v1/generation/content?id="+url.QueryEscape(generationID), nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPENDUNES_API_KEY"))
resp, err := http.DefaultClient.Do(req)
// 200 → { "data": { "output": { "files": ["…"] } } } — ids for GET /v1/files/{id}/content
// 404 → the request kept nothing (a text answer makes no file)Feedback takes a management key:
body, _ := json.Marshal(map[string]any{
"generation_id": generationID,
"category": "incorrect_response",
"comment": "The model repeated the same paragraph three times.",
})
req, _ := http.NewRequest("POST", "https://opendunes.com/v1/generation/feedback", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("OPENDUNES_MANAGEMENT_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
// → { "data": { "success": true } }category is one of latency, incoherence, incorrect_response, formatting, billing, api_error, other.