{"openapi":"3.1.0","info":{"title":"RevenueUI collector API","version":"1.0.0","description":"Signed server-to-server event ingestion used by RevenueUI infrastructure. Website browsers should use the RevenueUI tracking script instead of calling this endpoint directly."},"servers":[{"url":"https://api.revenueui.app"}],"paths":{"/api/collect":{"post":{"operationId":"collectTrackingEvents","summary":"Collect a batch of tracking events","security":[{"collectorSignature":[]}],"parameters":[{"name":"X-RevenueUI-Key-Id","in":"header","required":true,"schema":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$"}},{"name":"X-RevenueUI-Timestamp","in":"header","required":true,"description":"Ten-digit Unix timestamp used in the HMAC input.","schema":{"type":"string","pattern":"^[0-9]{10}$"}},{"name":"X-RevenueUI-Signature","in":"header","required":true,"description":"Lowercase hexadecimal HMAC-SHA256 of `{timestamp}.{raw request body}`.","schema":{"type":"string","pattern":"^[a-f0-9]{64}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventBatch"}}}},"responses":{"200":{"description":"Batch stored.","content":{"application/json":{"schema":{"type":"object","required":["accepted","stored"],"properties":{"accepted":{"type":"integer","minimum":1},"stored":{"type":"integer","minimum":0}}}}}},"401":{"description":"Signature is invalid or expired."},"409":{"description":"The signed request was already received."},"422":{"description":"The batch does not match the event contract."}}}}},"components":{"securitySchemes":{"collectorSignature":{"type":"apiKey","in":"header","name":"X-RevenueUI-Signature","description":"Internal HMAC authentication. The key identifier and Unix timestamp headers are also required."}},"schemas":{"EventBatch":{"type":"object","additionalProperties":false,"required":["events"],"properties":{"events":{"type":"array","minItems":1,"maxItems":20,"items":{"$ref":"#/components/schemas/TrackingEvent"}}}},"TrackingEvent":{"type":"object","additionalProperties":false,"required":["public_key","origin","event_id","visitor_id","session_id","event_name","identity_mode","path","referrer_host","referrer_path","utm_source","utm_medium","utm_campaign","page_view_event_id","engagement_time_ms","occurred_at","collector_received_at","consent_state","consent_observed_at","consent_source","browser","operating_system","device_type","country_code"],"properties":{"public_key":{"type":"string","pattern":"^[A-Za-z0-9]{32}$"},"origin":{"type":"string","format":"uri","maxLength":2048},"event_id":{"type":"string","format":"uuid"},"visitor_id":{"type":["string","null"],"format":"uuid"},"session_id":{"type":"string","format":"uuid"},"event_name":{"enum":["page_view","page_engagement"]},"identity_mode":{"enum":["first_party","cookieless"]},"path":{"type":"string","maxLength":2048,"pattern":"^/[^?#]*$"},"referrer_host":{"type":["string","null"],"maxLength":253},"referrer_path":{"type":["string","null"],"maxLength":2048},"utm_source":{"type":["string","null"],"maxLength":100},"utm_medium":{"type":["string","null"],"maxLength":100},"utm_campaign":{"type":["string","null"],"maxLength":100},"page_view_event_id":{"type":["string","null"],"format":"uuid"},"engagement_time_ms":{"type":["integer","null"],"minimum":1,"maximum":86400000},"occurred_at":{"type":"string","format":"date-time"},"collector_received_at":{"type":"string","format":"date-time"},"consent_state":{"enum":["unmanaged","unknown","granted","denied"]},"consent_observed_at":{"type":["string","null"],"format":"date-time"},"consent_source":{"type":["string","null"],"maxLength":32},"browser":{"type":["string","null"],"maxLength":32},"operating_system":{"type":["string","null"],"maxLength":32},"device_type":{"oneOf":[{"enum":["desktop","mobile","tablet","bot"]},{"type":"null"}]},"country_code":{"type":["string","null"],"pattern":"^[A-Z]{2}$"}}}}}}