Creates a new bulk CSV validation job and returns a presigned upload URL.
Use this endpoint when you need to validate a large number of email addresses stored in a CSV file. The workflow is:
- Call this endpoint to create a job and receive an upload URL
- Upload your CSV file to the returned
uploadUrlusing an HTTPPUTrequest withContent-Type: text/csv - Poll the job status endpoint until the job is complete
- Download the results CSV
Upload Instructions
The uploadUrl in the response is a presigned URL that accepts your CSV file via HTTP PUT. You must include the Content-Type: text/csv header.
curl -X PUT "<uploadUrl>" \
-H "Content-Type: text/csv" \
--data-binary @your-file.csv
The upload URL expires after 5 minutes. If it expires, create a new job.
CSV File Requirements
- Maximum file size: 100 MB
- Format: CSV with one email address per row in the specified column
- Delimiters: Comma (
,), semicolon (;), tab, or pipe (|) — automatically detected - Headers: Optional — automatically detected. If your file has a header row, it will be skipped during validation
- Email column: Specify which column (zero-indexed) contains the email addresses using the
emailColumnparameter
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
Creates a new bulk CSV validation job and returns a presigned upload URL.
Important: This endpoint only creates the job. You must then upload your CSV file to the returned
uploadUrl— see Uploading Your CSV File below. The job will not start processing until the file is uploaded.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
emailColumn | integer | Yes | Zero-indexed column number containing email addresses. Use 0 for the first column, 1 for the second, and so on. Maximum value is 1000. |
fileName | string | No | A name for your CSV file (must end in .csv, max 255 characters). This controls the name of your results file — for example, contacts.csv produces a results file named contacts_processed_by_allegrow.csv. If not provided, the results file is named using the job ID. |
callbackUrl | string | No | A webhook URL. Allegrow will send a POST request to this URL when the job completes, so you don't need to poll for status. See the Completion Webhook section for payload details. |
Example request:
curl -X POST https://api.allegrow.co/v1/email/validate-file \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emailColumn": 0,
"fileName": "contacts.csv",
"callbackUrl": "https://your-app.com/webhooks/validation-complete"
}'Response
A successful request returns HTTP 202 with the following fields:
| Field | Description |
|---|---|
jobId | Unique identifier for your job — use this in all subsequent requests |
status | Will be awaiting_upload — the job is waiting for your CSV file |
uploadUrl | Presigned URL where you upload your CSV file (see below) |
uploadExpiresIn | Seconds until the upload URL expires (300 = 5 minutes) |
Error Responses
All errors return a JSON body with an error field:
{
"error": "emailColumn is required"
}| Status | Error | Cause |
|---|---|---|
| 400 | emailColumn is required | Missing emailColumn field |
| 400 | emailColumn must be a non-negative integer | emailColumn is not a valid integer or is negative |
| 400 | fileName must be a non-empty string | Empty fileName provided |
| 400 | fileName must be 255 characters or less | fileName exceeds 255 characters |
| 400 | fileName must end in .csv | fileName does not have a .csv extension |
| 400 | Invalid callbackUrl | callbackUrl is not a valid URL |
| 429 | Concurrent job limit reached. Complete or wait for existing jobs before creating new ones. | You already have 5 active jobs (includes a Retry-After: 60 header) |
Uploading Your CSV File
After creating the job, upload your CSV file to the uploadUrl from the response. This is a direct file upload to a presigned URL — no API key is needed for this request.
curl -X PUT "<uploadUrl>" \
-H "Content-Type: text/csv" \
--data-binary @your-file.csvPython:
import requests
with open("your-file.csv", "rb") as f:
response = requests.put(upload_url, data=f, headers={"Content-Type": "text/csv"})JavaScript:
const fs = require('fs');
const fileBuffer = fs.readFileSync('your-file.csv');
await fetch(uploadUrl, {
method: 'PUT',
headers: { 'Content-Type': 'text/csv' },
body: fileBuffer,
});- Method:
PUT(not POST) - Header:
Content-Type: text/csv(required) - Body: Your raw CSV file contents
- Response: An HTTP
200with no body indicates a successful upload
Note: The upload URL expires after 5 minutes. If it expires (HTTP
403), create a new job to get a fresh upload URL.
CSV File Requirements
- Maximum file size: 100 MB
- Delimiters: Comma (
,), semicolon (;), tab, or pipe (|) — automatically detected - Headers: Optional — automatically detected and skipped if present
- Email column: Specified by the zero-indexed
emailColumnparameter (e.g.,0for the first column,1for the second)
Concurrency Limit
You can have up to 5 active jobs running concurrently per company. Active jobs include those with status awaiting_upload or processing. If you exceed this limit, you'll receive a 429 response with a Retry-After header.
Next Steps
Once your file is uploaded, processing starts automatically. Use the Get CSV Job Status endpoint to track progress, then Download CSV Job Results when complete.