All documentation

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/:id
  • POST /api/v1/feedback/event/:id

Label Decision

Provide feedback on a decision outcome.

Endpoint

POST/api/v1/feedback/decision/:id
POST /api/v1/feedback/decision/:id

Headers

HeaderDescription
Idempotency-KeyOptional. 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/:id
POST /api/v1/feedback/event/:id

Request

Same format as decision feedback.

Feedback Labels

LabelDescription
FRAUDConfirmed fraudulent activity
LEGITConfirmed legitimate activity
CHARGEBACKChargeback occurred
REFUNDRefund was issued
FALSE_POSITIVEDecision was incorrect (blocked legitimate transaction)
TRUE_POSITIVEDecision 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 processed

Examples

# 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 scope
  • 401: missing/invalid API key
  • 422/400: body validation failed (invalid label, oversized notes, etc.)