Upload Emails
Submit a list of emails for validation. Accepts either a multipart upload (CSV/Excel file) or a JSON body with an emails list. The endpoint creates a job, queues it for processing, and returns a job_id you can use to poll status, fetch records, and download results.
Endpoint
Method: POST
Path: /email-validation/jobs/upload/
Full URL: https://app.ecoreservice.com/backend/api/v1/email-validation/jobs/upload/
Auth: Authorization: Token YOUR_API_TOKEN — see Authentication
Cost: Per-email rate, charged on upload — refunded for any email that does not come back Valid. See Credit Costs.
Option A — JSON Body
| Field | Required | Notes |
|---|---|---|
emails | Yes | Non-empty list of email strings. Any malformed address rejects the entire request. |
list_name | No | Display label. Defaults to "API Upload" when omitted. |
curl -X POST \
"https://app.ecoreservice.com/backend/api/v1/email-validation/jobs/upload/" \
-H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"emails": ["john@acme.com", "jane@example.com"],
"list_name": "Q1 Leads"
}'
Option B — CSV / Excel Upload
| Form field | Required | Notes |
|---|---|---|
csv_file | Yes | A .csv, .xls, .xlsx, or .xlsm file. Must include an email column named email, e-mail, email_address, or email address (case-insensitive). Empty cells are skipped. |
list_name | No | Display label. Defaults to the uploaded filename. |
curl -X POST \
"https://app.ecoreservice.com/backend/api/v1/email-validation/jobs/upload/" \
-H "Authorization: Token YOUR_API_TOKEN" \
-F "csv_file=@/path/to/emails.csv" \
-F "list_name=Q1 Leads"
The form field file (instead of csv_file) is also accepted as a fallback name.
Request Behavior
- Each email is validated for format; invalid format →
400with per-index errors. - After validation: emails are stripped, lowercased, and deduplicated.
- Wallet balance is pre-checked against the cost (
<email count> × cost_per_email). Insufficient →402.
Successful Response — 201 Created
{
"job_id": 42,
"uuid": "f8a1c3e5-9b2d-4e6f-a8c1-0d3e5f7a9b2d",
"list_name": "Q1 Leads",
"total_records": 2,
"status": "Uploading"
}
| Field | Type | Description |
|---|---|---|
job_id | integer | Use this in subsequent endpoint paths (Status, Records, Download) |
uuid | string | UUID4 — useful for deduping client-side |
list_name | string | Display label assigned to the job |
total_records | integer | Count of unique, format-valid emails accepted |
status | string | "Uploading" immediately on creation — poll Job Status for progress |
Error Responses
| HTTP | Body | When |
|---|---|---|
| 400 | {"detail": "Provide either a 'csv_file' upload or an 'emails' list."} | Upload had neither a file nor a JSON emails list |
| 400 | {"csv_file": "Unsupported file format. Upload CSV or Excel."} | File extension wasn't .csv, .xls, .xlsx, or .xlsm |
| 400 | {"csv_file": "No email column found. Your CSV must include a column named 'email'."} | Couldn't detect an email column |
| 400 | {"emails": {"<index>": ["Not a valid email address."]}} | One or more emails failed format validation |
| 400 | {"emails": ["No valid email addresses found."]} | All entries deduped to nothing |
| 401 | {"detail": "Invalid token."} | Missing or invalid token |
| 402 | {"error": "Insufficient credits. You need N credits but have M.", "required": N, "balance": M} | Wallet balance too low for the upfront charge |
See Error Codes for the full list.
Next Step
Use Job Status to poll the job, then Job Records or Download Results once it reaches Processed.