Validate (Pre-flight)
Email Generation takes a CSV of contacts and finds a verified email for each. The flow is: validate → upload → poll → records → download.
1. validate → show "N contacts • X credits • can_afford?" confirm dialog
2. upload → get job_id, status = "Uploading"
3. poll job → every 3–5s until status = "Processed" (or "Failed")
4. records → paginated table of generated emails
5. download → CSV export
These are the in-app, JWT-authenticated endpoints used by the eCore frontend — the same auth used for every other in-app /api/v1 call. Send Authorization: Bearer <JWT>. They are distinct from the external API-token endpoints documented elsewhere in this reference.
Every /api/v1 response is wrapped as { "success": true, "message": "...", "code": 200, ...payload } — the payload fields shown on these pages sit alongside success / message / code (spread into the same object, not nested). The CSV download endpoint streams a file and is the only one not wrapped.
Endpoint
Method: POST
Path: /email-generation/validate/
Full URL: https://backend.ecoreservice.com/api/v1/email-generation/validate/
Auth: Authorization: Bearer <JWT>
Content-Type: application/json (JSON array) or multipart/form-data (file upload)
Use it to preview cost before committing to a run.
Request
Submit contacts either as a file or as a JSON array.
Option A — File upload (multipart/form-data)
| Field | Type | Required | Notes |
|---|---|---|---|
csv_file | file | Yes | CSV/Excel of contacts to generate emails for |
Option B — JSON body (application/json)
A JSON array of contact objects:
[
{ "first_name": "Jane", "last_name": "Doe", "company_domain": "acme.com" },
{ "first_name": "John", "last_name": "Roe", "company_domain": "globex.com", "ec_id": "1002" }
]
Contact fields
Case- and spacing-tolerant (CSV columns / JSON keys). Required: first_name, last_name, company_domain. Optional: matched_company_domain, ec_id. Rows missing first or last name are dropped.
Response Payload
{ "total_records": 4000, "credits_required": 20000, "current_balance": 25000, "can_afford": true }
| Field | Type | Description |
|---|---|---|
total_records | integer | Valid rows detected in the file |
credits_required | integer | total_records × 5 (5 credits per contact) |
current_balance | integer | Your wallet balance |
can_afford | boolean | true when the balance covers the cost |
If can_afford is false, block the upload and prompt the user to buy credits.
Credits
5 credits per contact, charged upfront when the job starts, and refunded for any contact with no email found. See Credit Costs.
Next Step
If affordable, Upload the same file to start a job.