Docs

POST /v1/ingest

Send any app event into the CC pipeline — errors, clicks, page hits, AI agent reports, and custom telemetry.

API

POST /v1/ingest

Send any event from your iOS, Android, React Native, or web app into the CC pipeline — errors, user interactions, page hits, device telemetry, or AI agent status reports.

Request

POST https://api.coolcoding.co.uk/v1/ingest

Headers

Header Value
Authorization Bearer cc-YOUR_API_KEY
Content-Type application/json
X-Project-ID (optional) your project identifier

Body Parameters

Parameter Type Required Default Description
app_id string Your app identifier
events array Array of event objects (see below)
platform string unknown ios · android · react-native · web
app_version string null Semver release string e.g. 2.4.1
session_id string null Client-generated session UUID
user object null User identity block (see User Object)
device object null Device/browser block (see Device Object)
location object null Location block (see Location Object)

Event Object

Every item in the events array follows this shape:

Field Type Required Description
type string See Event Types below
timestamp string ISO 8601 e.g. 2026-05-13T09:00:00Z
payload object Type-specific data (see below)
tags object Arbitrary key-value metadata
custom object Any additional params you want to track

Event Types

Error & Performance Events

crash

{
  "type": "crash",
  "timestamp": "2026-05-13T09:00:00Z",
  "payload": {
    "exception": "NullPointerException",
    "stack_trace": "at com.myapp.MainActivity.onCreate(MainActivity.java:42)",
    "fatal": true,
    "os_version": "Android 14",
    "device_model": "Pixel 8"
  }
}

anr (App Not Responding)

{
  "type": "anr",
  "timestamp": "2026-05-13T09:00:00Z",
  "payload": {
    "screen": "CheckoutScreen",
    "blocked_ms": 6200,
    "thread": "main"
  }
}

network_error

{
  "type": "network_error",
  "timestamp": "2026-05-13T09:01:00Z",
  "payload": {
    "endpoint": "/api/v1/checkout",
    "status_code": 503,
    "latency_ms": 4200,
    "network_type": "4G",
    "retries": 2
  }
}

slow_render

{
  "type": "slow_render",
  "timestamp": "2026-05-13T09:02:00Z",
  "payload": {
    "screen": "ProductDetailScreen",
    "fps": 12,
    "jank_frames": 18,
    "duration_ms": 3400
  }
}

Interaction & Engagement Events

page_hit — track any screen or page view

{
  "type": "page_hit",
  "timestamp": "2026-05-13T09:03:00Z",
  "payload": {
    "screen": "HomeScreen",
    "referrer": "PushNotification",
    "load_time_ms": 320,
    "is_first_visit": false
  }
}

click — track any tap or click interaction

{
  "type": "click",
  "timestamp": "2026-05-13T09:04:00Z",
  "payload": {
    "element_id": "btn-upgrade",
    "element_type": "button",
    "label": "Upgrade to Pro",
    "screen": "SettingsScreen",
    "x": 194,
    "y": 832
  }
}

friction — user frustration signals

{
  "type": "friction",
  "timestamp": "2026-05-13T09:05:00Z",
  "payload": {
    "signal": "rage_tap",
    "element_id": "btn-submit",
    "tap_count": 6,
    "screen": "CheckoutScreen"
  }
}

custom — send anything that doesn’t fit a standard type

{
  "type": "custom",
  "timestamp": "2026-05-13T09:06:00Z",
  "payload": {
    "name": "feature_flag_exposed",
    "flag": "new-checkout-flow",
    "variant": "B"
  },
  "custom": {
    "experiment_id": "exp_881",
    "cohort": "power-users"
  }
}

AI Agent Reports

Use agent_report to ingest status updates, findings, and fix confirmations directly from your AI agents. These appear on the CC dashboard in real time alongside the signals they relate to.

agent_report

Field Type Required Description
agent_id string Identifier for the agent sending the report
status string investigating · working_on_it · fixed · wont_fix · needs_human
summary string Human-readable status message shown on dashboard
signal_ids array CC signal IDs this report relates to
alert_ids array CC alert IDs this report relates to
root_cause string Explanation of why the error happened
fix_applied string Description of the fix that was deployed
confidence float Agent confidence score 0.0–1.0
next_action string What the agent or human should do next

Status: investigating

{
  "type": "agent_report",
  "timestamp": "2026-05-13T09:10:00Z",
  "payload": {
    "agent_id": "aa-monitor-v2",
    "status": "investigating",
    "summary": "Detected crash spike on iOS 18.1. Pulling stack traces now.",
    "signal_ids": ["sig_x9f2a1", "sig_x9f2a2"],
    "confidence": 0.85
  }
}

Status: working_on_it

{
  "type": "agent_report",
  "timestamp": "2026-05-13T09:15:00Z",
  "payload": {
    "agent_id": "aa-monitor-v2",
    "status": "working_on_it",
    "summary": "Root cause identified. Deploying patch to staging.",
    "signal_ids": ["sig_x9f2a1"],
    "root_cause": "Null reference on user.profile when account is in guest mode. Introduced in v2.4.1.",
    "confidence": 0.93,
    "next_action": "Monitor crash-free rate after staging deploy before pushing to production."
  }
}

Status: fixed

{
  "type": "agent_report",
  "timestamp": "2026-05-13T10:02:00Z",
  "payload": {
    "agent_id": "aa-monitor-v2",
    "status": "fixed",
    "summary": "Patch deployed to production. Crash-free rate restored to 99.8%.",
    "signal_ids": ["sig_x9f2a1", "sig_x9f2a2"],
    "alert_ids": ["alt_3f9c2b"],
    "root_cause": "Null reference on user.profile in guest mode. Introduced in v2.4.1.",
    "fix_applied": "Added null guard on user.profile before render. Shipped in v2.4.2.",
    "confidence": 0.99,
    "next_action": "Close alert. Watch Day-1 retention for affected cohort."
  }
}

Status: needs_human

{
  "type": "agent_report",
  "timestamp": "2026-05-13T09:20:00Z",
  "payload": {
    "agent_id": "aa-monitor-v2",
    "status": "needs_human",
    "summary": "Novel failure pattern. Unable to determine root cause automatically.",
    "signal_ids": ["sig_x9f2a3"],
    "confidence": 0.31,
    "next_action": "Engineering review required. Stack trace points to third-party SDK with no public docs."
  }
}

User Object

Include to associate events with a known user. All fields are optional — include only what you have and what your privacy policy permits.

"user": {
  "id": "usr_9f3a2c",
  "anonymous_id": "anon_7b1d4e",
  "email": "[email protected]",
  "name": "Jane Smith",
  "phone": "+447911123456",
  "age": 34,
  "gender": "female",
  "language": "en-GB",
  "plan": "pro",
  "created_at": "2025-11-01T00:00:00Z",
  "custom": {
    "company": "Acme Ltd",
    "referral_code": "REF882"
  }
}

Privacy: Only ingest personal data you have a lawful basis to process. See Data & Privacy for GDPR guidance. SP (Small Print) audits all personal data fields on ingestion.


Device Object

Captures browser or native device context automatically enriched by CC where possible.

"device": {
  "type": "mobile",
  "model": "iPhone 15 Pro",
  "os": "iOS",
  "os_version": "18.1",
  "manufacturer": "Apple",
  "screen_width": 393,
  "screen_height": 852,
  "screen_density": 3.0,
  "battery_level": 0.72,
  "low_power_mode": false,
  "network_type": "WiFi",
  "carrier": "EE",
  "browser": null,
  "browser_version": null,
  "user_agent": null
}

For web/browser events:

"device": {
  "type": "desktop",
  "browser": "Chrome",
  "browser_version": "124.0.0",
  "os": "macOS",
  "os_version": "14.4",
  "screen_width": 1440,
  "screen_height": 900,
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)..."
}

Location Object

All location fields are optional. Do not send precise GPS coordinates without explicit user consent.

"location": {
  "country": "GB",
  "country_name": "United Kingdom",
  "region": "England",
  "city": "London",
  "postcode": "EC1A",
  "timezone": "Europe/London",
  "latitude": 51.5074,
  "longitude": -0.1278,
  "accuracy_metres": 500,
  "ip_address": "82.45.123.10"
}

CC can auto-enrich country, city, and timezone from ip_address if you send the IP and omit the geo fields.


Full Example Request

curl -X POST https://api.coolcoding.co.uk/v1/ingest \
  -H "Authorization: Bearer cc-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "my-app",
    "platform": "ios",
    "app_version": "2.4.1",
    "session_id": "sess_abc123",
    "user": {
      "id": "usr_9f3a2c",
      "email": "[email protected]",
      "plan": "pro"
    },
    "device": {
      "type": "mobile",
      "model": "iPhone 15 Pro",
      "os": "iOS",
      "os_version": "18.1",
      "network_type": "WiFi"
    },
    "location": {
      "country": "GB",
      "city": "London",
      "timezone": "Europe/London",
      "ip_address": "82.45.123.10"
    },
    "events": [
      {
        "type": "page_hit",
        "timestamp": "2026-05-13T09:00:00Z",
        "payload": {
          "screen": "CheckoutScreen",
          "load_time_ms": 280
        }
      },
      {
        "type": "click",
        "timestamp": "2026-05-13T09:00:05Z",
        "payload": {
          "element_id": "btn-pay",
          "label": "Pay Now",
          "screen": "CheckoutScreen"
        }
      },
      {
        "type": "crash",
        "timestamp": "2026-05-13T09:00:06Z",
        "payload": {
          "exception": "NullPointerException",
          "stack_trace": "at com.myapp.Main:42",
          "fatal": true
        }
      }
    ]
  }'

Python:

import requests

response = requests.post(
    "https://api.coolcoding.co.uk/v1/ingest",
    headers={"Authorization": "Bearer cc-YOUR_API_KEY"},
    json={
        "app_id": "my-app",
        "platform": "ios",
        "app_version": "2.4.1",
        "session_id": "sess_abc123",
        "user": {"id": "usr_9f3a2c", "plan": "pro"},
        "device": {"model": "iPhone 15 Pro", "os_version": "18.1"},
        "location": {"country": "GB", "city": "London"},
        "events": [
            {
                "type": "page_hit",
                "timestamp": "2026-05-13T09:00:00Z",
                "payload": {"screen": "CheckoutScreen", "load_time_ms": 280}
            }
        ]
    }
)
print(response.json())

JavaScript:

const response = await fetch("https://api.coolcoding.co.uk/v1/ingest", {
  method: "POST",
  headers: {
    "Authorization": "Bearer cc-YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    app_id: "my-app",
    platform: "ios",
    app_version: "2.4.1",
    session_id: "sess_abc123",
    user: { id: "usr_9f3a2c", plan: "pro" },
    device: { model: "iPhone 15 Pro", os_version: "18.1" },
    location: { country: "GB", city: "London" },
    events: [{
      type: "page_hit",
      timestamp: new Date().toISOString(),
      payload: { screen: "CheckoutScreen", load_time_ms: 280 }
    }]
  })
});
console.log(await response.json());

Response

{
  "accepted": 3,
  "rejected": 0,
  "session_id": "sess_abc123",
  "request_id": "req_7f3a9c",
  "usage": { "credits": 1 }
}
Field Type Description
accepted integer Events successfully ingested
rejected integer Events rejected — malformed or missing required fields
session_id string Echo of the session ID
request_id string Share with support to debug specific requests
usage.credits integer Credits consumed by this request

Error Responses

Code Meaning
400 Bad Request — missing or invalid parameters
401 Unauthorized — API key missing or invalid
429 Too Many Requests — rate limit exceeded
432 Plan limit exceeded — upgrade your plan
500 Internal Server Error

429 example:

{
  "error": "Rate limit exceeded. Please reduce request frequency.",
  "retry_after": 60
}

Implement retry logic that respects the retry-after header value.

Expert help

Need help tracking this in your app?

Our team sets up analytics pipelines for mobile and web teams every day. Talk to us and get your first events flowing in under an hour.

Talk to an expert