Events API
Καταγράψτε συμβάντα και συμπεριφορά χρηστών προγραμματιστικά μέσω REST API.
Όλα τα endpoints αυτής της σελίδας είναι σχετικά ως προς το βασικό URL: https://api-eu1.joryio.com - δείτε Επισκόπηση API.
Το συμβάν αγοράς
Η αναφορά εσόδων, η απόδοση, το CLV και τα προβλεπτικά μοντέλα διαβάζουν ένα συμβάν. Αν στέλνετε αγορές με διαφορετικό όνομα, δεν προσμετρώνται πουθενά.
| Όνομα συμβάντος | Order Completed |
| Απαιτούμενες ιδιότητες | total, currency |
| Συνιστώμενες | total_base, base_currency, orderId |
{
"eventName": "Order Completed",
"userId": "user_123",
"properties": {
"total": 149.90,
"currency": "EUR",
"total_base": 162.35,
"base_currency": "USD",
"orderId": "1024"
}
}
Γιατί μόνο ένα όνομα
Άλλες πλατφόρμες χρησιμοποιούν άλλα ονόματα - Placed Order (Klaviyo),
purchase (GA4). Δεν τα δεχόμαστε σκόπιμα, επειδή η αποδοχή πολλών ονομάτων
σημαίνει πρόσθεσή τους: ένα κατάστημα που τρέχει ετικέτα GA4 μαζί με τον
σύνδεσμό μας θα στείλει μία πώληση με δύο ονόματα και θα δει διπλάσια έσοδα.
Ένα ποσό εσόδων που είναι σιωπηλά 2x εντοπίζεται πολύ δυσκολότερα από ένα που
είναι προφανώς 0.
Έτσι ο κανόνας είναι ένα δημοσιευμένο συμβόλαιο. Αν οι παραγγελίες δεν εμφανίζονται, η αιτία φαίνεται αμέσως κατά την ενσωμάτωση - και διορθώνεται - αντί να είναι σιωπηλά λανθασμένη για μήνες.
Σχετικά με τα ποσά
Τα total και total_base είναι δύο διαφορετικά μεγέθη, όχι εναλλακτικές:
total- τι πλήρωσε ο πελάτης, στο νόμισμα που πλήρωσε.total_base+base_currency- η ίδια παραγγελία στο νόμισμα αναφοράς σας. Στείλτε τα αν πουλάτε σε περισσότερα από ένα νομίσματα, ώστε τα σύνολα να αθροίζονται σωστά.
Στείλτε μόνο το total αν έχετε ένα νόμισμα. Το orderId είναι προαιρετικό
αλλά συνιστάται: αποτρέπει τη διπλοκαταχώριση παραγγελίας που φτάνει
περισσότερες από μία φορές (επανάληψη, ανανέωση σελίδας στο ταμείο).
Αν ήδη στέλνετε άλλο όνομα
Τα ιστορικά σας συμβάντα διατηρούνται, αλλά δεν θεωρούνται παραγγελίες.
Μεταφέρετε τις νέες παραγγελίες στο Order Completed και η αναφορά εσόδων
ξεκινά από εκείνο το σημείο. Δεν ξαναγράφουμε παλιά συμβάντα, ώστε τίποτα να
μην επανερμηνεύεται σιωπηλά.
Έλεγχος ταυτότητας
Όλα τα αιτήματα απαιτούν έλεγχο ταυτότητας με κλειδί API:
Authorization: Bearer jry_live_your_api_key_here
Content-Type: application/json
Καταγραφή συμβάντος
Καταγράψτε ένα μεμονωμένο συμβάν χρήστη με προαιρετικές ιδιότητες.
Αυτό το endpoint δέχεται δύο μορφές σώματος: ένα μεμονωμένο αντικείμενο συμβάντος (τεκμηριώνεται εδώ) ή έναν σκέτο πίνακα JSON με αντικείμενα συμβάντων για μαζική καταγραφή (μέγιστο 500) - δείτε Καταγραφή πολλαπλών συμβάντων (σώμα-πίνακας).
Endpoint
POST /events/track
Σώμα αιτήματος
| Πεδίο | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
userId | string | Ναι* | Το δικό σας αναγνωριστικό χρήστη. *Απαιτείται ένα από τα userId, joryioUserId, anonymousId ή userAlias |
eventName | string | Ναι | Όνομα του συμβάντος (μέγιστο 255 χαρακτήρες) |
properties | object | Όχι | Ιδιότητες συμβάντος (μέγιστο 200 κλειδιά ανώτατου επιπέδου, 50KB, βάθος ένθεσης 5) |
timestamp | string ή number | Όχι | Χρονοσφραγίδα συμβάντος (συμβολοσειρά ISO 8601 ή epoch χιλιοστά· προεπιλογή η τρέχουσα στιγμή) |
joryioUserId | string | Όχι | Το εσωτερικό ID χρήστη του Joryio - το 24-hex id που επιστρέφεται στις αποκρίσεις του user API (εναλλακτικό του userId) |
anonymousId | string | Όχι | ID ανώνυμου επισκέπτη (εναλλακτικό αναγνωριστικό) |
userAlias | object | Όχι | { aliasLabel, aliasName } - αναγνωριστικό ψευδωνύμου (εναλλακτικό του userId) |
sessionId | string | Όχι | Αναγνωριστικό συνεδρίας |
deviceId | string | Όχι | Αναγνωριστικό συσκευής |
clientEventId | string | Όχι | ID συμβάντος που δημιουργεί ο πελάτης - χρησιμοποιείται ως το αποθηκευμένο ID συμβάντος, οπότε οι επαναλήψεις με την ίδια τιμή απαλείφονται ως διπλότυπα |
Παράδειγμα αιτήματος
curl -X POST https://api-eu1.joryio.com/events/track \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"userId": "user_123",
"eventName": "Order Completed",
"properties": {
"orderId": "order_456",
"total": 99.99,
"currency": "USD",
"items": 3,
"paymentMethod": "credit_card"
},
"timestamp": "2024-01-20T14:30:00.000Z"
}'
Απόκριση
Η μορφή μεμονωμένου αντικειμένου επιστρέφει το ID του αποθηκευμένου συμβάντος:
{
"eventId": "9b2f6c1e-4a8d-4f0b-9c3d-2e1f5a6b7c8d",
"success": true
}
Σημειώσεις
- Τα συμβάντα επεξεργάζονται ασύγχρονα
- Χρησιμοποιείτε συνεπή ονομασία συμβάντων (δείτε Καλές πρακτικές ονομασίας συμβάντων)
- Οι ιδιότητες μπαίνουν σε ευρετήριο για τμηματοποίηση
- Η χρονοσφραγίδα προεπιλέγεται στην ώρα του διακομιστή αν δεν παρέχεται
Καταγραφή πολλαπλών συμβάντων (σώμα-πίνακας)
Δεν υπάρχει ξεχωριστό endpoint μαζικής καταγραφής: το POST /events/track δέχεται είτε ένα μεμονωμένο αντικείμενο συμβάντος είτε έναν σκέτο πίνακα JSON με αντικείμενα συμβάντων (χωρίς αντικείμενο-περιτύλιγμα). Η μορφή πίνακα καταγράφει έως 500 συμβάντα σε ένα αίτημα.
Endpoint
POST /events/track
Σώμα αιτήματος
Ένας πίνακας JSON (μέγιστο 500 στοιχεία). Κάθε στοιχείο ακολουθεί την ίδια μορφή με τη μορφή μεμονωμένου αντικειμένου.
Κάθε στοιχείο περνά από πλήρη επικύρωση. Ένα μη έγκυρο στοιχείο αναφέρεται στο rejected με τον δείκτη του στον πίνακα - δεν γίνεται ποτέ σιωπηλά αποδεκτό - και τα υπόλοιπα έγκυρα στοιχεία εξακολουθούν να επεξεργάζονται.
Παράδειγμα αιτήματος
curl -X POST https://api-eu1.joryio.com/events/track \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '[
{
"userId": "user_123",
"eventName": "Product Viewed",
"properties": {
"productId": "prod_456",
"price": 49.99
}
},
{
"userId": "user_123",
"eventName": "Added To Cart",
"properties": {
"productId": "prod_456",
"quantity": 1
}
},
{
"userId": "user_456",
"eventName": "Page Viewed",
"properties": {
"page": "/pricing"
}
}
]'
Απόκριση
Σε αντίθεση με τη μορφή αντικειμένου (που επιστρέφει { eventId, success }), η μορφή πίνακα επιστρέφει μια συγκεντρωτική σύνοψη:
{
"processed": 3,
"accepted": 3,
"rejected": []
}
| Πεδίο | Περιγραφή |
|---|---|
processed | Πλήθος στοιχείων που παραλήφθηκαν στον πίνακα του αιτήματος |
accepted | Συμβάντα που πραγματικά καταγράφηκαν |
rejected | Αποτυχίες ανά στοιχείο: index (θέση στον πίνακα του αιτήματος), name (το όνομα συμβάντος του στοιχείου, όταν υπάρχει), reason |
Παράδειγμα με ένα μη έγκυρο στοιχείο:
{
"processed": 3,
"accepted": 2,
"rejected": [
{
"index": 1,
"name": "Added To Cart",
"reason": "property hacker should not exist"
}
]
}
Όρια
- Μέγιστο 500 συμβάντα ανά αίτημα (περισσότερα επιστρέφουν
400)· κενός πίνακας επιστρέφει επίσης400 - Κάθε συμβάν ακολουθεί την ίδια μορφή με τη μορφή μεμονωμένου αντικειμένου
- Η μαζική επεξεργασία δεν είναι ατομική: τα έγκυρα συμβάντα καταγράφονται ακόμη κι όταν κάποια στοιχεία απορρίπτονται - ελέγξτε το
rejectedγια μερικές αποτυχίες
Ερώτημα συμβάντων
Ανακτήστε συμβάντα με φιλτράρισμα και σελιδοποίηση. Δεν υπάρχει endpoint ανάκτησης βάσει ID συμβάντος - φιλτράρετε αυτό το ερώτημα αντ' αυτού.
Endpoint
GET /events/query
Παράμετροι query
| Παράμετρος | Τύπος | Προεπιλογή | Περιγραφή |
|---|---|---|---|
userId | string | - | Φιλτράρισμα βάσει ID χρήστη |
eventName | string | - | Φιλτράρισμα βάσει ονόματος συμβάντος |
startDate | string | - | Φιλτράρισμα συμβάντων μετά από αυτή την ημερομηνία (ISO 8601) |
endDate | string | - | Φιλτράρισμα συμβάντων πριν από αυτή την ημερομηνία (ISO 8601) |
limit | number | 100 | Αποτελέσματα ανά σελίδα (μέγιστο 1000) |
offset | number | 0 | Πλήθος συμβάντων που παραλείπονται |
Παράδειγμα αιτήματος
# Get all "Order Completed" events in January 2024
curl -X GET "https://api-eu1.joryio.com/events/query?eventName=Order+Completed&startDate=2024-01-01T00:00:00Z&endDate=2024-02-01T00:00:00Z&limit=100" \
-H "Authorization: Bearer jry_live_your_api_key"
Απόκριση
Ένας σκέτος πίνακας JSON, με τα νεότερα πρώτα. Τα πεδία των συμβάντων χρησιμοποιούν snake_case (προέρχονται από το analytics store):
[
{
"event_id": "9b2f6c1e-4a8d-4f0b-9c3d-2e1f5a6b7c8d",
"user_id": "665f1e2a9b3c4d5e6f7a8b9c",
"anonymous_id": "",
"event_name": "Order Completed",
"properties": {
"orderId": "order_456",
"total": 99.99
},
"timestamp": "2024-01-20 14:30:00",
"session_id": "",
"device_id": ""
},
{
"event_id": "1c3e5a7b-9d2f-4b6c-8e0a-3f5d7b9c1e2a",
"user_id": "665f1e2a9b3c4d5e6f7a8b9d",
"anonymous_id": "",
"event_name": "Order Completed",
"properties": {
"orderId": "order_789",
"total": 149.99
},
"timestamp": "2024-01-19 10:15:00",
"session_id": "",
"device_id": ""
}
]
Συγκεντρωτικά συμβάντων
Λήψη συγκεντρωτικών στατιστικών συμβάντων με ομαδοποίηση και μετρικές.
Endpoint
POST /events/aggregate
Σώμα αιτήματος
| Πεδίο | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
eventName | string | Ναι | Όνομα του συμβάντος προς συγκέντρωση |
startDate | string | Όχι | Ημερομηνία έναρξης (ISO 8601) |
endDate | string | Όχι | Ημερομηνία λήξης (ISO 8601) |
groupBy | string | Όχι | Χρονική ομαδοποίηση: hour, day, week, month (προεπιλογή: day) |
metrics | array | Όχι | Μετρικές προς υπολογισμό: count, sum, avg, min, max (προεπιλογή: ['count']) |
sumField | string | Όχι | Όνομα του κλειδιού στο properties προς άθροιση/συγκέντρωση (π.χ. total) |
avgField | string | Όχι | Όνομα του κλειδιού στο properties για μέσο όρο |
eventProperties | object | Όχι | Φιλτράρισμα βάσει ιδιοτήτων συμβάντος |
Παράδειγμα αιτήματος
curl -X POST https://api-eu1.joryio.com/events/aggregate \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"eventName": "Order Completed",
"startDate": "2024-01-01T00:00:00Z",
"endDate": "2024-02-01T00:00:00Z",
"groupBy": "day",
"metrics": ["count", "sum"],
"sumField": "total"
}'
Απόκριση
{
"success": true,
"data": {
"eventName": "Order Completed",
"groupBy": "day",
"metrics": ["count", "sum"],
"results": [
{
"period": "2024-01-01T00:00:00Z",
"count": 45,
"sum_value": 4567.89
},
{
"period": "2024-01-02T00:00:00Z",
"count": 52,
"sum_value": 5123.45
},
{
"period": "2024-01-03T00:00:00Z",
"count": 38,
"sum_value": 3890.12
}
],
"total": 3
}
}
Υποστηριζόμενες μετρικές
- count: Συνολικό πλήθος συμβάντων
- sum: Άθροισμα των τιμών του καθορισμένου πεδίου
- avg: Μέσος όρος των τιμών του καθορισμένου πεδίου
- min: Ελάχιστη τιμή του καθορισμένου πεδίου
- max: Μέγιστη τιμή του καθορισμένου πεδίου
Παράδειγμα: Ανάλυση εσόδων
# Get daily revenue from purchases
curl -X POST https://api-eu1.joryio.com/events/aggregate \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"eventName": "Order Completed",
"startDate": "2024-01-01T00:00:00Z",
"endDate": "2024-01-31T00:00:00Z",
"groupBy": "day",
"metrics": ["count", "sum", "avg"],
"sumField": "total"
}'
Παράδειγμα: Χρήση λειτουργίας ανά ώρα
# Track feature usage patterns by hour
curl -X POST https://api-eu1.joryio.com/events/aggregate \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"eventName": "Feature Used",
"startDate": "2024-01-20T00:00:00Z",
"endDate": "2024-01-21T00:00:00Z",
"groupBy": "hour",
"metrics": ["count"]
}'
Συνήθη συμβάντα
Συμβάντα e-commerce
// Product Viewed
POST /events/track
{
"userId": "user_123",
"eventName": "Product Viewed",
"properties": {
"productId": "prod_456",
"productName": "Premium Plan",
"category": "Subscription",
"price": 99.99,
"currency": "USD"
}
}
// Added To Cart
POST /events/track
{
"userId": "user_123",
"eventName": "Added To Cart",
"properties": {
"productId": "prod_456",
"quantity": 1,
"price": 99.99
}
}
// Order Completed
POST /events/track
{
"userId": "user_123",
"eventName": "Order Completed",
"properties": {
"orderId": "order_789",
"total": 249.99,
"currency": "USD",
"itemCount": 3,
"discount": 25.00,
"paymentMethod": "credit_card"
}
}
Συμβάντα κύκλου ζωής χρήστη
// Signup Completed
POST /events/track
{
"userId": "user_123",
"eventName": "Signup Completed",
"properties": {
"method": "email",
"source": "homepage_cta"
}
}
// Onboarding Completed
POST /events/track
{
"userId": "user_123",
"eventName": "Onboarding Completed",
"properties": {
"stepsCompleted": 5,
"timeSpent": "8m 30s"
}
}
// Trial Started
POST /events/track
{
"userId": "user_123",
"eventName": "Trial Started",
"properties": {
"plan": "premium",
"trialDays": 14
}
}
Συμβάντα αλληλεπίδρασης
// Feature Used
POST /events/track
{
"userId": "user_123",
"eventName": "Feature Used",
"properties": {
"featureName": "export",
"exportFormat": "csv",
"recordCount": 1500
}
}
// Page Viewed
POST /events/track
{
"userId": "user_123",
"eventName": "Page Viewed",
"properties": {
"page": "/pricing",
"category": "Marketing",
"referrer": "google"
}
}
Ιδιότητες συμβάντων
Καλές πρακτικές
Χρησιμοποιείτε περιγραφικά ονόματα ιδιοτήτων:
Σωστό:
{
"properties": {
"productId": "prod_123",
"productName": "Premium Plan",
"price": 99.99,
"currency": "USD"
}
}
Λάθος:
{
"properties": {
"pid": "prod_123",
"n": "Premium Plan",
"p": 99.99
}
}
Υποστηριζόμενοι τύποι δεδομένων
{
"properties": {
"string": "value",
"number": 99.99,
"integer": 5,
"boolean": true,
"date": "2024-01-15T10:30:00Z",
"array": ["tag1", "tag2"],
"object": {
"nested": "value",
"deep": {
"property": "value"
}
}
}
}
Δεσμευμένες ιδιότητες
Οι ιδιότητες που ξεκινούν με $ είναι δεσμευμένες για χρήση από το σύστημα:
$app_id- Αναγνωριστικό εφαρμογής$app_name- Όνομα εφαρμογής$platform- Πλατφόρμα (web, ios, android)$session_id- Αναγνωριστικό συνεδρίας$anonymous_id- ID ανώνυμου χρήστη
Μην χρησιμοποιείτε αυτά τα ονόματα για προσαρμοσμένες ιδιότητες.
Όρια συμβάντων
Όρια μεγέθους
| Όριο | Τιμή |
|---|---|
| Μέγιστο μήκος ονόματος συμβάντος | 255 χαρακτήρες |
| Μέγιστο μήκος αναγνωριστικού (userId, anonymousId, sessionId, deviceId, clientEventId) | 255 χαρακτήρες |
| Μέγιστα κλειδιά ιδιοτήτων ανώτατου επιπέδου ανά συμβάν | 200 |
| Μέγιστο μέγεθος ιδιοτήτων (JSON) | 50 KB |
| Μέγιστο βάθος ένθεσης ιδιοτήτων | 5 επίπεδα |
| Μέγιστα συμβάντα ανά αίτημα σώματος-πίνακα | 500 |
Όρια ρυθμού
Το Events API δεν έχει σήμερα σταθερά όρια ρυθμού ανά endpoint - δείτε Επισκόπηση API: Όρια ρυθμού.
Αποκρίσεις σφαλμάτων
Όλα τα σφάλματα χρησιμοποιούν το τυπικό σώμα σφάλματος - δείτε Επισκόπηση API: Απόκριση σφάλματος.
400 Bad Request - Αποτυχία επικύρωσης
{
"statusCode": 400,
"message": "Bad Request Exception",
"timestamp": "2026-01-15T10:30:00.000Z",
"path": "/events/track",
"errors": [
"eventName should not be empty"
]
}
400 Bad Request - Υπερμεγέθεις ιδιότητες
{
"statusCode": 400,
"message": "Event properties exceed maximum size of 50KB (received 63KB)",
"timestamp": "2026-01-15T10:30:00.000Z",
"path": "/events/track"
}
Καλές πρακτικές
1. Ομαδοποιείτε τα συμβάντα όπου είναι δυνατόν
Σωστό - Ομαδοποίηση πολλών συμβάντων με σώμα-πίνακα:
await fetch('/events/track', {
method: 'POST',
body: JSON.stringify([event1, event2, event3])
});
Λάθος - Μεμονωμένα αιτήματα:
await fetch('/events/track', { method: 'POST', body: JSON.stringify(event1) });
await fetch('/events/track', { method: 'POST', body: JSON.stringify(event2) });
await fetch('/events/track', { method: 'POST', body: JSON.stringify(event3) });
2. Χρησιμοποιείτε συνεπή ονομασία συμβάντων
Ακολουθήστε το μοτίβο «Αντικείμενο + ρήμα σε παρελθόντα χρόνο»:
Σωστό: Product Viewed, Order Completed, Trial Started
Λάθος: view_product, clicked, user_action_123
3. Συμπεριλαμβάνετε χρονοσφραγίδες
Για ιστορικά συμβάντα, συμπεριλαμβάνετε πάντα ακριβείς χρονοσφραγίδες:
{
"userId": "user_123",
"eventName": "Order Completed",
"timestamp": "2024-01-15T10:30:00.000Z", // Actual event time
"properties": { ... }
}
4. Κρατήστε τις ιδιότητες λιτές
Συμπεριλαμβάνετε μόνο τις σχετικές ιδιότητες:
Σωστό:
{
"eventName": "Order Completed",
"properties": {
"orderId": "order_123",
"total": 99.99,
"currency": "USD"
}
}
Λάθος:
{
"eventName": "Order Completed",
"properties": {
"orderId": "order_123",
"total": 99.99,
"currency": "USD",
"userAgent": "Mozilla/5.0...", // Too much detail
"sessionData": { /* large object */ },
"cookies": [ /* array of cookies */ ]
}
}
5. Χειρίζεστε τα σφάλματα ομαλά
Υλοποιήστε λογική επαναλήψεων με εκθετική αναμονή:
async function trackWithRetry(event, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch('/events/track', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(event)
});
if (response.ok) return await response.json();
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i);
await sleep(retryAfter * 1000);
continue;
}
throw new Error(`HTTP ${response.status}`);
} catch (error) {
if (i === maxRetries - 1) throw error;
await sleep(Math.pow(2, i) * 1000); // 1s, 2s, 4s
}
}
}
Εντοπισμός σφαλμάτων
Ενεργοποίηση λειτουργίας debug (SDK)
Όταν χρησιμοποιείτε το Web SDK:
import JoryioSDK from '@joryio/web-sdk';
const joryio = new JoryioSDK({
sdkKey: 'jry_sdk_web_...',
enableDebug: true // Log all events to console
});
Επαλήθευση συμβάντων στο dashboard
- Μεταβείτε στους Χρήστες → Βρείτε τον χρήστη
- Κάντε κλικ στην καρτέλα Δραστηριότητα
- Δείτε όλα τα καταγεγραμμένα συμβάντα
Συνήθη προβλήματα
Τα συμβάντα δεν εμφανίζονται:
- Επαληθεύστε ότι το κλειδί API είναι σωστό
- Ελέγξτε ότι ο χρήστης έχει ταυτοποιηθεί
- Βεβαιωθείτε ότι το όνομα συμβάντος και οι ιδιότητες είναι έγκυρα
- Ελέγξτε τα όρια ρυθμού
Οι ιδιότητες δεν εμφανίζονται:
- Επαληθεύστε ότι τα ονόματα ιδιοτήτων είναι σωστά
- Ελέγξτε ότι οι τύποι δεδομένων υποστηρίζονται
- Αποφύγετε τα δεσμευμένα ονόματα ιδιοτήτων (πρόθεμα $)
SDKs
Για ευκολότερη ενσωμάτωση, χρησιμοποιήστε τα επίσημα SDK:
- Web SDK: Οδηγός ενσωμάτωσης
- iOS SDK: Swift Package / CocoaPods
- Android SDK: Gradle
- React Native SDK: npm install @joryio/react-native-sdk