Feedback API
Write investigation outcomes back to Naiza so fraud rules and review queues learn from confirmed ALLOW, REVIEW, and BLOCK cases.
Feedback API
The Feedback API allows you to provide feedback on decisions and events to improve fraud detection accuracy.
Auth
x-api-key is required.
Endpoints
POST /api/v1/feedback/decision/:idPOST /api/v1/feedback/event/:id
Label Decision
Provide feedback on a decision outcome.
Endpoint
POST
/api/v1/feedback/decision/:idPOST /api/v1/feedback/decision/:id
Headers
| Header | Description |
|---|---|
| Idempotency-Key | Optional. Unique key to prevent duplicate submissions |
Request
{
"label": "FRAUD",
"notes": "Customer confirmed this was fraudulent activity",
"externalCaseId": "case_12345"
}Response
{
"id": "feedback_abc123",
"type": "DECISION",
"targetId": "evt_ckm9876543210",
"label": "FRAUD",
"notes": "Customer confirmed this was fraudulent activity",
"externalCaseId": "case_12345",
"createdAt": "2025-01-15T10:00:00Z",
"updatedAt": "2025-01-15T10:00:00Z"
}Label Event
Provide feedback on an event outcome.
Endpoint
POST
/api/v1/feedback/event/:idPOST /api/v1/feedback/event/:id
Request
Same format as decision feedback.
Feedback Labels
| Label | Description |
|---|---|
| FRAUD | Confirmed fraudulent activity |
| LEGIT | Confirmed legitimate activity |
| CHARGEBACK | Chargeback occurred |
| REFUND | Refund was issued |
| FALSE_POSITIVE | Decision was incorrect (blocked legitimate transaction) |
| TRUE_POSITIVE | Decision was correct (blocked fraudulent transaction) |
Idempotency
Feedback endpoints support idempotency to prevent duplicate submissions. Include Idempotency-Key:
POST /api/v1/feedback/decision/evt_123
Idempotency-Key: unique-key-here
Content-Type: application/json
{
"label": "FRAUD",
"notes": "Customer confirmed fraud"
}Expected behavior
- First request: processed normally and the response is stored for replay
- Duplicate key (same tenant + same endpoint path): returns the stored response body
- Keys expire after 24 hours
- Reuse the same key for safe retries of the same logical action
Example with Idempotency
const idempotencyKey = `feedback-${decisionId}-${Date.now()}`;
const response = await fetch(
`https://api.naiza.ai/api/v1/feedback/decision/${decisionId}`,
{
method: 'POST',
headers: {
'x-api-key': 'naiza_api_sk_live_...',
'Idempotency-Key': idempotencyKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({
label: 'FRAUD',
notes: 'Customer confirmed fraud',
}),
}
);
// Safe to retry with same idempotency key
// Will return cached response if already processedExamples
# Label decision as fraud
curl -X POST https://api.naiza.ai/api/v1/feedback/decision/evt_123 \
-H "x-api-key: naiza_api_sk_live_..." \
-H "Idempotency-Key: feedback-evt_123-1234567890" \
-H "Content-Type: application/json" \
-d '{
"label": "FRAUD",
"notes": "Customer confirmed this was fraudulent",
"externalCaseId": "case_12345"
}'Best Practices
1. Use Idempotency Keys
Always use idempotency keys when submitting feedback to prevent duplicates:
const idempotencyKey = `${decisionId}-${label}-${timestamp}`;2. Include External Case IDs
Link feedback to your internal case management system:
{
"label": "FRAUD",
"externalCaseId": "case_12345",
"notes": "Linked to support ticket #12345"
}3. Provide Detailed Notes
Include context in notes for better model training:
{
"label": "FALSE_POSITIVE",
"notes": "Customer verified identity via phone call. Original decision was incorrect."
}4. Handle Retries
Implement retry logic with the same idempotency key:
async function submitFeedbackWithRetry(decisionId, label, notes, maxRetries = 3) {
const idempotencyKey = `feedback-${decisionId}-${label}`;
for (let i = 0; i < maxRetries; i++) {
try {
return await submitFeedback(decisionId, label, notes, idempotencyKey);
} catch (error) {
if (i === maxRetries - 1) throw error;
await sleep(Math.pow(2, i) * 1000); // Exponential backoff
}
}
}Troubleshooting
404: target decision/event ID not found in your tenant scope401: missing/invalid API key422/400: body validation failed (invalidlabel, oversizednotes, etc.)