API

Quickstart

Lade eine CSV hoch, nutze einen von einem Menschen erstellten Job, starte einen Run und exportiere Ergebnisse mit Raw-HTTP-Calls an die Everyn-API.

Dieser Quickstart zeigt den kürzesten Maschinen-API-Pfad durch Everyn: CSV hochladen, einen von einem Menschen erstellten wiederverwendbaren Job nutzen, Run starten und CSV-Ergebnisse exportieren.

Die API ist Raw HTTP. Die TypeScript- und Python-Beispiele unten nutzen fetch und requests; sie sind keine SDK-Beispiele.

Agent prompt
Hilf mir, den Everyn API Quickstart abzuschließen.

Lies:
https://www.everyn.ai/de/docs/api/agent-quickstart.md

Folge dem vierstufigen Quickstart: CSV hochladen, mich einen Job über meine
Browser Session oder Inbound MCP nach OAuth-Consent erstellen lassen, Run mit
einem Maschinen-Key starten und Ergebnisse exportieren. Frage zuerst, ob ich die
Sample-CSV unten oder meine eigene CSV nutzen möchte. Frage mich nach der Job-ID;
erstelle niemals einen Job mit einem Maschinen-Key.

Voraussetzungen

Du brauchst:

  • curl und jq für den kanonischen Copy-paste-Pfad.
  • Optional: Node.js 18 oder neuer für die TypeScript-fetch-Beispiele.
  • Optional: Python 3 mit installiertem requests für die Python-Beispiele.

Erstelle die Sample-CSV lokal:

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
CSV

Setze für die Copy-paste-Commands Shell-Variablen für diese Terminal-Session oder passe die Snippets an dein bevorzugtes Secret-Management an.

export EVERYN_BASE_URL="https://api.everyn.ai"
export EVERYN_API_KEY="sk-everyn-..."

Die TypeScript- und Python-Snippets erwarten dieselben Umgebungsvariablen im Prozess.

1. CSV hochladen

Erstelle einen Dataset Upload mit einem Idempotency Key. Verwende denselben Key nur dann erneut, wenn du dieselbe Anfrage nach einem Timeout wiederholst.

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')

Erwarteter erfolgreicher Upload-Response-Ausschnitt:

{
  "id": "upl_...",
  "status": "processing",
  "datasetId": null,
  "failure": null
}

Warte, bis Intake abgeschlossen ist. Diese Schleife beendet sich bei completed, bricht bei failed oder expired sofort ab und timed nach ungefähr einer Minute aus.

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"

Erwarteter abgeschlossener Upload-Ausschnitt:

{
  "id": "upl_...",
  "status": "completed",
  "datasetId": "ds_...",
  "failure": null
}

Wenn der Upload fehlschlägt, prüfe failure.code, failure.docsUrl und failure.fieldErrors. Siehe Dataset Uploads und die Dataset Uploads API-Referenz.

2. Von einem Menschen erstellten Job verwenden

Ein Job ist der wiederverwendbare Arbeitsvertrag für zukünftige Runs. Lass einen verifizierten Menschen „Lead fit scoring“ über eine authentifizierte Browser Session oder Inbound MCP nach Human-OAuth-Consent erstellen. Der Job soll mit openai:gpt-6-luna für jede Company fit_score, fit_reason und confidence zurückgeben. Nur der aktuelle menschliche Eigentümer darf ihn bearbeiten; ein Teammate darf ihn forken.

Kopiere die zurückgegebene Job-ID in deine Shell. Ein Maschinen-API-Key kann Jobs weder erstellen, bearbeiten, forken noch freigeben, selbst mit dem alten Scope job_specs:write. Mit job_specs:read kann er einen vorhandenen Job lesen und mit runs:write ausführen. Kopiere keine Browser Session in ein Skript und erstelle keinen persönlichen API Token, um die menschliche Autorisierung zu umgehen.

export JOB_SPEC_ID="js_..."
export EVERYN_JOB_SPEC_ID="$JOB_SPEC_ID"

curl -fsS "$EVERYN_BASE_URL/v1/job-specs/$JOB_SPEC_ID" \
  -H "Authorization: Bearer $EVERYN_API_KEY" |
  jq -e '{id, name, owner, canRun} | select(.owner != null and .canRun)'

Die TypeScript- und Python-Run-Beispiele in Schritt 3 lesen EVERYN_JOB_SPEC_ID aus ihrer Prozessumgebung. Die Antwort sollte einen menschlichen owner und canRun: true zeigen. Falls das Model geändert werden muss, kann der menschliche Eigentümer den Job bearbeiten; ein Teammate kann ihn forken. Siehe Job Specs und die Job Specs API-Referenz.

3. Run starten

Erstelle einen begrenzten Run gegen das hochgeladene Dataset und den Job, und starte ihn dann. Die Sample-CSV hat drei Rows, und der explizite limit-Scope hält diesen Pfad begrenzt, wenn du später deine eigene CSV einsetzt.

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" | jq

Erwarteter Run-Response-Ausschnitt:

{
  "id": "run_...",
  "state": "queued",
  "rowCounts": {
    "total": 3,
    "processed": 0,
    "failed": 0
  }
}

Wenn Start für einen queued oder running Run wiederholt wird, kommt der bestehende Run zurück und es darf keine doppelte Runner-Arbeit entstehen.

Warte, bis der Run einen terminalen Zustand erreicht:

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}'

Nutze succeeded als sauberen Pfad. Nutze completed_with_flags als Inspect-and-decide-Pfad. Behandle failed und canceled als Stop-and-debug-Zustände. Siehe Runs und die Runs API-Referenz für Recovery.

Prüfe vor dem Export das Sample-Ergebnis:

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-Checkliste:

  • Der Run ist terminal: succeeded oder completed_with_flags.
  • rowCounts.processed entspricht der versuchten Sample-Größe, in diesem Guide also 3.
  • Generierte Felder passen zum outputSchema: fit_score, fit_reason und confidence.
  • Fehlgeschlagene oder markierte Rows haben verständliche Werte für failure.phase, failure.code, failure.message, failure.retryable, failure.userActionable und failure.recommendedAction.
  • Prompt, Model, Schema, Outputs, Events und Usage sind gut genug, um darauf zu handeln.

Exportiere erst, wenn diese Checkliste passt. Retrye oder revidiere statt zu exportieren, wenn das Sample Ausführungsprobleme oder Qualitätsprobleme zeigt.

4. Ergebnisse exportieren

Erstelle einen self-starting CSV-Export aus dem 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')

Erwarteter Export-Response-Ausschnitt:

{
  "id": "exp_...",
  "status": "ready",
  "downloadReady": true,
  "downloadUrl": "/v1/exports/exp_.../download",
  "failure": null
}

Wenn der Export nicht sofort ready ist, polle ihn vor dem Download:

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.csv

Siehe Exports API-Referenz für Exporttypen und Download-Verhalten.

Troubleshooting

SymptomWo nachsehen
401 oder 403Authentifizierung und Scopes des Machine Keys.
Doppelte Erstellung nach TimeoutIdempotenz und ursprünglicher Idempotency Key.
CSV konnte nicht verarbeitet werdenDataset Uploads und failure.docsUrl auf dem Upload.
Job Spec wurde abgelehntJob Specs, /v1/models und Validation Errors.
Run oder Rows sind fehlgeschlagenRuns, API-Fehler und Runs API-Referenz.
Listen stoppen nach einer SeitePagination.

Nächste Schritte