{"openapi":"3.1.0","info":{"title":"MailValid — Email Verification API","version":"0.1.0","description":"Real-time email verification API: validity, disposable / role-based / catch-all detection, SMTP mailbox check, and confidence scoring. Single and bulk. Authenticate with an API key in the X-API-Key header (create one at https://mailvalid.io/dashboard).","contact":{"name":"MailValid Support","email":"sachin@mailvalid.io"},"x-logo":{"url":"https://mailvalid.io/static/logo.png"}},"servers":[{"url":"https://mailvalid.io","description":"Production"}],"paths":{"/api/v1/verify/single":{"post":{"tags":["Verification"],"summary":"Verify Single Email Address","description":"Verify a single email address and validate its deliverability using SMTP validation, MX lookup, and advanced pattern matching.\n\n**What you get:**\n- Valid/Invalid/Catch-all/Unknown/Do-Not-Mail status\n- Disposable email detection (temp mail, throwaway domains)\n- Role-based detection (info@, admin@, support@)\n- SMTP mailbox confirmation\n- Confidence score (0-100)\n\n**Use cases:** Email signup forms, contact forms, lead qualification, CRM data cleaning, e-commerce checkout validation.\n\n**Pricing:** Pay-per-use at $0.003 per verification. No monthly fees. Requests via RapidAPI do NOT deduct credits (RapidAPI handles billing).","operationId":"verify_single_email_api_v1_verify_single_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SingleVerifyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SingleVerifyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/verify/bulk":{"post":{"tags":["Verification"],"summary":"Verify Bulk Emails","description":"Submit a batch of emails for verification.\n\n**Cost:** 1 credit per completed result (`valid`, `invalid`, `catch_all`, `do_not_mail`),\nwhether fresh or served from cache. Duplicate emails and `unknown` results are not charged.\n**RapidAPI:** Requests via RapidAPI do NOT deduct credits (RapidAPI handles billing)\n\n**Authentication:** Requires X-API-Key header\n\n**Limits (per bulk job, by plan):**\n- Free: 100 · Paid (MailValid Plus or pay-as-you-go): 10,000\n- Exceeding your plan's cap returns 413; results via GET /v1/verify/bulk/{job_id}\n\n**Webhook (Optional):**\nProvide a `webhook_url` to receive a POST notification when the job completes.","operationId":"verify_bulk_emails_api_v1_verify_bulk_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkVerifyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkVerifyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Verification"],"summary":"List Bulk Jobs","description":"List your bulk verification jobs.","operationId":"list_bulk_jobs_api_v1_verify_bulk_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":20,"title":"Page Size"},"description":"Items per page"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkJobListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/verify/bulk/{job_id}":{"get":{"tags":["Verification"],"summary":"Get Bulk Job Status","description":"Get the status and results of a bulk verification job.","operationId":"get_bulk_job_status_api_v1_verify_bulk__job_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkJobStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Verification"],"summary":"Cancel Bulk Job","description":"Cancel a pending or processing bulk verification job.","operationId":"cancel_bulk_job_api_v1_verify_bulk__job_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/verify/bulk/{job_id}/download":{"get":{"tags":["Verification"],"summary":"Download Bulk Results","description":"Download bulk verification results as JSON or CSV.\n\nAny passthrough columns supplied when the job was submitted are appended to\nthe RIGHT of the standard verification columns, so a customer gets their own\nspreadsheet back with our verdict in front of it.","operationId":"download_bulk_results_api_v1_verify_bulk__job_id__download_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"Export format: json or csv","default":"json","title":"Format"},"description":"Export format: json or csv"},{"name":"filter","in":"query","required":false,"schema":{"type":"string","description":"Which rows to export: 'all' (default), 'valid', 'invalid', 'catch_all', 'unknown' or 'do_not_mail'. Defaults to the full result set, so omitting it is unchanged behaviour.","default":"all","title":"Filter"},"description":"Which rows to export: 'all' (default), 'valid', 'invalid', 'catch_all', 'unknown' or 'do_not_mail'. Defaults to the full result set, so omitting it is unchanged behaviour."},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/credits":{"get":{"tags":["Credits"],"summary":"Get Credits","description":"Get current credit balance.\n\n**Authentication:** Requires X-API-Key header","operationId":"get_credits_api_v1_credits_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditBalance"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/secret":{"get":{"tags":["Webhooks"],"summary":"Get Webhook Secret","description":"Return your per-user webhook signing secret so you can verify the\n`X-Mailvalid-Signature` header (HMAC-SHA256) on delivered webhooks.\n\nAuthenticated with your API key (`X-API-Key`). The value is stable per\naccount — the same secret shown in the dashboard. Returns\n`{\"webhook_secret\": \"...\"}`.","operationId":"get_webhook_secret_api_v1_webhooks_secret_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/bounce":{"post":{"tags":["Webhooks"],"summary":"Receive Bounce Webhook","description":"Receive bounce/delivery events to improve verification accuracy.\n\n**Authentication:** Requires X-API-Key header\n\n**Event Types:**\n- `delivered` — Email was successfully delivered\n- `hard_bounce` — Permanent bounce (mailbox doesn't exist)\n- `soft_bounce` — Temporary bounce (mailbox full, server down)\n- `complaint` — Spam complaint received\n- `unsubscribe` — User unsubscribed\n\n**How it works:**\nEach event updates our historical bounce database. Over time, this data\nmakes verification results more accurate — especially for providers that\nblock SMTP verification (Microsoft, Apple).\n\n**Limits:** Max 1,000 events per request.","operationId":"receive_bounce_webhook_api_v1_webhooks_bounce_post","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BounceWebhookRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BounceWebhookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"BounceEvent":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"event_type":{"type":"string","title":"Event Type","description":"Event type: hard_bounce, soft_bounce, delivered, complaint, unsubscribe"},"bounce_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bounce Code","description":"SMTP bounce code (e.g. '550', '452')"},"bounce_message":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Bounce Message","description":"Bounce reason message"},"timestamp":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Timestamp","description":"When the event occurred (defaults to now)"}},"type":"object","required":["email","event_type"],"title":"BounceEvent","description":"Single bounce/delivery event from customer webhook"},"BounceWebhookRequest":{"properties":{"events":{"items":{"$ref":"#/components/schemas/BounceEvent"},"type":"array","maxItems":1000,"minItems":1,"title":"Events","description":"List of bounce/delivery events (max 1000 per request)"}},"type":"object","required":["events"],"title":"BounceWebhookRequest","description":"Bounce webhook payload — batch of events"},"BounceWebhookResponse":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"processed":{"type":"integer","title":"Processed","default":0},"errors":{"type":"integer","title":"Errors","default":0},"message":{"type":"string","title":"Message","default":""}},"type":"object","title":"BounceWebhookResponse","description":"Bounce webhook response"},"BulkJobListResponse":{"properties":{"jobs":{"items":{"$ref":"#/components/schemas/BulkJobSummary"},"type":"array","title":"Jobs"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["jobs","total","page","page_size","has_more"],"title":"BulkJobListResponse","description":"Response for listing bulk jobs"},"BulkJobStatus":{"properties":{"job_id":{"type":"string","format":"uuid","title":"Job Id"},"status":{"type":"string","title":"Status"},"total_emails":{"type":"integer","title":"Total Emails"},"processed_emails":{"type":"integer","title":"Processed Emails"},"valid_count":{"type":"integer","title":"Valid Count"},"invalid_count":{"type":"integer","title":"Invalid Count"},"progress_percentage":{"type":"number","title":"Progress Percentage"},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"},"results":{"anyOf":[{"items":{"$ref":"#/components/schemas/VerificationResult"},"type":"array"},{"type":"null"}],"title":"Results"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"webhook_delivered":{"type":"boolean","title":"Webhook Delivered","default":false},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["job_id","status","total_emails","processed_emails","valid_count","invalid_count","progress_percentage","created_at"],"title":"BulkJobStatus","description":"Bulk job status response"},"BulkJobSummary":{"properties":{"job_id":{"type":"string","format":"uuid","title":"Job Id"},"status":{"type":"string","title":"Status"},"total_emails":{"type":"integer","title":"Total Emails"},"processed_emails":{"type":"integer","title":"Processed Emails"},"valid_count":{"type":"integer","title":"Valid Count"},"invalid_count":{"type":"integer","title":"Invalid Count"},"progress_percentage":{"type":"number","title":"Progress Percentage"},"credits_used":{"type":"integer","title":"Credits Used"},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["job_id","status","total_emails","processed_emails","valid_count","invalid_count","progress_percentage","credits_used","created_at"],"title":"BulkJobSummary","description":"Bulk job summary for listing (without results)"},"BulkSourceData":{"properties":{"columns":{"items":{"type":"string"},"type":"array","maxItems":40,"title":"Columns"},"rows":{"additionalProperties":{"items":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"array"},"type":"object","title":"Rows"}},"type":"object","title":"BulkSourceData","description":"The non-email columns of an uploaded list, echoed back on download.\n\n``rows`` is keyed by lowercased email and holds values positionally against\n``columns`` — keying by email survives the server-side dedupe, and positional\nvalues keep a 10k-row list from repeating every column name 10k times."},"BulkVerifyRequest":{"properties":{"emails":{"items":{"type":"string"},"type":"array","maxItems":10000,"minItems":1,"title":"Emails"},"filename":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Filename","description":"Optional source file name (e.g. 'leads-q3.csv'). Stored and echoed back on job status/list so you can recognise the job by its list instead of the job id. Display-only."},"source_data":{"anyOf":[{"$ref":"#/components/schemas/BulkSourceData"},{"type":"null"}],"description":"Optional passthrough columns from the uploaded file. Any column given here is appended, unchanged, to the RIGHT of the standard verification columns in the CSV/JSON download, so results can be stitched straight back onto your own data. Omit it and downloads are byte-identical to before."},"webhook_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Webhook Url","description":"Optional webhook URL to receive job completion notification"}},"type":"object","required":["emails"],"title":"BulkVerifyRequest","description":"Bulk email verification request.\n\n`emails` is intentionally ``list[str]`` rather than ``list[EmailStr]``.\nPydantic validates ``list[EmailStr]`` atomically, so a single malformed\naddress used to 422 the *entire* batch — fatal for the real-world dirty\nlists this product exists to clean. We now accept raw strings and let the\nverifier classify malformed addresses as ``invalid`` (status_reason\n``email_format_invalid``), exactly as the single-verify endpoint already\ndoes. Blank entries are stripped out before the job is created."},"BulkVerifyResponse":{"properties":{"job_id":{"type":"string","format":"uuid","title":"Job Id"},"status":{"type":"string","title":"Status","default":"pending"},"total_emails":{"type":"integer","title":"Total Emails"},"credits_reserved":{"type":"integer","title":"Credits Reserved"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"message":{"type":"string","title":"Message","default":"Bulk verification job created. Poll the status endpoint or wait for webhook."}},"type":"object","required":["job_id","total_emails","credits_reserved"],"title":"BulkVerifyResponse","description":"Bulk verification job created response"},"CreditBalance":{"properties":{"balance":{"type":"integer","title":"Balance"},"lifetime_used":{"type":"integer","title":"Lifetime Used"}},"type":"object","required":["balance","lifetime_used"],"title":"CreditBalance","description":"Current credit balance"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"MXRecord":{"properties":{"priority":{"type":"integer","title":"Priority"},"host":{"type":"string","title":"Host"}},"type":"object","required":["priority","host"],"title":"MXRecord","description":"MX record info"},"SingleVerifyRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"SingleVerifyRequest","description":"Single email verification request"},"SingleVerifyResponse":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"credits_used":{"type":"integer","title":"Credits Used","default":1},"result":{"$ref":"#/components/schemas/VerificationResult"}},"type":"object","required":["result"],"title":"SingleVerifyResponse","description":"Single email verification response"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerificationResult":{"properties":{"email":{"type":"string","title":"Email"},"status":{"type":"string","title":"Status"},"is_valid":{"type":"boolean","title":"Is Valid"},"syntax_valid":{"type":"boolean","title":"Syntax Valid"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"domain_valid":{"type":"boolean","title":"Domain Valid"},"has_mx":{"type":"boolean","title":"Has Mx"},"mx_records":{"items":{"$ref":"#/components/schemas/MXRecord"},"type":"array","title":"Mx Records","default":[]},"smtp_checked":{"type":"boolean","title":"Smtp Checked"},"smtp_response_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Smtp Response Code"},"is_disposable":{"type":"boolean","title":"Is Disposable","default":false},"is_role_based":{"type":"boolean","title":"Is Role Based","default":false},"is_catch_all":{"type":"boolean","title":"Is Catch All","default":false},"is_free_provider":{"type":"boolean","title":"Is Free Provider","default":false},"confidence_score":{"type":"integer","title":"Confidence Score","default":0},"status_reason":{"type":"string","title":"Status Reason","default":""},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"},"verification_time_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Verification Time Ms"},"cached":{"type":"boolean","title":"Cached","default":false}},"type":"object","required":["email","status","is_valid","syntax_valid","domain_valid","has_mx","smtp_checked"],"title":"VerificationResult","description":"Single email verification result with confidence scoring.\n\nStatus codes (industry-standard):\n  valid       — SMTP confirmed mailbox exists. Safe to send.\n  invalid     — Address will bounce (bad syntax, no domain, mailbox not found).\n  catch_all   — Domain accepts all addresses. Cannot confirm individual mailbox.\n  unknown     — Could not determine (server blocked, timeout, provider blocks SMTP).\n  do_not_mail — Address may work but is risky (disposable, role-based).\n\nSub-status (status_reason) gives the specific reason:\n  mailbox_confirmed, mailbox_not_found, failed_syntax_check, no_dns_entries,\n  no_mx_records, disposable, role_based, accept_all, antispam_system,\n  failed_smtp_connection, greylisted, mail_server_temporary_error"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}},"tags":[{"name":"Verification","description":"Verify single or bulk email addresses (syntax, DNS/MX, SMTP, disposable/role/catch-all detection)."},{"name":"Credits","description":"Check your credit balance and usage history."},{"name":"Webhooks","description":"Submit bounce / delivery events."}]}