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, andtimezonefromip_addressif 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.
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