All documentation

Feedback API

Investigation outcomes and feedback writes.

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.)