Send events from your backend
Create a product public key, authenticate Events API requests, and replace a key.
Use a product public access key to send Tracking events from your backend. This covers events the browser cannot reliably report: confirmed payments, renewals, refunds, and orders completed on an externally hosted checkout.
Keep the key on your server. The browser tracking script needs no key, and you must not put one in a browser or mobile application. The platform creates and checks keys; Tracking does not manage them.
Before you start: have a product Owner or Admin available to create the key, and a secret store your backend can read.
Get a key
- Open the product’s
Settings→Public Access. Choose the product whose events your backend will send. This is a platform settings page, separate from Tracking’sPublic accessstatus page. - Create and name the key. The name identifies it in your key list; it does not grant permissions.
- Choose its scope. For a backend that only sends Tracking events, choose Selected toolkits and select
tracking. All toolkits covers every public route of the product. A scope can be changed later. To limit a key toPOST /events, use the management API; public access explains route-specific scopes and how editing them in the UI can widen access. - Save the secret when it appears. A new key starts with
lpk_followed by 32 hexadecimal characters. The creation dialog shows it once. Store it in your backend’s secret store; only a hash is retained, so a lost value must be replaced.
Each key belongs to one product. A key from a staging product cannot write events into a different production product. Allow about 30 seconds for a new key to take effect before checking it with a request.
Send it
-
Copy the endpoint from Tracking’s
Public accesspage. Its format ishttps://<tracking host>/<product id>/tracking/events. The host defaults topublic.lepsto.com, or uses the custom host you claimed onTracking domain. -
Send the key as a bearer token with the event batch. Replace
YOUR_KEY_HEREwith the secret read by your backend:Authorization: Bearer YOUR_KEY_HERE -
Check the response and event. A successful request returns
200withaccepted,duplicates, andrejected. Confirm the intended event was accepted and appears inLive; inspect any rejected entries before treating the whole batch as stored.
The platform validates the key and removes it before forwarding the request to Tracking. Use send revenue from your backend for batch fields, event names, and amount units, and the public HTTP routes and SDK for the full route and error bodies.
The legacy carrier
Existing integrations can continue to send the same key in X-Api-Key:
X-Api-Key: YOUR_KEY_HEREUse Authorization: Bearer in new integrations. If both headers are present, the bearer token takes precedence.
The platform also accepts X-Public-Key. See public access for all accepted headers, their precedence, and platform refusal codes.
The keys you already had
Active keys originally issued by Tracking were imported into the product’s Public Access list. They keep their exact secret and sk_live_ prefix, so existing integrations can keep using the same value with either documented header. They are not converted to lpk_ strings.
An imported key:
- Is marked as imported and keeps its original name and creation date, with no member listed as its creator.
- Covers the Tracking toolkit’s keyed routes. An Owner or Admin can narrow its scope or revoke it.
- Shows only its identifying prefix in the list. Its full secret is not displayed again.
Previously revoked keys were not imported and remain revoked. Revoking an imported key is permanent, just as it is for a newly created key.
Replace a key
Replace keys when they may have been exposed, when the person or system holding them no longer needs access, or when your rotation policy requires it. There is no rotation button; use this sequence:
- Create a replacement key with the needed scope and save its secret. Allow the propagation window below before using it.
- Deploy the replacement to every backend that uses the old key. Confirm those backends’ events are still accepted and appear in
Live. - Revoke the old key in the product’s Settings → Public Access.
Both keys can work during the changeover. Checking the replacement before revoking the old key avoids an authentication gap. Revoking first stops callers that still use the old secret once the change propagates.
When a change takes effect
Key validation uses a snapshot refreshed about every 30 seconds. A new key can briefly return 401 before the snapshot includes it; a revoked key can remain accepted until the next refresh. Account for this window when testing creation or revocation.
When a request is refused
Code | Meaning | Check |
|---|---|---|
401 public_key_required | No key reached the platform in an accepted header | Send the bearer header with the request |
401 public_key_invalid | The key is not an active key of this product | Check the value and product, and whether the key was revoked or just created |
403 public_key_scope | The key’s scope does not cover the Events API | Confirm it covers POST /events |
503 public_config_unavailable means the platform has not loaded its key snapshot yet. Retry; replacing the key does not fix that condition. Public access lists the platform codes, and Tracking troubleshooting gives the checks for rejected requests.
Keep keys safe
- Give each sending system its own named key so you can replace or revoke it independently.
- Scope it to the routes that system uses.
- Read secrets from your deployment’s secret store. Keep them out of source control and configuration files distributed with your application.
- Keep keys out of browser and mobile code and public repositories. Use your backend for authenticated events; use the keyless tracking script in the browser.
- Revoke keys when they are no longer needed.
Next steps
- Send revenue from your backend: construct lifecycle events and amounts.
- Record your own events: choose between browser and backend collection.
- Fix a rejected request: diagnose status codes and rejected events.
- The public HTTP routes and SDK: inspect the route and typed client.
- Look up a setting: check defaults and limits.