Limits, errors and troubleshooting

Kentro Pixel limits, CORS behavior, reason codes, request errors, troubleshooting, background processing and retention.

This page collects the numbers and codes you need when something does not arrive: request and rate limits, CORS, per-event reason codes and request errors. It also explains what happens after ingestion and how long each kind of data is kept.

In this page

  • Limits
  • CORS
  • Per-event reason codes
  • Request errors
  • Troubleshooting
  • Processing
  • Retention

Limits

LimitValue
Browser request body (/v1/events, /v1/events/batch)64 KB
Server request body (/v1/server/events)512 KB
One event, serialized32 KB
Events per request100 on browser routes and the validate endpoint, 500 on the server route
GIF beacon e parameter16 KB of base64url
occurred_at skew7 days in the past, 5 minutes in the future
Server signature window300 seconds
Idempotency key128 characters
Rate limit, public key600 events per minute, bursts up to 1,200
Rate limit, server key6,000 events per minute, bursts up to 12,000
Rate limit, client IP on browser routes and the validate endpoint600 requests per minute, bursts up to 1,200
Rate limit, client IP on the server route1,200 requests per minute, bursts up to 2,400
Lookups of keys not seen in the last minute, per client IP60 per minute, bursts up to 120
Signup capture (SDK form)60 signups per minute per property; body up to 4 KB
Identity tokens5 distinct tokens per request, 1,024 characters each, valid at most 24 hours
Duplicate detection (event_id)At least 14 days per property
Allowed origins50 per property
Sensitive path patterns50 per property, 200 characters and 20 segments each
Custom event schemas500 per workspace are loaded
Destination event mapping50 entries
Destination replay windowAt most 180 days long, from at most 30 days back
Privacy request subject keys1 to 100

Key rate limits count events, not requests (a batch of 50 uses 50); client IP limits count requests, and lookups of unknown keys count separately, so unknown keys cannot be used to scan for valid ones. All limits are enforced per collector instance. A refused request answers 429 RATE_LIMITED with a Retry-After header in seconds; the SDK retries automatically.

CORS

  • The collector endpoints answer CORS themselves: Access-Control-Allow-Origin echoes the request origin when the property allows it (or *), with Vary: Origin, Timing-Allow-Origin, methods POST, GET, OPTIONS, headers Content-Type, X-Kentro-Pixel-Key and a preflight cache of 10 minutes (Access-Control-Max-Age: 600). Credentials are not used.
  • The SDK sends text/plain with the key in the body, which needs no preflight. Sending application/json or the X-Kentro-Pixel-Key header from a browser triggers a preflight, which is supported.
  • The SDK file is served with Access-Control-Allow-Origin: * and Cross-Origin-Resource-Policy: cross-origin.
  • The signup capture used by form echoes only an allowed origin and never uses credentials.
  • The management API uses the standard Kentro API CORS policy.

Per-event reason codes

CodeStatusMeaning
INVALID_ENVELOPErejectedNot an object, fails the envelope rules (types, lengths, the event_name pattern) or occurred_at is not a date.
PAYLOAD_TOO_LARGErejectedThe event is larger than 32 KB serialized.
CLOCK_SKEWrejectedoccurred_at is more than 7 days in the past or 5 minutes in the future.
UNKNOWN_EVENTrejectedNo builtin or custom schema for this event_name and schema_version.
RESERVED_EVENTrejectedThe name is one Kentro produces itself, refused on every route and for any schema_version. The reason says what to use instead.
SCHEMA_VIOLATIONrejectedproperties does not match the schema; reason points at the field.
SENSITIVE_PAYLOADquarantinedHealth terms, ICD-10 codes, secrets or card numbers were detected.
SENSITIVE_SCAN_INCOMPLETEquarantinedThe payload was too large or too deeply nested to scan completely.
CONSENT_DENIEDsuppressedThe effective consent for the event's purpose is denied.
GPC_OPT_OUTsuppressedGlobal Privacy Control alone denied an event with the marketing purpose.
SENSITIVE_REDACTEDacceptedAuthoritative server commerce events only: matching fields were replaced; the order still counts, but the event is never forwarded to destinations.
IDENTITY_UNVERIFIEDacceptedBrowser events: a person reference without a valid identity token was dropped; the event was recorded anonymously.

Request errors

Request-level errors refuse the whole request. Handler errors answer { "error": "<CODE>", "reason_code": "<CODE>", "message": "..." }; framework errors (400 for unparsable JSON, 413, 415, 500) answer { "error": "<CODE>", "message": "..." }. The same codes apply to browser and server routes.

HTTPCodeWhenRetry
400INVALID_ENVELOPEThe body is not JSON, not an envelope or { "events": [...] }, or has no events.No
400BATCH_TOO_LARGEMore than 100 (browser) or 500 (server) events; the body carries max.Split the batch
401KEY_INVALIDMissing or unknown key, disabled property, or a key whose environment does not match the property.No
401KEY_REVOKEDThe key was revoked.No
401SIGNATURE_INVALIDMissing or wrong signature, or the body was not sent as application/json.After fixing the signing
401TIMESTAMP_STALEX-Kentro-Timestamp missing, not digits, or more than 300 seconds off.After re-signing
403ORIGIN_NOT_ALLOWEDThe browser origin is not in allowed_origins.No
409IDEMPOTENCY_KEY_REUSEDServer route: the idempotency key was already used with a different body.With a new key
413PAYLOAD_TOO_LARGEThe body exceeds 64 KB (browser) or 512 KB (server).Split the batch
415UNSUPPORTED_MEDIA_TYPEA content type other than application/json (or text/plain on browser routes).No
429RATE_LIMITEDToo many events for this key, or too many requests (or unknown keys) from this client.After Retry-After
500INTERNAL_ERRORUnexpected error.With backoff
503COLLECTOR_DISABLEDThe collector is switched off.Later
503INGEST_UNAVAILABLEStorage is temporarily unavailable.With backoff
503SIGNING_UNAVAILABLEServer key secrets are temporarily unavailable.Later

Troubleshooting

SymptomLikely causeWhat to do
No request leaves the pageThe script tag has no data-key, or init was called without key and endpoint; or a call was queued before init.Use the snippet from GET /v1/properties/:id/snippet, or pass both options to init, and queue init first.
Requests blocked by the browserA Content-Security-Policy without the collector host.Allow https://pixel.kentro.live in script-src and connect-src (and img-src for the GIF fallback), and allow the inline queue stub with a nonce or hash.
401 KEY_INVALIDWrong key, disabled property, or a pk_test_ key on a production property (or the reverse).Copy the key from the property; keys are tied to the property's environment.
401 KEY_REVOKEDThe key was revoked.Create a new key and update the snippet.
403 ORIGIN_NOT_ALLOWEDThe page's host is not in allowed_origins, or the request carried neither Origin nor Referer while an allowlist is set.Add the exact host or a *.domain entry (the apex needs its own entry). A Referrer-Policy: no-referrer page cannot use the GIF beacon with an allowlist.
Result rejected, UNKNOWN_EVENTThe name is not in the taxonomy, is not lower-case namespace.name, or schema_version does not match.Use a name from the taxonomy.
Result rejected, RESERVED_EVENTThe name is one Kentro produces itself: attribution, audience membership, conversions, Kentro GO campaign data or Kentro Email history (email.*).Stop sending it; use what reason names.
Result rejected, SCHEMA_VIOLATIONA property is not on the event's allowlist, a required property is missing, or money was sent as a float.Check reason; send money as { "amount_minor", "currency" }; put identifiers under properties.customer.
Result rejected, CLOCK_SKEWoccurred_at is far off, or was sent in milliseconds.Send ISO 8601 timestamps from a synchronized clock.
Result suppressed, CONSENT_DENIED or GPC_OPT_OUTConsent is unknown or denied for the event's purpose, or GPC alone blocked a marketing event.Report consent with consentChanged; include consent in server envelopes; review settings.consent.
Result quarantined, SENSITIVE_PAYLOADA property value, the page title or a form value matched a detector, for example "appointment" or "patient" in a page title.Keep medical terms, secrets and card numbers out of event data and page titles.
Result duplicateThe event_id was already accepted for the property, or an envelope without event_id was identical to an earlier one.Give every real-world event its own event_id; expect duplicate on retries.
429 RATE_LIMITEDMore than the per-key budget.Wait for Retry-After; batch events; use a server key for high-volume backend traffic.
401 SIGNATURE_INVALID on the server routeThe signed string differs from the bytes sent, the secret belongs to another key id, the sha256= prefix or lower-case hex is missing, the secret was base64-decoded, or the body was not sent as application/json.Sign the exact string you send, with the secret as given, and send Content-Type: application/json.
401 TIMESTAMP_STALEThe clock is off by more than 300 seconds, or the timestamp is in milliseconds.Send Unix seconds from a synchronized clock.
Result accepted with IDENTITY_UNVERIFIEDA person reference without a valid identity token (missing, malformed, expired, or signed by a revoked key or a key of another property).Mint tokens as in Identity tokens; never put subject_ref in browser events.
409 IDEMPOTENCY_KEY_REUSEDThe idempotency key was already used with a different body.Use a new key for every new batch.
503 COLLECTOR_DISABLED, INGEST_UNAVAILABLE, SIGNING_UNAVAILABLEThe collector is switched off, or storage or secrets are temporarily unavailable.Retry later with the same event_id values.
Signups from the form command never arriveThe property's allowed_origins is empty or misses the page's host (403), the consent checkbox was not checked, the email field was not found, or a Content-Security-Policy blocks https://t.kentro.email.Add the host to allowed_origins, check consentSelector and emailField, and allow the host in connect-src. Set debug: true to see option warnings.
Events in the debugger but not in analytics or a destinationProcessing runs in the background; a destination sends only mapped events once it is enabled, and only with the consent it needs.Check processing_status in the debugger, the destination's status and mapping, and its delivery history (suppressedReason).
404 Not Found on every management routeThe management API is switched off on this environment.During the preview it is enabled per environment; contact [email protected] for access.

Processing

After ingestion, Kentro's background processor works through accepted events in the order they arrived:

  • People and sessions. Each event is attached to the person keys it carries; a verified login or an order links an anonymous visitor to the person. Sessions follow settings.session (30 idle minutes by default) and record the touchpoint: UTM values, hashed ad click ids, the campaign reference and the referrer class. Sessions, touchpoints and browser conversions need analytics or marketing consent.
  • Kentro Email touchpoints. A click on a tracked Kentro Email link records a touchpoint of channel email (source kentro_email, medium email) for that contact, so attribution can credit email. Opens are not touchpoints.
  • Consent record. Explicit consent choices are filed as described in Consent and privacy.
  • Conversions. commerce.order_placed and commerce.order_paid record an order, and cancellations and refunds correct it; marketing.lead_captured, marketing.signup_completed and marketing.demo_booked are lead conversions. Each order counts once (a server copy wins over a browser copy, commerce.order_paid over commerce.order_placed) and each lead once per conversion type and lead_ref.
  • Destinations. Each mapped event of an enabled destination becomes a delivery, sent with retries; consent is checked again when it is sent.
  • Attribution. Last-touch attribution over 30 days is refreshed automatically when conversions change; the other models run on request (POST /v1/analytics/attribution/runs).
  • Audiences. Active audiences are recomputed about every 10 minutes; the membership changes are what an audience sync sends.
  • Privacy requests run as described in Consent and privacy.

Retention

Retention is enforced automatically. Changing settings.retention applies to the history already stored: a longer period keeps existing history longer, and a shorter one removes stored history past the new period, starting with the next daily retention run.

DataKept
Event historyAt least 13 months, or longer when settings.retention.journalMonths asks for it
Ingestion receipts and server batch idempotency keysAs long as the property's event history
Accepted event ids, for duplicate detection14 days
Rejected-event samples (ingestion health)settings.retention.errorsDays: 30 days by default, 1 to 365
Attribution results and order reconciliation recordsAs long as the property's event history
People records (person keys and the links between them)Removed once a person has not been seen for the full event retention period, belongs to no active audience and has no conversion within that period. Kentro Email contacts, and people a Kentro Email contact's customer record points to through an authorized CRM link, are kept. Deletion records of privacy requests are kept, so a deleted person is never recreated.
Consent recordsAs long as the person's record, and at least for the event retention period. Consent withdrawal records are always kept.
Audience membership historyCurrent memberships while they last; a leave is kept 90 days
Raw ad click ids90 days, then removed from sessions and events
The full browser user agent of marketing-consented events30 days
The salted hash of the client IP address on ingestion receipts (the raw address is never stored)30 days
Delivery history30 days; a delivery still waiting to be sent is kept until it is sent or gives up
Privacy request records24 months after completion, then deleted
Privacy export downloads24 hours