Skip to content

curl examples — Ludex ingestion

Replace placeholders before running:

Placeholder Meaning
BASE_URL https://ingest.ludexstudio.com (or the URL Ludex provides)
API_KEY Bearer token from Ludex (scopes must include the endpoint you call)
PROJECT_ID Must match the credential’s project_id
ENVIRONMENT Must match the credential’s environment_id (same string the platform stores on the key)

All routes are under /v1. Successful accepts return 202.


Single event — POST /v1/ingest/event

Requires scope ingest:events.

curl -sS -X POST "${BASE_URL}/v1/ingest/event" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "'"${PROJECT_ID}"'",
    "environment": "'"${ENVIRONMENT}"'",
    "event": {
      "event_name": "level_complete",
      "timestamp": "2026-04-13T12:00:00.000Z",
      "player_id": "player-uuid-123",
      "session_id": "session-abc",
      "platform": "Windows",
      "build_version": "1.0.0",
      "game_version": "0.9.2",
      "event_id": "550e8400-e29b-41d4-a716-446655440000",
      "properties": {
        "level": 3,
        "score": 1200
      },
      "sdk": { "name": "curl-example", "version": "1.0.0" }
    }
  }'

Omit event_id to let the server generate a UUID (recommended for one-off tests; for production clients, prefer a stable client-generated id per logical event for retries).


Single event with optional headers

  • Idempotency-Key — replays within the server TTL return the cached 202 body (default cache TTL is 300 seconds per process).
  • X-Correlation-Id — propagated for traceability.
  • X-Request-Id — used in structured logs when present.
curl -sS -X POST "${BASE_URL}/v1/ingest/event" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-first-event-$(date +%s)" \
  -H "X-Correlation-Id: corr-demo-001" \
  -H "X-Request-Id: client-req-001" \
  -d '{
    "project_id": "'"${PROJECT_ID}"'",
    "environment": "'"${ENVIRONMENT}"'",
    "event": {
      "event_name": "tutorial_started",
      "timestamp": "2026-04-13T12:00:00.000Z",
      "properties": {}
    }
  }'

Batch — POST /v1/ingest/batch

Requires scope ingest:batch. Maximum 5000 events per request (default server limit).

curl -sS -X POST "${BASE_URL}/v1/ingest/batch" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "'"${PROJECT_ID}"'",
    "environment": "'"${ENVIRONMENT}"'",
    "events": [
      {
        "event_name": "match_started",
        "timestamp": "2026-04-13T12:00:01.000Z",
        "session_id": "sess-1",
        "properties": { "mode": "ranked" }
      },
      {
        "event_name": "match_ended",
        "timestamp": "2026-04-13T12:15:00.000Z",
        "session_id": "sess-1",
        "properties": { "duration_sec": 900, "result": "win" }
      }
    ]
  }'

Batch with idempotency

Use the same key only when you intend the entire batch to be treated as one logical submit (cached response applies to that key + credential scope).

curl -sS -X POST "${BASE_URL}/v1/ingest/batch" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: nightly-export-batch-2026-04-13" \
  -d @batch-payload.json

Put the JSON body in batch-payload.json with the same project_id / environment / events shape as above.


Inspecting HTTP status

Add -w "\n%{http_code}\n" to print the status line after the body:

curl -sS -o body.json -w "%{http_code}\n" -X POST "${BASE_URL}/v1/ingest/event" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"project_id":"'"${PROJECT_ID}"'","environment":"'"${ENVIRONMENT}"'","event":{"event_name":"ping","timestamp":"2026-04-13T12:00:00Z","properties":{}}}' \
&& cat body.json

Expected: 202 with a JSON body describing acceptance (see contract-reference.md).