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.