Μετάβαση στο κύριο περιεχόμενο

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

Σώμα αιτήματος

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
userIdstringΝαι*Το δικό σας αναγνωριστικό χρήστη. *Απαιτείται ένα από τα userId, joryioUserId, anonymousId ή userAlias
eventNamestringΝαιΌνομα του συμβάντος (μέγιστο 255 χαρακτήρες)
propertiesobjectΌχιΙδιότητες συμβάντος (μέγιστο 200 κλειδιά ανώτατου επιπέδου, 50KB, βάθος ένθεσης 5)
timestampstring ή numberΌχιΧρονοσφραγίδα συμβάντος (συμβολοσειρά ISO 8601 ή epoch χιλιοστά· προεπιλογή η τρέχουσα στιγμή)
joryioUserIdstringΌχιΤο εσωτερικό ID χρήστη του Joryio - το 24-hex id που επιστρέφεται στις αποκρίσεις του user API (εναλλακτικό του userId)
anonymousIdstringΌχιID ανώνυμου επισκέπτη (εναλλακτικό αναγνωριστικό)
userAliasobjectΌχι{ aliasLabel, aliasName } - αναγνωριστικό ψευδωνύμου (εναλλακτικό του userId)
sessionIdstringΌχιΑναγνωριστικό συνεδρίας
deviceIdstringΌχιΑναγνωριστικό συσκευής
clientEventIdstringΌχι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

ΠαράμετροςΤύποςΠροεπιλογήΠεριγραφή
userIdstring-Φιλτράρισμα βάσει ID χρήστη
eventNamestring-Φιλτράρισμα βάσει ονόματος συμβάντος
startDatestring-Φιλτράρισμα συμβάντων μετά από αυτή την ημερομηνία (ISO 8601)
endDatestring-Φιλτράρισμα συμβάντων πριν από αυτή την ημερομηνία (ISO 8601)
limitnumber100Αποτελέσματα ανά σελίδα (μέγιστο 1000)
offsetnumber0Πλήθος συμβάντων που παραλείπονται

Παράδειγμα αιτήματος

# 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

Σώμα αιτήματος

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
eventNamestringΝαιΌνομα του συμβάντος προς συγκέντρωση
startDatestringΌχιΗμερομηνία έναρξης (ISO 8601)
endDatestringΌχιΗμερομηνία λήξης (ISO 8601)
groupBystringΌχιΧρονική ομαδοποίηση: hour, day, week, month (προεπιλογή: day)
metricsarrayΌχιΜετρικές προς υπολογισμό: count, sum, avg, min, max (προεπιλογή: ['count'])
sumFieldstringΌχιΌνομα του κλειδιού στο properties προς άθροιση/συγκέντρωση (π.χ. total)
avgFieldstringΌχιΌνομα του κλειδιού στο properties για μέσο όρο
eventPropertiesobjectΌχιΦιλτράρισμα βάσει ιδιοτήτων συμβάντος

Παράδειγμα αιτήματος

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

  1. Μεταβείτε στους Χρήστες → Βρείτε τον χρήστη
  2. Κάντε κλικ στην καρτέλα Δραστηριότητα
  3. Δείτε όλα τα καταγεγραμμένα συμβάντα

Συνήθη προβλήματα

Τα συμβάντα δεν εμφανίζονται:

  • Επαληθεύστε ότι το κλειδί API είναι σωστό
  • Ελέγξτε ότι ο χρήστης έχει ταυτοποιηθεί
  • Βεβαιωθείτε ότι το όνομα συμβάντος και οι ιδιότητες είναι έγκυρα
  • Ελέγξτε τα όρια ρυθμού

Οι ιδιότητες δεν εμφανίζονται:

  • Επαληθεύστε ότι τα ονόματα ιδιοτήτων είναι σωστά
  • Ελέγξτε ότι οι τύποι δεδομένων υποστηρίζονται
  • Αποφύγετε τα δεσμευμένα ονόματα ιδιοτήτων (πρόθεμα $)

SDKs

Για ευκολότερη ενσωμάτωση, χρησιμοποιήστε τα επίσημα SDK:


Επόμενα βήματα