Check stored contracts against live traffic
Diffs every stored contract (or one, with event) against the events in the window and returns the violations, worst first.
Three violation kinds, kept separate because they have three different fixes: missing_required (key absent), null_value (key present but null), type_mismatch (key present with a type other than the declared one). Keys observed but not declared are reported under undeclared and are never violations — a growing integration always has some.
A contract whose event had no traffic returns status: "no_data" with no violations and is counted in summary.events_no_data. An event that stopped firing must not read as "every field is missing". no_data always carries a no_data_reason telling you which of its three causes applies — a tracking outage, this event alone not firing, or sampling — because the fix is different for each. See the EventReport schema.
Every violation carries a samples link to GET /client/v1/contracts/violations's companion endpoint /client/v1/contracts/samples, pre-filled with this window: the actual offending events, with session_id and page URL.
Cost note: this reads raw events to get the denominator. The window defaults to 1 day; pass event to narrow it, and sample for wide windows on high-volume events.
curl -X GET "https://mythic-analytics.gulp.workers.dev/client/v1/contracts/violations?location_id=example_string&event=example_string&date_from=2026-07-27&date_to=2026-08-03&sample=10" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN"
import requests
import json
url = "https://mythic-analytics.gulp.workers.dev/client/v1/contracts/violations?location_id=example_string&event=example_string&date_from=2026-07-27&date_to=2026-08-03&sample=10"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
response = requests.get(url, headers=headers)
print(response.json())
const response = await fetch("https://mythic-analytics.gulp.workers.dev/client/v1/contracts/violations?location_id=example_string&event=example_string&date_from=2026-07-27&date_to=2026-08-03&sample=10", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
)
func main() {
req, err := http.NewRequest("GET", "https://mythic-analytics.gulp.workers.dev/client/v1/contracts/violations?location_id=example_string&event=example_string&date_from=2026-07-27&date_to=2026-08-03&sample=10", nil)
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://mythic-analytics.gulp.workers.dev/client/v1/contracts/violations?location_id=example_string&event=example_string&date_from=2026-07-27&date_to=2026-08-03&sample=10')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
response = http.request(request)
puts response.body
{
"success": true,
"data": {
"window": {
"date_from": "last 1 day",
"date_to": "now",
"sample": {
"keeping": "1/10 of events",
"note": "example_string"
}
},
"summary": {
"contracts": 3,
"events_ok": 1,
"events_with_violations": 1,
"events_no_data": 1,
"total_violations": 2,
"reference": {
"location_events": 41320,
"source": "client_event_summary (unsampled)",
"warning": "example_string"
}
},
"events": [
{
"event": "order_completed",
"status": "ok",
"total_events": 1000,
"reference_events": 1000,
"no_data_reason": "no_events_at_all",
"detail": "example_string",
"warnings": [
"example_string"
],
"properties": [
{
"key": "value",
"expected_type": "number",
"required": true,
"present": 700,
"absent": 200,
"null_values": 100,
"type_mismatches": 150,
"coverage": 0.7,
"observed_types": {}
}
],
"violations": [
{
"key": "value",
"kind": "missing_required",
"count": 200,
"rate": 0.2,
"detail": "`value` is absent on 200 of 1000 events",
"samples": "/client/v1/contracts/samples?event=order_completed&key=value&kind=missing_required",
"samples_note": "example_string"
}
],
"undeclared": [
{
"key": "shipping_tier",
"observed_type": "string",
"occurrences": 300,
"coverage": 0.3
}
]
}
],
"truncated": true,
"warning": "example_string",
"hint": "example_string"
}
}
{
"error": "Bad Request",
"message": "The request contains invalid parameters or malformed data",
"code": 400,
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
{
"error": "Unauthorized",
"message": "Authentication required. Please provide a valid API token",
"code": 401
}
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Please try again later",
"code": 429,
"retryAfter": 3600
}
/client/v1/contracts/violations
Target server for requests. Edit to use your own host.
Agency key (ak_) or location secret key (sk_). Scoped keys (mcp_) are accepted too and need contracts:read or contracts:write. See Using an mcp_ key over HTTP.
ak_) or location secret key (sk_). Scoped keys (mcp_) are accepted too and need contracts:read or contracts:write. See Using an mcp_ key over HTTP.Location to scope to. Required for ak_ keys (or send the X-Location-Id header); ignored for sk_.
Check only this event's contract. Substantially cheaper than checking all.
Start of the window, ISO 8601 date or timestamp. Defaults to 1 day ago.
End of the window (inclusive day), ISO 8601. Defaults to now.
Keep a deterministic 1/N of events. Rates and coverage stay unbiased; counts become counts of the sample and are not scaled up. Use for wide windows on high-volume events — sample=10 handles 7 days of a 300k-event event name.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Agency key (ak_) or location secret key (sk_). Scoped keys (mcp_) are accepted too and need contracts:read or contracts:write. See Using an mcp_ key over HTTP.
Query Parameters
Location to scope to. Required for ak_ keys (or send the X-Location-Id header); ignored for sk_.
Check only this event's contract. Substantially cheaper than checking all.
Start of the window, ISO 8601 date or timestamp. Defaults to 1 day ago.
2026-07-27Keep a deterministic 1/N of events. Rates and coverage stay unbiased; counts become counts of the sample and are not scaled up. Use for wide windows on high-volume events — sample=10 handles 7 days of a 300k-event event name.
10