{
  "openapi": "3.0.3",
  "info": {
    "title": "Ava Data API",
    "version": "1.1.0",
    "description": "Integrate Ava Data's skip tracing directly into your CRM, AI agents, or custom software. Access comprehensive contact data including phone numbers, email addresses, and related persons through single searches or high-volume bulk CSV processing.\n\nCredits are only charged when a match is found, and bulk uploads charge per data type per match.",
    "contact": {
      "name": "Ava Data Support",
      "email": "Support@avadata.ai"
    }
  },
  "servers": [
    {
      "url": "https://app.avadata.ai/api/v1",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Search",
      "description": "Single-record skip trace searches."
    },
    {
      "name": "Bulk",
      "description": "High-volume CSV processing with async jobs."
    },
    {
      "name": "Digital Matching",
      "description": "Turn a contact CSV into ready-to-upload Custom Audience files for major ad platforms. Securely hashed identifiers, formatted per platform."
    },
    {
      "name": "Account",
      "description": "Credit balance and API usage."
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/deep-search": {
      "post": {
        "tags": [
          "Search"
        ],
        "summary": "Deep Search",
        "operationId": "deepSearch",
        "description": "Comprehensive skip trace returning phone numbers, email addresses, and related persons/family members. Costs 10 credits per match. Credits are only charged when a match is found.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeepSearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search completed (may or may not contain a match).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeepSearchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/standard-search": {
      "post": {
        "tags": [
          "Search"
        ],
        "summary": "Standard Search",
        "operationId": "standardSearch",
        "description": "Flexible search that returns phone data, email data, or both via the dataTypes parameter. Charged 1 credit per data type per match (max 2). Credits are only charged when a match is found.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StandardSearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search completed (may or may not contain a match).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StandardSearchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/bulk/upload": {
      "post": {
        "tags": [
          "Bulk"
        ],
        "summary": "Upload CSV for bulk processing",
        "operationId": "bulkUpload",
        "description": "Upload a CSV file for high-volume Standard Search processing. The CSV must contain at minimum an 'address' column; firstName, lastName, city, state, and zip columns improve match rates. Credits are reserved upfront and adjusted to actual matches after processing completes (1 credit per data type per match). Returns a jobId to poll for status and download results.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "dataTypes"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSV file (.csv). Must include a header row and at least one data row."
                  },
                  "dataTypes": {
                    "type": "string",
                    "description": "JSON array string of data types to append, e.g. [\"phone\"], [\"email\"], or [\"phone\",\"email\"].",
                    "example": "[\"phone\",\"email\"]"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job accepted and processing started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkUploadResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/bulk/{jobId}/status": {
      "get": {
        "tags": [
          "Bulk"
        ],
        "summary": "Check bulk job status",
        "operationId": "bulkStatus",
        "description": "Poll the progress of a bulk processing job.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job ID returned by the bulk upload endpoint."
          }
        ],
        "responses": {
          "200": {
            "description": "Current job status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkStatusResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/bulk/{jobId}/download": {
      "get": {
        "tags": [
          "Bulk"
        ],
        "summary": "Download bulk job results",
        "operationId": "bulkDownload",
        "description": "Download the results of a completed bulk job as JSON (default) or CSV. The job must be in the 'completed' status.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job ID returned by the bulk upload endpoint."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ],
              "default": "json"
            },
            "description": "Response format. Defaults to JSON. Use 'csv' to download a CSV file."
          }
        ],
        "responses": {
          "200": {
            "description": "Completed job results.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkDownloadResponse"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/audience/upload": {
      "post": {
        "tags": [
          "Digital Matching"
        ],
        "summary": "Upload CSV to build ad audiences",
        "operationId": "audienceUpload",
        "description": "Upload a contact CSV and receive ready-to-upload Custom Audience files for the selected ad platforms. Each contact is matched against Ava Data's identity graph and every match is appended with securely hashed identifiers (the format ad platforms require) — often several verified emails and phone numbers per person, which is what lifts your matched-audience size. The CSV needs an email or phone column, or a name plus address/city/state/zip columns. Credits are reserved upfront and only matched contacts are charged (flat rate per matched contact — every selected platform included). By uploading you confirm you have the right to use the list for advertising and will follow each ad platform's customer-list policies.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "platforms"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSV file (.csv). Must include a header row and at least one data row."
                  },
                  "platforms": {
                    "type": "string",
                    "description": "JSON array string of target platforms: \"facebook\", \"google\", \"linkedin\", \"tiktok\", \"generic\".",
                    "example": "[\"facebook\",\"google\"]"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job accepted and processing started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AudienceUploadResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/audience/{jobId}/status": {
      "get": {
        "tags": [
          "Digital Matching"
        ],
        "summary": "Check Digital Matching job status",
        "operationId": "audienceStatus",
        "description": "Poll the progress of a Digital Matching job.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job ID returned by the audience upload endpoint."
          }
        ],
        "responses": {
          "200": {
            "description": "Current job status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AudienceStatusResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/audience/{jobId}/download": {
      "get": {
        "tags": [
          "Digital Matching"
        ],
        "summary": "Download audience files",
        "operationId": "audienceDownload",
        "description": "Download the completed job's audience files. Default is a ZIP containing one ready-to-upload CSV per selected platform, a master data file, and upload instructions. Pass ?platform= to download a single platform's CSV instead. The job must be in the 'completed' status.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The job ID returned by the audience upload endpoint."
          },
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "facebook",
                "google",
                "linkedin",
                "tiktok",
                "generic"
              ]
            },
            "description": "Download a single platform's CSV instead of the full ZIP."
          }
        ],
        "responses": {
          "200": {
            "description": "Audience files (ZIP) or a single platform CSV.",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/credits": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Check credit balance",
        "operationId": "getCredits",
        "description": "Returns your current credit balance, including subscription credits and wallet balance.",
        "responses": {
          "200": {
            "description": "Current credit balance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/usage": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Get API usage",
        "operationId": "getUsage",
        "description": "Returns aggregate API usage statistics plus a paginated list of recent requests.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 100
            },
            "description": "Number of recent activity records to return (max 100)."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "Number of records to skip for pagination."
          }
        ],
        "responses": {
          "200": {
            "description": "Usage statistics and recent activity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sk_live_...",
        "description": "Include your API key in the Authorization header using the Bearer scheme: `Authorization: Bearer sk_live_your_api_key_here`. Keys are generated from Settings → API Access once an administrator enables API access for your account. Rate limited to 60 requests per minute per key."
      }
    },
    "schemas": {
      "DeepSearchRequest": {
        "type": "object",
        "required": [
          "lastName"
        ],
        "properties": {
          "firstName": {
            "type": "string",
            "description": "Optional. Improves match accuracy.",
            "example": "John"
          },
          "lastName": {
            "type": "string",
            "minLength": 1,
            "description": "Required.",
            "example": "Smith"
          },
          "address": {
            "type": "string",
            "example": "123 Main St"
          },
          "city": {
            "type": "string",
            "example": "Austin"
          },
          "state": {
            "type": "string",
            "example": "TX"
          },
          "zip": {
            "type": "string",
            "example": "78701"
          }
        }
      },
      "StandardSearchRequest": {
        "type": "object",
        "required": [
          "lastName",
          "dataTypes"
        ],
        "properties": {
          "firstName": {
            "type": "string",
            "example": "John"
          },
          "lastName": {
            "type": "string",
            "minLength": 1,
            "example": "Smith"
          },
          "address": {
            "type": "string",
            "example": "123 Main St"
          },
          "city": {
            "type": "string",
            "example": "Austin"
          },
          "state": {
            "type": "string",
            "example": "TX"
          },
          "zip": {
            "type": "string",
            "example": "78701"
          },
          "dataTypes": {
            "type": "array",
            "minItems": 1,
            "description": "Which contact data to return and how credits are charged. [\"phone\"] = 1 credit, [\"email\"] = 1 credit, [\"phone\",\"email\"] = 2 credits.",
            "items": {
              "type": "string",
              "enum": [
                "phone",
                "email"
              ]
            },
            "example": [
              "phone",
              "email"
            ]
          }
        }
      },
      "Phone": {
        "type": "object",
        "properties": {
          "number": {
            "type": "string",
            "example": "5125551234"
          },
          "type": {
            "type": "string",
            "example": "mobile"
          }
        }
      },
      "Email": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "example": "john.smith@example.com"
          }
        }
      },
      "Address": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string",
            "example": "123 Main St"
          },
          "city": {
            "type": "string",
            "example": "Austin"
          },
          "state": {
            "type": "string",
            "example": "TX"
          },
          "zip": {
            "type": "string",
            "example": "78701"
          }
        }
      },
      "Subject": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "age": {
            "type": "integer",
            "nullable": true
          },
          "dob": {
            "type": "string",
            "nullable": true
          },
          "deceased": {
            "type": "boolean",
            "nullable": true
          },
          "phones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Phone"
            }
          },
          "emails": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Email"
            }
          },
          "addresses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Address"
            }
          },
          "bankruptcy": {
            "type": "boolean",
            "nullable": true
          }
        }
      },
      "RelatedPerson": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "age": {
            "type": "integer",
            "nullable": true
          },
          "deceased": {
            "type": "boolean",
            "nullable": true
          },
          "relationship": {
            "type": "string",
            "nullable": true,
            "example": "Spouse"
          },
          "phones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Phone"
            }
          },
          "emails": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Email"
            }
          },
          "addresses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Address"
            }
          },
          "bankruptcy": {
            "type": "boolean",
            "nullable": true
          }
        }
      },
      "DeepSearchResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "matchFound": {
                "type": "boolean"
              },
              "creditsCharged": {
                "type": "integer",
                "description": "10 when a match is found, otherwise 0.",
                "example": 10
              },
              "subject": {
                "$ref": "#/components/schemas/Subject"
              },
              "relatedPeople": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/RelatedPerson"
                }
              }
            }
          }
        }
      },
      "StandardSearchResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "matchFound": {
                "type": "boolean"
              },
              "creditsCharged": {
                "type": "integer",
                "description": "Number of data types charged when a match is found, otherwise 0.",
                "example": 2
              },
              "phones": {
                "type": "array",
                "description": "Present only when \"phone\" was requested and a match was found.",
                "items": {
                  "$ref": "#/components/schemas/Phone"
                }
              },
              "emails": {
                "type": "array",
                "description": "Present only when \"email\" was requested and a match was found.",
                "items": {
                  "$ref": "#/components/schemas/Email"
                }
              },
              "name": {
                "type": "string",
                "nullable": true
              },
              "addresses": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Address"
                }
              },
              "matchType": {
                "type": "string",
                "nullable": true
              }
            }
          }
        }
      },
      "BulkUploadResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "jobId": {
                "type": "string",
                "example": "abc123-def456"
              },
              "lookupId": {
                "type": "string",
                "example": "xyz789"
              },
              "recordCount": {
                "type": "integer"
              },
              "dataTypes": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "phone",
                    "email"
                  ]
                }
              },
              "creditsPerMatch": {
                "type": "integer",
                "example": 2
              },
              "status": {
                "type": "string",
                "example": "processing"
              },
              "message": {
                "type": "string"
              },
              "staffCapApplied": {
                "type": "boolean",
                "description": "Present only when a staff account's per-user processing cap truncated the upload."
              },
              "originalRecordCount": {
                "type": "integer",
                "description": "Present only when staffCapApplied is true: the number of records in the original file."
              },
              "bulkProcessingCap": {
                "type": "integer",
                "description": "Present only when staffCapApplied is true: the maximum records this account may process."
              }
            }
          }
        }
      },
      "BulkStatusResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "jobId": {
                "type": "string",
                "example": "abc123-def456"
              },
              "status": {
                "type": "string",
                "description": "Job lifecycle status.",
                "example": "processing",
                "enum": [
                  "uploading",
                  "queued",
                  "processing",
                  "completed",
                  "failed"
                ]
              },
              "progress": {
                "type": "integer",
                "description": "Percent complete (0-100).",
                "example": 65
              },
              "estimatedSecondsRemaining": {
                "type": "integer",
                "nullable": true,
                "example": 120
              },
              "numRecords": {
                "type": "integer"
              },
              "numMatches": {
                "type": "integer",
                "nullable": true
              },
              "errorMessage": {
                "type": "string",
                "nullable": true
              }
            }
          }
        }
      },
      "AudienceUploadResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "jobId": {
                "type": "string",
                "example": "abc123-def456"
              },
              "lookupId": {
                "type": "string",
                "example": "xyz789"
              },
              "recordCount": {
                "type": "integer"
              },
              "platforms": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "example": [
                  "facebook",
                  "google"
                ]
              },
              "creditsPerMatch": {
                "type": "integer",
                "example": 2
              },
              "status": {
                "type": "string",
                "example": "processing"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "AudienceStatusResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "jobId": {
                "type": "string",
                "example": "abc123-def456"
              },
              "status": {
                "type": "string",
                "description": "Job lifecycle status.",
                "example": "processing",
                "enum": [
                  "uploading",
                  "queued",
                  "processing",
                  "completed",
                  "failed"
                ]
              },
              "progress": {
                "type": "integer",
                "description": "Percent complete (0-100).",
                "example": 65
              },
              "numRecords": {
                "type": "integer"
              },
              "numMatches": {
                "type": "integer",
                "nullable": true,
                "description": "Matched contacts (each charged the flat per-match rate)."
              },
              "creditsCharged": {
                "type": "integer",
                "nullable": true,
                "example": 624
              },
              "platforms": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "example": [
                  "facebook",
                  "google"
                ]
              },
              "platformCounts": {
                "type": "object",
                "nullable": true,
                "additionalProperties": {
                  "type": "integer"
                },
                "description": "Matched contacts per platform, populated when the job completes."
              },
              "errorMessage": {
                "type": "string",
                "nullable": true
              }
            }
          }
        }
      },
      "BulkDownloadResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "jobId": {
                "type": "string",
                "example": "abc123-def456"
              },
              "numRecords": {
                "type": "integer"
              },
              "numMatches": {
                "type": "integer"
              },
              "creditsCharged": {
                "type": "integer",
                "example": 624
              },
              "results": {
                "type": "array",
                "description": "Enriched per-record results. Shape mirrors your uploaded columns plus appended data.",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "CreditsResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "subscriptionCredits": {
                "type": "integer",
                "example": 3000
              },
              "walletCredits": {
                "type": "integer",
                "example": 1500
              },
              "reservedCredits": {
                "type": "integer",
                "example": 0
              },
              "totalCredits": {
                "type": "integer",
                "example": 4500
              },
              "availableCredits": {
                "type": "integer",
                "example": 4500
              },
              "subscriptionStatus": {
                "type": "string",
                "nullable": true,
                "example": "active"
              }
            }
          }
        }
      },
      "UsageResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "stats": {
                "type": "object",
                "properties": {
                  "totalRequests": {
                    "type": "integer",
                    "example": 1250
                  },
                  "totalCreditsUsed": {
                    "type": "integer",
                    "example": 8400
                  },
                  "requestsToday": {
                    "type": "integer",
                    "example": 45
                  },
                  "requestsThisMonth": {
                    "type": "integer",
                    "example": 890
                  }
                }
              },
              "recentActivity": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "endpoint": {
                      "type": "string",
                      "example": "/api/v1/deep-search"
                    },
                    "method": {
                      "type": "string",
                      "example": "POST"
                    },
                    "statusCode": {
                      "type": "integer",
                      "example": 200
                    },
                    "creditsUsed": {
                      "type": "integer",
                      "example": 10
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              },
              "pagination": {
                "type": "object",
                "properties": {
                  "limit": {
                    "type": "integer",
                    "example": 50
                  },
                  "offset": {
                    "type": "integer",
                    "example": 0
                  },
                  "hasMore": {
                    "type": "boolean",
                    "example": false
                  }
                }
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string",
            "description": "Descriptive message explaining what went wrong."
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid or missing request parameters.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, invalid, or inactive API key, or API access not enabled.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "Insufficient credits for the requested operation.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Account suspended or access denied to the requested resource.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "The requested resource does not exist.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests — exceeds 60 requests per minute per API key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ServerError": {
        "description": "Internal server error. Any charged credits are refunded for search endpoints.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}
