{"openapi": "3.1.0", "info": {"title": "dev.batchiq.io", "version": "developers-v0.0.1-7ddfc3", "description": ""}, "paths": {"/v1/health": {"get": {"operationId": "apps_developers_api_health", "summary": "Health", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"additionalProperties": true, "title": "Response", "type": "object"}}}}}, "description": "Health check\n\nNo authentication required \u2014 safe for uptime monitors and load balancers.\n\n**Example response**\n\n```json\n{\"error\": false, \"data\": {\"status\": \"ok\", \"message\": \"API is running\"}}\n```", "tags": ["Developers"]}}, "/v1/errors": {"get": {"operationId": "apps_developers_api_errors", "summary": "Errors", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"additionalProperties": true, "title": "Response", "type": "object"}}}}}, "description": "Error catalog\n\nA dictionary of every error this API can return, keyed by error name.\nUse it to look up what an `error_code` means instead of hard-coding the\nmessages in your client.\n\n**Error envelope**\n\nEvery unsuccessful response has `\"error\": true` and the error fields\nunder `data`:\n\n```json\n{\n  \"error\": true,\n  \"data\": {\n    \"error_code\": 4500,\n    \"code\": 401,\n    \"message\": \"Invalid API key\",\n    \"details\": \"The API key is unknown, revoked, or its membership is not active\"\n  }\n}\n```\n\n| Field | Meaning |\n|---|---|\n| `code` | HTTP status of the response |\n| `error_code` | Stable, unique identifier for this error type |\n| `message` | Short human-readable summary |\n| `details` | Extra context about what went wrong |\n\nNo authentication required.", "tags": ["Developers"]}}, "/v1/dnc/check": {"post": {"operationId": "apps_developers_dnc_check", "summary": "Check", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResponseDncCheck"}}}}}, "description": "Check a phone number against DNC data\n\nScreen one phone number against litigation, blacklist and DNC lists.\n\n**Auth:** `X-API-Key` header \u2014 requires the `dnc.check` permission\n(an active DNC plan). There is no daily limit: check as often as you like.\n\n**Request body**\n\n```json\n{\"phone\": \"8439689323\"}\n```\n\n**Response**\n\n```json\n{\"error\": false, \"data\": {\"phone\": \"8439689323\", \"status\": \"CLEAR\", \"id\": 42}}\n```\n\n- `status` \u2014 `CLEAR` = safe to call, `DNC` = do not call, `LITIGATOR\n  BLACKLIST` = do not call (the number appears on a litigator/blacklist\n  entry). Treat any other or empty value as blocked.\n- `id` \u2014 reference id of the stored result; `null` when the check could\n  not be stored (the `status` is then empty too).\n\nRepeat calls for the same number answer instantly from previous results.\n\n**Errors**\n\n| Status | `error_code` | When |\n|---|---|---|\n| 401 | 4500 / 4503 | missing, invalid or expired API key |\n| 403 | 4033 | your plan does not include `dnc.check` |\n| 400 | 4000 | `phone` missing or empty |\n| 429 | \u2014 | rate limit (100 requests/second per key) |", "tags": ["DNC"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PayloadDncCheck"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/v1/dnc/upload": {"post": {"operationId": "apps_developers_dnc_upload", "summary": "Upload", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResponseDncBatchUpload"}}}}}, "description": "Upload a file for batch DNC checking\n\nScreen every phone number in a CSV/Excel file against DNC data. The\nresult file comes back with a **status column added next to the phone\ncolumn** \u2014 same file, now annotated.\n\n**Auth:** `X-API-Key` header \u2014 requires the `dnc.upload` permission.\n\n**Request** \u2014 `multipart/form-data`:\n\n| Field | Required | Description |\n|---|---|---|\n| `file` | yes | `.csv`, `.xlsx` or `.xls` with at least one column whose header mentions *phone* |\n| `name` | no | label for this run; a generated `batches-upload-<number>` when omitted. Reusing one of your own labels adds a ` (2)` counter \u2014 the stored label always comes back as `batch_name`, so poll and download with that |\n| `webhook_url` | no | absolute `http(s)` URL to `POST` a JSON payload to when the run completes. Omit for no webhook |\n\nWhen `webhook_url` is set, a completion payload is sent once the run\nfinishes and the annotated file is written:\n\n```json\n{\n  \"event\": \"dnc.batch.completed\",\n  \"batch_id\": 17,\n  \"batch_name\": \"leads-2026-10\",\n  \"status\": \"completed\",\n  \"phones\": 500,\n  \"completed_at\": \"2026-10-13T09:15:00Z\"\n}\n```\n\nThe delivery is retried a few times on failure; treat it as\nat-least-once and deduplicate on `batch_id` if that matters to you.\n\n**Response**\n\n```json\n{\"error\": false, \"data\": {\"batch_id\": 17, \"batch_name\": \"leads-2026-10\", \"status\": \"queued\", \"phones\": 500}}\n```\n\n**Workflow**\n\n1. Upload and note `batch_name`.\n2. Poll `GET /v1/dnc/batches?name=<batch_name>` until `status` is `completed`.\n3. Optionally read rows from `GET /v1/dnc/batches/{batch_id}`.\n4. Download the annotated file from `GET /v1/dnc/download?name=<batch_name>`.\n\n**Errors**\n\n| Status | `error_code` | When |\n|---|---|---|\n| 401 | 4500 / 4503 | missing, invalid or expired API key |\n| 403 | 4033 | your plan does not include `dnc.upload` |\n| 400 | 4008 | not a `.csv`/`.xlsx`/`.xls` file |\n| 400 | 4000 | unreadable file, no phone column, no phone numbers, or an invalid `webhook_url` |", "tags": ["DNC"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/v1/dnc/batches": {"get": {"operationId": "apps_developers_dnc_list_batches", "summary": "List Batches", "parameters": [{"in": "query", "name": "name", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "required": false}, {"in": "query", "name": "kind", "schema": {"default": "batch", "title": "Kind", "type": "string"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "minimum": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"anyOf": [{"minimum": 1, "type": "integer"}, {"type": "null"}], "title": "Page Size"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PagedResponseDncBatch"}}}}}, "description": "List your DNC runs\n\nEvery batch upload, single check and file screening shows up here as a\n*run*, newest first. Poll this after an upload to follow its progress.\n\n**Auth:** `X-API-Key` header \u2014 requires the `dnc.read` permission.\n\n**Query parameters**\n\n| Param | Default | Description |\n|---|---|---|\n| `name` | \u2014 | exact run label (the `batch_name` from the upload response); when given, `kind` is ignored |\n| `kind` | `batch` | `batch` = file uploads, `single` = one-off checks, `enrichment` = file screenings |\n| `page` | 1 | page number, 100 runs per page |\n\n**Response** \u2014 `{\"items\": [...], \"count\": n}`, each item:\n\n```json\n{\n  \"batch_id\": 17,\n  \"name\": \"leads-2026-10\",\n  \"kind\": \"batch\",\n  \"status\": \"completed\",\n  \"created_at\": \"2026-10-13T09:15:00Z\",\n  \"check_count\": 500,\n  \"meta\": {\"total\": 500, \"processed\": 500, \"saved\": 500}\n}\n```\n\n- `status` \u2014 `queued` \u2192 `running` \u2192 `completed` (or `failed`)\n- `check_count` \u2014 number of results so far\n- `meta` \u2014 progress counters and result totals while it runs\n\n**Errors:** `401` invalid key \u00b7 `403` `error_code` 4033 (no `dnc.read`)", "tags": ["DNC"], "security": [{"ApiKeyAuth": []}]}}, "/v1/dnc/batches/{batch_id}": {"get": {"operationId": "apps_developers_dnc_batch_result", "summary": "Batch Result", "parameters": [{"in": "path", "name": "batch_id", "schema": {"title": "Batch Id", "type": "integer"}, "required": true}, {"in": "query", "name": "page", "schema": {"default": 1, "minimum": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"anyOf": [{"minimum": 1, "type": "integer"}, {"type": "null"}], "title": "Page Size"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PagedResponseDncBatchResult"}}}}}, "description": "Get the results of one run\n\nEvery checked phone of a run, row by row \u2014 the same columns the\ndownloadable result file gains.\n\n**Auth:** `X-API-Key` header \u2014 requires the `dnc.read` permission.\n\n**Path parameter:** `batch_id` \u2014 from `GET /v1/dnc/batches` or the\nupload response. Results are paginated (100 rows per page, `?page=`).\n\n**Row**\n\n```json\n{\n  \"phone\": \"8439689323\",\n  \"status\": \"CLEAR\",\n  \"dnc_id\": 1234,\n  \"batch_id\": 17,\n  \"checked_at\": \"2026-10-13T09:15:00Z\"\n}\n```\n\n- `status` \u2014 `CLEAR` (safe to call), `DNC` or `LITIGATOR BLACKLIST`\n  (do not call)\n\n**Errors**\n\n| Status | `error_code` | When |\n|---|---|---|\n| 401 | 4500 / 4503 | missing, invalid or expired API key |\n| 403 | 4033 | your plan does not include `dnc.read` |\n| 404 | 4040 | unknown run, or a run belonging to another account |", "tags": ["DNC"], "security": [{"ApiKeyAuth": []}]}}, "/v1/dnc/download": {"get": {"operationId": "apps_developers_dnc_download_result", "summary": "Download Result", "parameters": [{"in": "query", "name": "name", "schema": {"title": "Name", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResponseDncDownloadUrl"}}}}}, "description": "Download a run's result file\n\nGet a temporary link to the uploaded file **with the DNC status column\nadded** next to the phone column (same file, now annotated).\n\n**Auth:** `X-API-Key` header \u2014 requires the `dnc.download` permission.\n\n**Query parameters**\n\n| Param | Description |\n|---|---|\n| `name` | run label \u2014 the `batch_name` returned by the upload |\n\n**Response**\n\n```json\n{\"error\": false, \"data\": {\"download_url\": \"https://...\", \"expires_in\": 3600}}\n```\n\n`download_url` is valid for `expires_in` seconds (3600). Request a fresh\nlink after it expires; links can be shared with anyone while valid.\n\n**Errors**\n\n| Status | `error_code` | When |\n|---|---|---|\n| 401 | 4500 / 4503 | missing, invalid or expired API key |\n| 403 | 4033 | your plan does not include `dnc.download` |\n| 404 | 4040 | no run with that label on your account |\n| 400 | 4001 | result file not ready yet \u2014 wait for `completed` and retry |", "tags": ["DNC"], "security": [{"ApiKeyAuth": []}]}}, "/v1/skip-trace/upload": {"post": {"operationId": "apps_developers_files_upload_file", "summary": "Upload File", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResponseFileUpload"}}}}}, "description": "Upload a file for batch append processing\n\nUpload a CSV/Excel file, have it processed (batch append, phone append\nor reverse phone lookup), and pay from your account's credit balance in\na single call. The credit charge happens immediately at the estimated\ncost; when processing finishes the charge is adjusted to the actual\nresult (overcharge refunded, shortfall deducted).\n\n**Auth:** `X-API-Key` header \u2014 any active key whose owner has enough\ncredit. There is no separate permission scope; the credit balance is\nthe gate.\n\n**Request** \u2014 `multipart/form-data`:\n\n| Field | Required | Description |\n|---|---|---|\n| `file` | yes | `.csv`, `.xlsx` or `.xls` |\n| `product` | yes | `batch_append` (batch append), `phone_append` (phone append), `phone_lookup` (reverse phone). Phone-append accounts accept only `phone_append`. |\n| `headers[...]` | no | optional header mapping in PHP-style form format, e.g. `headers[first_name]=First Name` |\n| `webhook_url` | no | absolute `http(s)` URL to `POST` a JSON payload to when the file completes. Omit for no webhook |\n\nWhen `webhook_url` is set, a completion payload is sent once the\nfile is processed and paid for:\n\n```json\n{\n  \"event\": \"skip_trace.file.completed\",\n  \"file_id\": \"3f2b...\",\n  \"filename\": \"leads.csv\",\n  \"product\": \"batch_append\",\n  \"status\": \"completed\",\n  \"rows\": 500,\n  \"charged\": \"12.50\",\n  \"completed_at\": \"2026-10-13T09:22:00Z\"\n}\n```\n\nThe delivery is retried a few times on failure; treat it as\nat-least-once and deduplicate on `file_id` if that matters to you.\n\n**Response**\n\n```json\n{\"error\": false, \"data\": {\"file_id\": \"3f2b...\", \"status\": \"processing\", \"product\": \"batch_append\", \"rows\": 500, \"charged\": \"12.50\", \"credit_remaining\": \"87.50\"}}\n```\n\n- `charged` \u2014 amount deducted from your credit now (respects your\n  account's minimum charge; no processing fee on credit payments)\n- `credit_remaining` \u2014 balance after the deduction\n\n**Workflow**\n\n1. Upload and note `file_id`.\n2. Poll `GET /v1/skip-trace/{file_id}` until `status` is `completed`.\n3. Download the result from `GET /v1/skip-trace/{file_id}/download`.\n\n**Errors**\n\n| Status | `error_code` | When |\n|---|---|---|\n| 401 | 4500 / 4503 | missing, invalid or expired API key |\n| 402 | 4020 | credit balance does not cover the charge |\n| 400 | 4008 | not a `.csv`/`.xlsx`/`.xls` file |\n| 400 | 4000 | missing/invalid `product`, unreadable file, empty file, below minimum rows, no pricing configured, or an invalid `webhook_url` |", "tags": ["Skip Trace"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/v1/skip-trace": {"get": {"operationId": "apps_developers_files_list_files", "summary": "List Files", "parameters": [{"in": "query", "name": "page", "schema": {"default": 1, "minimum": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"anyOf": [{"minimum": 1, "type": "integer"}, {"type": "null"}], "title": "Page Size"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PagedResponseFile"}}}}}, "description": "List your uploaded files\n\nEvery file uploaded through this API, newest first.\n\n**Auth:** `X-API-Key` header \u2014 any active key.\n\n**Response** \u2014 `{\"items\": [...], \"count\": n}`, each item:\n\n```json\n{\n  \"file_id\": \"3f2b...\",\n  \"filename\": \"leads.csv\",\n  \"product\": \"batch_append\",\n  \"status\": \"completed\",\n  \"rows\": 500,\n  \"charged\": \"12.50\",\n  \"created_at\": \"2026-10-13T09:15:00Z\",\n  \"completed_at\": \"2026-10-13T09:22:00Z\",\n  \"download_url\": null,\n  \"error\": null\n}\n```\n\n- `status` \u2014 `pending` \u2192 `processing` \u2192 `completed` (or `failed`)\n- `charged` \u2014 amount taken from your credit (adjusted at completion)\n- `error` \u2014 failure reason when `status` is `failed`\n\n**Errors:** `401` invalid key", "tags": ["Skip Trace"], "security": [{"ApiKeyAuth": []}]}}, "/v1/skip-trace/{file_id}": {"get": {"operationId": "apps_developers_files_get_file", "summary": "Get File", "parameters": [{"in": "path", "name": "file_id", "schema": {"format": "uuid", "title": "File Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResponseFile"}}}}}, "description": "Get one file's status\n\nPoll this after an upload until `status` is `completed`; the response\nthen carries a `download_url` for the result file.\n\n**Auth:** `X-API-Key` header \u2014 any active key.\n\n**Path parameter:** `file_id` \u2014 from the upload response.\n\n**Response**\n\n```json\n{\n  \"file_id\": \"3f2b...\",\n  \"filename\": \"leads.csv\",\n  \"product\": \"batch_append\",\n  \"status\": \"completed\",\n  \"rows\": 500,\n  \"charged\": \"12.50\",\n  \"created_at\": \"2026-10-13T09:15:00Z\",\n  \"completed_at\": \"2026-10-13T09:22:00Z\",\n  \"download_url\": \"https://...\",\n  \"error\": null\n}\n```\n\n- `download_url` \u2014 present only when the file is completed and paid;\n  otherwise `null` (use `GET /v1/skip-trace/{file_id}/download` which\n  reports `4001` while not ready)\n\n**Errors**\n\n| Status | `error_code` | When |\n|---|---|---|\n| 401 | 4500 / 4503 | missing, invalid or expired API key |\n| 404 | 4040 | unknown file, or a file belonging to another account |", "tags": ["Skip Trace"], "security": [{"ApiKeyAuth": []}]}}, "/v1/skip-trace/{file_id}/download": {"get": {"operationId": "apps_developers_files_download_result", "summary": "Download Result", "parameters": [{"in": "path", "name": "file_id", "schema": {"format": "uuid", "title": "File Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResponseDownloadUrl"}}}}}, "description": "Download a file's result\n\nGet a temporary link to the processed result file.\n\n**Auth:** `X-API-Key` header \u2014 any active key.\n\n**Path parameter:** `file_id` \u2014 from the upload response.\n\n**Response**\n\n```json\n{\"error\": false, \"data\": {\"download_url\": \"https://...\", \"expires_in\": 3600}}\n```\n\n`download_url` is valid for `expires_in` seconds (3600). Request a\nfresh link after it expires; links can be shared with anyone while\nvalid.\n\n**Errors**\n\n| Status | `error_code` | When |\n|---|---|---|\n| 401 | 4500 / 4503 | missing, invalid or expired API key |\n| 404 | 4040 | unknown file, or a file belonging to another account |\n| 400 | 4001 | result not ready yet \u2014 wait for `completed` and retry |\n| 400 | 4000 | result exists but is not paid for |", "tags": ["Skip Trace"], "security": [{"ApiKeyAuth": []}]}}}, "components": {"schemas": {"ResponseDncCheck": {"description": "Response for POST /v1/dnc/check: phone, status and row id only.", "properties": {"phone": {"title": "Phone", "type": "string"}, "status": {"title": "Status", "type": "string"}, "id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}}, "required": ["phone", "status", "id"], "title": "ResponseDncCheck", "type": "object"}, "PayloadDncCheck": {"description": "Request body for POST /v1/dnc/check.", "properties": {"phone": {"title": "Phone", "type": "string"}}, "required": ["phone"], "title": "PayloadDncCheck", "type": "object"}, "ResponseDncBatchUpload": {"description": "Response for POST /v1/dnc/upload: the queued batch.", "properties": {"batch_id": {"title": "Batch Id", "type": "integer"}, "batch_name": {"title": "Batch Name", "type": "string"}, "status": {"title": "Status", "type": "string"}, "phones": {"title": "Phones", "type": "integer"}}, "required": ["batch_id", "batch_name", "status", "phones"], "title": "ResponseDncBatchUpload", "type": "object"}, "Input": {"properties": {"page": {"default": 1, "minimum": 1, "title": "Page", "type": "integer"}, "page_size": {"anyOf": [{"minimum": 1, "type": "integer"}, {"type": "null"}], "title": "Page Size"}}, "title": "Input", "type": "object"}, "PagedResponseDncBatch": {"properties": {"items": {"items": {"$ref": "#/components/schemas/ResponseDncBatch"}, "title": "Items", "type": "array"}, "count": {"title": "Count", "type": "integer"}}, "required": ["items", "count"], "title": "PagedResponseDncBatch", "type": "object"}, "ResponseDncBatch": {"description": "Response row for GET /v1/dnc/batches: one run and its stats.", "properties": {"batch_id": {"title": "Batch Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "kind": {"title": "Kind", "type": "string"}, "status": {"title": "Status", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "check_count": {"title": "Check Count", "type": "integer"}, "meta": {"additionalProperties": true, "title": "Meta", "type": "object"}}, "required": ["batch_id", "name", "kind", "status", "created_at", "check_count", "meta"], "title": "ResponseDncBatch", "type": "object"}, "PagedResponseDncBatchResult": {"properties": {"items": {"items": {"$ref": "#/components/schemas/ResponseDncBatchResult"}, "title": "Items", "type": "array"}, "count": {"title": "Count", "type": "integer"}}, "required": ["items", "count"], "title": "PagedResponseDncBatchResult", "type": "object"}, "ResponseDncBatchResult": {"description": "One row of GET /v1/dnc/batches/{id} \u2014 same columns as the file.", "properties": {"phone": {"title": "Phone", "type": "string"}, "status": {"title": "Status", "type": "string"}, "dnc_id": {"title": "Dnc Id", "type": "integer"}, "batch_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Batch Id"}, "checked_at": {"title": "Checked At", "type": "string"}}, "required": ["phone", "status", "dnc_id", "batch_id", "checked_at"], "title": "ResponseDncBatchResult", "type": "object"}, "ResponseDncDownloadUrl": {"description": "Presigned result-file URL for GET /v1/dnc/download.", "properties": {"download_url": {"title": "Download Url", "type": "string"}, "expires_in": {"title": "Expires In", "type": "integer"}}, "required": ["download_url", "expires_in"], "title": "ResponseDncDownloadUrl", "type": "object"}, "ResponseFileUpload": {"description": "Response for POST /v1/skip-trace/upload: the queued file and its charge.", "properties": {"file_id": {"format": "uuid", "title": "File Id", "type": "string"}, "status": {"title": "Status", "type": "string"}, "product": {"title": "Product", "type": "string"}, "rows": {"title": "Rows", "type": "integer"}, "charged": {"title": "Charged", "type": "string"}, "credit_remaining": {"title": "Credit Remaining", "type": "string"}}, "required": ["file_id", "status", "product", "rows", "charged", "credit_remaining"], "title": "ResponseFileUpload", "type": "object"}, "PagedResponseFile": {"properties": {"items": {"items": {"$ref": "#/components/schemas/ResponseFile"}, "title": "Items", "type": "array"}, "count": {"title": "Count", "type": "integer"}}, "required": ["items", "count"], "title": "PagedResponseFile", "type": "object"}, "ResponseFile": {"description": "Response row for GET /v1/skip-trace and GET /v1/skip-trace/{id}.", "properties": {"file_id": {"format": "uuid", "title": "File Id", "type": "string"}, "filename": {"title": "Filename", "type": "string"}, "product": {"title": "Product", "type": "string"}, "status": {"title": "Status", "type": "string"}, "rows": {"title": "Rows", "type": "integer"}, "charged": {"title": "Charged", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Completed At"}, "download_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Download Url"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}}, "required": ["file_id", "filename", "product", "status", "rows", "charged", "created_at"], "title": "ResponseFile", "type": "object"}, "ResponseDownloadUrl": {"description": "Presigned result-file URL for GET /v1/skip-trace/{id}/download.", "properties": {"download_url": {"title": "Download Url", "type": "string"}, "expires_in": {"title": "Expires In", "type": "integer"}}, "required": ["download_url", "expires_in"], "title": "ResponseDownloadUrl", "type": "object"}}, "securitySchemes": {"ApiKeyAuth": {"type": "apiKey", "in": "header", "name": "X-API-Key"}}}, "servers": []}