Quickstart
Upload a CSV, create a job, start a run, and export results with raw HTTP calls to the Everyn API.
This quickstart shows the shortest raw HTTP path through the Everyn API: upload a CSV, create a reusable job, start a run, and export CSV results.
The API is raw HTTP. The TypeScript and Python examples below use fetch and requests; they are not SDK examples.
Help me complete the Everyn API quickstart.
Read:
https://www.geteveryn.com/docs/api/agent-quickstart.md
Follow the four-step quickstart: upload a CSV, create a job, start a run, and
export results. Start by asking whether I want to use the sample CSV below or my own CSV.
If you need an Everyn API key, ask me for it.Before you start
You need:
curlandjqfor the canonical copy-paste path.- Optional: Node.js 18 or newer for the TypeScript
fetchexamples. - Optional: Python 3 with
requestsinstalled for the Python examples.
Create the sample CSV locally:
cat > leads.csv <<'CSV'
company,website,industry,employee_count,region,notes
Northstar Robotics,https://northstar.example,Manufacturing,420,North America,Looking for automated QA on production lines
Lumen Health,https://lumen.example,Healthcare,180,Europe,Expanding clinical operations across two countries
Atlas Freight,https://atlas.example,Logistics,760,North America,Interested in lane optimization and shipment visibility
CSVFor the copy-paste commands, set shell variables for this terminal session, or adapt the snippets to your preferred secret-management setup.
export EVERYN_BASE_URL="https://api.geteveryn.com"
export EVERYN_API_KEY="sk-everyn-..."The TypeScript and Python snippets assume the same environment variables are available in the process.
1. Upload a CSV
Create a dataset upload with an idempotency key. Reuse the same key only when retrying the same request after a timeout.
UPLOAD_RESPONSE=$(curl -sS -X POST "$EVERYN_BASE_URL/v1/dataset-uploads" \
-H "Authorization: Bearer $EVERYN_API_KEY" \
-H "Idempotency-Key: upload-leads-001" \
-F "sourceType=csv" \
-F "sourceName=leads.csv" \
-F 'metadata={"purpose":"quickstart"}' \
-F "file=@./leads.csv;type=text/csv")
echo "$UPLOAD_RESPONSE" | jq
UPLOAD_ID=$(echo "$UPLOAD_RESPONSE" | jq -r '.id')Expected successful upload response excerpt:
{
"id": "upl_...",
"status": "processing",
"datasetId": null,
"failure": null
}Wait for intake to finish. This loop exits on completed, fails fast on failed or expired, and times out after about one minute.
DATASET_ID=""
for attempt in $(seq 1 30); do
UPLOAD_RESPONSE=$(curl -sS "$EVERYN_BASE_URL/v1/dataset-uploads/$UPLOAD_ID" \
-H "Authorization: Bearer $EVERYN_API_KEY")
STATUS=$(echo "$UPLOAD_RESPONSE" | jq -r '.status')
if [ "$STATUS" = "completed" ]; then
DATASET_ID=$(echo "$UPLOAD_RESPONSE" | jq -r '.datasetId')
break
fi
if [ "$STATUS" = "failed" ] || [ "$STATUS" = "expired" ]; then
echo "$UPLOAD_RESPONSE" | jq '.failure'
exit 1
fi
sleep 2
done
if [ -z "$DATASET_ID" ]; then
echo "Timed out waiting for dataset upload $UPLOAD_ID"
exit 1
fi
echo "DATASET_ID=$DATASET_ID"Expected completed upload excerpt:
{
"id": "upl_...",
"status": "completed",
"datasetId": "ds_...",
"failure": null
}If the upload fails, inspect failure.code, failure.docsUrl, and failure.fieldErrors. See Dataset uploads and the Dataset Uploads API reference.
2. Create a job
A job is the reusable work contract for future runs. This example scores each company for fit against a target customer profile.
JOB_SPEC_RESPONSE=$(curl -sS -X POST "$EVERYN_BASE_URL/v1/job-specs" \
-H "Authorization: Bearer $EVERYN_API_KEY" \
-H "Idempotency-Key: job-lead-fit-001" \
-H "Content-Type: application/json" \
--data '{
"name": "Lead fit scoring",
"description": "Score leads against the target ICP.",
"mode": "add_columns",
"prompt": "Score each company for ICP fit. Return a score, reason, and confidence.",
"model": "openai:gpt-5.4-mini",
"outputSchema": {
"columns": [
{
"name": "fit_score",
"type": "integer",
"description": "Score from 1 to 5.",
"minimum": 1,
"maximum": 5
},
{
"name": "fit_reason",
"type": "string",
"description": "Concise explanation."
},
{
"name": "confidence",
"type": "number",
"description": "Confidence from 0 to 1.",
"minimum": 0,
"maximum": 1
}
]
}
}')
echo "$JOB_SPEC_RESPONSE" | jq
JOB_SPEC_ID=$(echo "$JOB_SPEC_RESPONSE" | jq -r '.id')Expected response excerpt:
{
"id": "js_...",
"name": "Lead fit scoring",
"currentVersionId": "jsv_...",
"version": {
"mode": "add_columns",
"model": "openai:gpt-5.4-mini",
"outputSchema": {
"columns": [
{ "name": "fit_score" },
{ "name": "fit_reason" },
{ "name": "confidence" }
]
}
}
}If model validation fails, pick a runnable model from /v1/models. See Job specs and the Job Specs API reference.
3. Start a run
Create a limited run against the uploaded dataset and job, then start it. The sample CSV has three rows, and the explicit limit scope keeps this path bounded when you swap in your own CSV.
RUN_RESPONSE=$(curl -sS -X POST "$EVERYN_BASE_URL/v1/runs" \
-H "Authorization: Bearer $EVERYN_API_KEY" \
-H "Idempotency-Key: run-leads-001" \
-H "Content-Type: application/json" \
--data "{
\"datasetId\": \"$DATASET_ID\",
\"jobSpecId\": \"$JOB_SPEC_ID\",
\"scope\": { \"type\": \"limit\", \"count\": 3 }
}")
echo "$RUN_RESPONSE" | jq
RUN_ID=$(echo "$RUN_RESPONSE" | jq -r '.id')
curl -sS -X POST "$EVERYN_BASE_URL/v1/runs/$RUN_ID/start" \
-H "Authorization: Bearer $EVERYN_API_KEY" | jqExpected run response excerpt:
{
"id": "run_...",
"state": "queued",
"rowCounts": {
"total": 3,
"processed": 0,
"failed": 0
}
}Repeating the start request for a queued or running run returns the existing run and must not submit duplicate runner work.
Wait for the run to reach a terminal state:
TERMINAL_STATE=""
for attempt in $(seq 1 60); do
RUN_RESPONSE=$(curl -sS "$EVERYN_BASE_URL/v1/runs/$RUN_ID" \
-H "Authorization: Bearer $EVERYN_API_KEY")
STATE=$(echo "$RUN_RESPONSE" | jq -r '.state')
case "$STATE" in
succeeded|completed_with_flags|failed|canceled)
TERMINAL_STATE="$STATE"
break
;;
esac
sleep 2
done
if [ -z "$TERMINAL_STATE" ]; then
echo "Timed out waiting for run $RUN_ID"
exit 1
fi
echo "$RUN_RESPONSE" | jq '{id, state, rowCounts}'Use succeeded as the clean path. Use completed_with_flags as the inspect-and-decide path. Treat failed and canceled as stop-and-debug states. See Runs and the Runs API reference for recovery.
Before exporting, inspect the sample result:
curl -sS "$EVERYN_BASE_URL/v1/runs/$RUN_ID/rows?limit=50" \
-H "Authorization: Bearer $EVERYN_API_KEY" | jq
curl -sS "$EVERYN_BASE_URL/v1/runs/$RUN_ID/events?limit=50" \
-H "Authorization: Bearer $EVERYN_API_KEY" | jq
curl -sS "$EVERYN_BASE_URL/v1/runs/$RUN_ID/outputs?limit=50" \
-H "Authorization: Bearer $EVERYN_API_KEY" | jq
curl -sS "$EVERYN_BASE_URL/v1/runs/$RUN_ID/failures?limit=50" \
-H "Authorization: Bearer $EVERYN_API_KEY" | jq
echo "$RUN_RESPONSE" | jq '{state, rowCounts, modelUsage}'Review checklist:
- The run is terminal:
succeededorcompleted_with_flags. rowCounts.processedmatches the attempted sample size, which is3in this guide.- Generated fields match the
outputSchema:fit_score,fit_reason, andconfidence. - Any failed or flagged rows have understandable
failure.phase,failure.code,failure.message,failure.retryable,failure.userActionable, andfailure.recommendedAction. - The prompt, model, schema, outputs, events, and usage are good enough to act on.
Export only after this checklist passes. Retry or revise instead of exporting when the sample exposes execution problems or product-quality issues.
4. Export results
Create a self-starting CSV export from the run.
EXPORT_RESPONSE=$(curl -sS -X POST "$EVERYN_BASE_URL/v1/runs/$RUN_ID/exports" \
-H "Authorization: Bearer $EVERYN_API_KEY" \
-H "Idempotency-Key: export-results-001" \
-H "Content-Type: application/json" \
--data '{ "type": "generated_outputs", "format": "csv", "fileName": "results.csv" }')
echo "$EXPORT_RESPONSE" | jq
EXPORT_ID=$(echo "$EXPORT_RESPONSE" | jq -r '.id')Expected export response excerpt:
{
"id": "exp_...",
"status": "ready",
"downloadReady": true,
"downloadUrl": "/v1/exports/exp_.../download",
"failure": null
}If the export is not immediately ready, poll it before downloading:
for attempt in $(seq 1 30); do
EXPORT_RESPONSE=$(curl -sS "$EVERYN_BASE_URL/v1/exports/$EXPORT_ID" \
-H "Authorization: Bearer $EVERYN_API_KEY")
STATUS=$(echo "$EXPORT_RESPONSE" | jq -r '.status')
if [ "$STATUS" = "ready" ]; then
break
fi
if [ "$STATUS" = "failed" ] || [ "$STATUS" = "expired" ]; then
echo "$EXPORT_RESPONSE" | jq '.failure'
exit 1
fi
sleep 2
done
if [ "$STATUS" != "ready" ]; then
echo "Timed out waiting for export $EXPORT_ID"
exit 1
fi
curl -sS "$EVERYN_BASE_URL/v1/exports/$EXPORT_ID/download" \
-H "Authorization: Bearer $EVERYN_API_KEY" \
-o results.csvSee Exports API reference for export types and download behavior.
Troubleshooting
| Symptom | Where to look |
|---|---|
401 or 403 | Authentication and the key scopes on the machine key. |
| Duplicate create after a timeout | Idempotency and the original idempotency key. |
| CSV failed to process | Dataset uploads and the failure.docsUrl on the upload. |
| Job spec rejected | Job specs, /v1/models, and validation errors. |
| Run failed or rows failed | Runs, API errors, and Runs API reference. |
| Lists stop after one page | Pagination. |
Next steps
- Read Concepts for the durable object model.
- Read Datasets, Job specs, and Runs for product behavior.
- Use the generated API reference when implementing endpoint-level clients.