Repair API

Send messy data. Get production-ready data back. In a single call, Repair inspects your records, infers a schema, reconciles equivalent field names, normalizes and safely repairs values, detects and (at high confidence) merges duplicates, flags anomalies, and returns clean records with a complete audit trail of everything it changed.

Repair is a convenience layer over Zapinners deterministic engines (normalize, dedupe, anomalies). You dont need to understand the internal pipeline send one request, get clean records plus evidence of every change. It is billed once per input record, never separately for the internal steps.

Endpoint & cost

POST /api/v1/repair

Metering is based on input records: a request with 10 records draws down 10 records from your monthly allowance, no matter how many internal operations run. The synchronous maximum is 500 records per request. Requests that fail validation are never charged.

What one call does

Every request runs this deterministic pipeline (each stage is toggleable):

  • Inspect the incoming records and detect their likely structure.
  • Detect equivalent field names and map them to canonical fields.
  • Infer a typed schema (email, phone, currency, date, and more).
  • Normalize and safely repair values (trim, lowercase, parse numbers/dates).
  • Validate values and separate unfixable issues from automatic repairs.
  • Detect duplicates and merge only the high-confidence ones.
  • Detect anomalies and flag records that need a human.
  • Return repaired data plus a detailed, per-change audit trail.

Request fields

FieldTypeDescription
records*object[]Messy records to repair (1-500). Field names, casing, and value formats may vary across records. Values must be primitives (no nested objects/arrays).
options.normalizebooleanNormalize and safely repair values. Default true.
options.dedupebooleanDetect duplicate records. Default true.
options.merge_duplicatesbooleanMerge high-confidence duplicates. Low-confidence matches are never merged. Default true.
options.detect_anomaliesbooleanFlag unusual or inconsistent records. Default true.
options.infer_schemabooleanInfer a typed schema for the canonical fields. Default true.
options.strictbooleanOnly apply high-confidence fixes; send ambiguous cases to review_required. Default false.
options.dry_runbooleanReturn proposed changes without modifying the returned dataset. Default false.

Response

FieldTypeDescription
dataobject[]The repaired records. In dry-run mode this is the original dataset, unchanged.
schemaobjectInferred type, nullability, and confidence for each canonical field.
field_mappingsobject[]Which input field names were reconciled into each canonical field, with confidence.
changesobject[]The audit trail: every value change with from, to, action, a specific reason, and confidence.
duplicatesobject[]Duplicate groups with action merge (applied) or review (left for a human).
anomaliesobject[]Unusual records, flagged (never deleted) with evidence.
review_requiredobject[]Everything that needs a human: validation failures, low-confidence duplicates, ambiguous fields.
summaryobjectCounts: records_received/returned, issues_found/fixed, duplicates_found/merged, anomalies_found, review_required.

Dry run

Set options.dry_run: true to preview a repair without changing the returned dataset. The data array comes back exactly as you sent it, while changes, duplicates, anomalies, and schema describe everything Repair would do. Ideal for building trust and diffing before you commit.

Strict mode

Set options.strict: true to only apply high-confidence fixes. Fields whose type cant be inferred confidently are left untouched and surfaced in review_required instead of being coerced, and duplicate merging requires a higher confidence threshold. Use strict mode when correctness matters more than automation.

Usage & metering

Repair draws down the same account-wide monthly record allowance as every other capability, at 1 unit per input record. Internal normalize, dedupe, and anomaly work is not billed separately you pay once for the repair. Usage is shared across all API keys on your account. See Rate limits.

Errors & limits

Repair uses the same structured error format as the rest of the platform (error.code, error.message, request_id). Common cases:

  • 400 invalid_request empty records, a non-object record, or a nested/non-primitive value.
  • 413 payload_too_large the body exceeds the size cap or more than 500 records.
  • 401 unauthorized / invalid_api_key missing or invalid key.
  • 429 usage_limit_exceeded the request would exceed your monthly record allowance.
  • 429 rate_limit_exceeded too many requests in the burst window.

Internal server errors return a sanitized 500 internal_error and never leak record contents or stack traces. See Errors.

Try it live

Pick a scenario (repair, dry run, or strict) or edit the JSON, then send it against the live engine. No API key required.

Try it livePOST /api/v1/repair
Request bodyeditable
Response

// Send the request to see the live response.

Live demo endpoint · no API key needed · rate-limited · not stored · runs the production engine

Example request

Request
POST /api/v1/repair
Authorization: Bearer zap_live_...
Content-Type: application/json

{
  "records": [
    { "Company Name": "ACME, INC.", "Email": " JOHN@ACME.COM ", "Revenue": "$1.2M", "signup": "3/7/26" },
    { "company": "Acme Inc", "email_address": "john@acme.com", "revenue": "1200000", "created": "2026-03-07" }
  ],
  "options": {
    "normalize": true,
    "dedupe": true,
    "merge_duplicates": true,
    "detect_anomalies": true,
    "infer_schema": true,
    "strict": false,
    "dry_run": false
  }
}

Example response

200 OK
{
  "request_id": "req_xxx",
  "success": true,
  "data": [
    { "company": "ACME, INC.", "email": "john@acme.com", "revenue": 1200000, "signup_date": "2026-03-07" }
  ],
  "schema": {
    "company": { "type": "company", "nullable": false, "confidence": 0.9 },
    "email": { "type": "email", "nullable": false, "confidence": 1 },
    "revenue": { "type": "currency", "nullable": false, "confidence": 1 },
    "signup_date": { "type": "date", "nullable": false, "confidence": 1, "format": "YYYY-MM-DD" }
  },
  "field_mappings": [
    { "inputs": ["Company Name", "company"], "canonical": "company", "confidence": 0.95, "concept": "company" },
    { "inputs": ["Email", "email_address"], "canonical": "email", "confidence": 0.98, "concept": "email" }
  ],
  "changes": [
    { "record": 0, "field": "email", "from": " JOHN@ACME.COM ", "to": "john@acme.com", "action": "normalized", "reason": "email trimmed and lowercased", "confidence": 0.99 },
    { "record": 0, "field": "revenue", "from": "$1.2M", "to": 1200000, "action": "normalized", "reason": "currency value parsed to a numeric amount", "confidence": 0.97 }
  ],
  "duplicates": [
    { "source_records": [0, 1], "result_record": 0, "confidence": 0.97, "reason": "company matches; email matches", "action": "merge" }
  ],
  "anomalies": [],
  "review_required": [],
  "summary": {
    "records_received": 2,
    "records_returned": 1,
    "issues_found": 6,
    "issues_fixed": 6,
    "duplicates_found": 1,
    "duplicates_merged": 1,
    "anomalies_found": 0,
    "review_required": 0,
    "dry_run": false,
    "strict": false
  },
  "usage": { "records_processed": 2, "credits_used": 2, "credits_remaining": 998 }
}

Code examples

curl -X POST https://zapinner.com/api/v1/repair \
  -H "Authorization: Bearer $ZAPINNER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "records": [
      { "Company Name": "ACME, INC.", "Email": " JOHN@ACME.COM ", "Revenue": "$1.2M" },
      { "company": "Acme Inc", "email_address": "john@acme.com", "revenue": "1200000" }
    ]
  }'
  • Normalize the value-standardization engine Repair reuses.
  • Dedupe the duplicate-detection engine Repair reuses.
  • Anomalies the anomaly-detection engine Repair reuses.
  • Analyze run individual operations when you want fine-grained control.