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

Subscriptions API

Το Subscriptions API είναι η επιφάνεια συγκατάθεσης του Joryio. Διαχειρίζεται, ανά επαφή, την κατάσταση opt-in/opt-out κάθε καναλιού μηνυμάτων (email, SMS, WhatsApp, push, Viber), τη συμμετοχή σε λίστες συνδρομών (κατηγορίες συγκατάθεσης / θέματα), την κατάσταση bounce email και το πλήρες ιστορικό ελέγχου των αλλαγών συγκατάθεσης.

Αυτή η σελίδα καλύπτει τρεις πόρους:

  • Συγκατάθεση επαφής - /subscriptions/contacts/...: ανάγνωση και αλλαγή της συγκατάθεσης καναλιών και λιστών μίας επαφής.
  • Λίστες συνδρομών - /lists: δημιουργία και διαχείριση των ίδιων των λιστών, καθώς και μαζικές λειτουργίες συμμετοχής.
  • Φιλοξενούμενη σελίδα προτιμήσεων - /subscriptions/hosted-page: σύνταξη της φιλοξενούμενης σελίδας του κέντρου προτιμήσεων του χώρου εργασίας.

Όλα τα endpoints αυτής της σελίδας είναι σχετικά ως προς το βασικό URL: https://api-eu1.joryio.com/api - δείτε Επισκόπηση API.

Έλεγχος ταυτότητας​

Όλα τα αιτήματα απαιτούν έλεγχο ταυτότητας με κλειδί API (λειτουργεί και JWT συνεδρίας dashboard):

Authorization: Bearer jry_live_your_api_key_here
Content-Type: application/json

Scopes ανά endpoint​

EndpointScope
GET /subscriptions/contacts/:userIdsubscriptions:read or compliance:read
PUT /subscriptions/contacts/:userId/channels/:channelsubscriptions:write or compliance:write
POST /subscriptions/contacts/:userId/clear-bouncesubscriptions:write or compliance:write
GET /subscriptions/contacts/:userId/listssubscriptions:read or compliance:read
POST /subscriptions/contacts/:userId/lists/:listIdsubscriptions:write or compliance:write
DELETE /subscriptions/contacts/:userId/lists/:listIdsubscriptions:write or compliance:write
GET /subscriptions/contacts/:userId/historycompliance:read
GET /subscriptions/unsubscribe-reasonscompliance:read
GET /subscriptions/contacts/:userId/channels/:channel/statussubscriptions:read or compliance:read
GET /subscriptions/contacts/:userId/email-validsubscriptions:read or compliance:read
POST /listslists:write or settings:write
GET /lists, GET /lists/:listId, GET /lists/:listId/statslists:read or settings:read
GET /lists/:listId/memberscompliance:read
PUT /lists/:listId, DELETE /lists/:listId, POST /lists/:listId/restorelists:write or settings:write
POST /lists/:listId/members/bulk, DELETE /lists/:listId/members/bulklists:write or settings:write
GET /subscriptions/hosted-page/preference-center, POST /subscriptions/hosted-page/previewsettings:read
PUT /subscriptions/hosted-page/preference-centersettings:write

Δύο διαδρομές παραμένουν σκόπιμα κλειστές σε κλειδί API με τα scopes συνδρομών: το GET .../history είναι το ιστορικό συγκατάθεσης - αποδεικτικό για ρυθμιστική αρχή, όχι λειτουργική κατάσταση - και το GET /lists/:listId/members αποκαλύπτει επαφές. Και τα δύο διατηρούν μόνο compliance:read.

Βασικές έννοιες​

Το id επαφής​

Κάθε διαδρομή /subscriptions/contacts/:userId δέχεται το εσωτερικό id επαφής του Joryio - το id που επιστρέφει το Users API - όχι το εξωτερικό userId που στέλνετε στα συμβάντα. Πρέπει να είναι 24-χαρακτήρων δεκαεξαδικό ObjectId (ή UUID)· οτιδήποτε άλλο απορρίπτεται με 400 Bad Request.

Εγγραφή κατά τη δημιουργία​

Οι επαφές δημιουργούνται μέσω του POST /users/track, και η ίδια κλήση μπορεί να ορίσει τις συνδρομές τους σε λίστες: κάθε στοιχείο του attributes δέχεται subscriptions (λεπτομέρειες), που εφαρμόζονται μέσω της ίδιας διαδρομής συγκατάθεσης με τα endpoints αυτής της σελίδας. Τα αυτόνομα endpoints αυτής της σελίδας παραμένουν ο τρόπος διαχείρισης της συγκατάθεσης μετά τη δημιουργία: ορίστε τη συγκατάθεση καναλιού με PUT /subscriptions/contacts/:userId/channels/:channel και τη συμμετοχή σε λίστες με POST /subscriptions/contacts/:userId/lists/:listId. Οι εγγραφές κατά τη δημιουργία δεν αναιρούν ποτέ ένα υπάρχον opt-out - μια ρητή επανεγγραφή (re-opt-in) πρέπει να γίνει με POST /subscriptions/contacts/:userId/lists/:listId.

Κανάλια​

Υπάρχουν πέντε κανάλια συνδρομών: email, sms, whatsapp, push, viber. Οποιαδήποτε άλλη τιμή καναλιού επιστρέφει 400 Bad Request.

Τιμές κατάστασης​

ΚατάστασηΠεριγραφή
optedInΡητό opt-in (π.χ. επιβεβαιωμένο double opt-in)
subscribedΕγγεγραμμένος (single opt-in / προεπιλογή)
unsubscribedΑπεγγραμμένος
pendingΑναμένει επιβεβαίωση: ζήτησε εγγραφή αλλά δεν έχει επιβεβαιώσει ακόμη το double opt-in. Δεν λαμβάνει μηνύματα μέχρι να επιβεβαιώσει· η επιβεβαίωση το κάνει subscribed. Ορίζεται από ροή επιβεβαίωσης (π.χ. double opt-in της Delivyr), ποτέ από τα SDK.

Οι τιμές κατάστασης είναι σε camelCase - optedIn, όχι opted_in. Μια επαφή χωρίς καταγεγραμμένη κατάσταση για ένα κανάλι αντιμετωπίζεται από τις πύλες αποστολής ως εγγεγραμμένη («καμία εγγραφή» δεν είναι opt-out).

Οι αλλαγές συγκατάθεσης ελέγχονται και αντικατοπτρίζονται​

Κάθε εγγραφή μέσω αυτού του API καταγράφεται στο ημερολόγιο ελέγχου συνδρομών της επαφής (με πηγή, διεύθυνση IP, user agent και την ταυτότητα του ενεργούντος κλειδιού API / διαχειριστή) και ανακτάται μέσω του endpoint ιστορικού. Τα opt-out αντικατοπτρίζονται επιπλέον σε λίστες καταστολής με κλειδί το αναγνωριστικό - μια απεγγραφή SMS/WhatsApp ακολουθεί τον αριθμό τηλεφώνου και μια απεγγραφή email ακολουθεί τη διεύθυνση (σε όλο τον χώρο εργασίας), ώστε να καλύπτονται και διπλότυπες επαφές που μοιράζονται το αναγνωριστικό. Δείτε το Suppressions API.


Συγκατάθεση επαφής​

Λήψη συνδρομών επαφής​

Επιστρέφει την κατάσταση συγκατάθεσης ανά κανάλι μιας επαφής, μαζί με τις συμμετοχές της σε λίστες.

Endpoint​

GET /subscriptions/contacts/:userId

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

ΠαράμετροςΤύποςΠεριγραφή
userIdstringId επαφής Joryio

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

curl -X GET https://api-eu1.joryio.com/api/subscriptions/contacts/665f1c2ab3d4e5f6a7b8c9d0 \
-H "Authorization: Bearer jry_live_your_api_key"

Απόκριση​

{
"channels": {
"email": {
"status": "subscribed",
"optInDate": "2026-05-14T09:21:07.000Z",
"optInSource": "api",
"consentText": "Send me product updates",
"isValid": true,
"bounceType": null,
"bounceCount": 0
},
"sms": {
"status": "unsubscribed",
"optOutDate": "2026-06-02T18:40:00.000Z",
"optInSource": "preference_center"
}
},
"lists": [
{
"_id": "665f2e11aa22bb33cc44dd55",
"organizationId": "org-uuid",
"workspaceId": "ws-uuid",
"contactId": "665f1c2ab3d4e5f6a7b8c9d0",
"listId": "3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b",
"channel": "email",
"status": "subscribed",
"subscribedAt": "2026-05-14T09:21:07.000Z",
"optInSource": "api",
"createdAt": "2026-05-14T09:21:07.000Z",
"updatedAt": "2026-05-14T09:21:07.000Z"
}
]
}

Τα κανάλια για τα οποία η επαφή δεν έχει καταγεγραμμένη κατάσταση απλώς απουσιάζουν από το channels. Το κανάλι email φέρει τα επιπλέον πεδία bounce (isValid, bounceType, bounceCount, lastBounceAt). Το lists επιστρέφει τις πρώτες 500 γραμμές συμμετοχής της επαφής.

Επιστρέφει 404 Not Found αν η επαφή δεν υπάρχει στον χώρο εργασίας.


Ενημέρωση συνδρομής καναλιού​

Ορίστε την κατάσταση συγκατάθεσης μιας επαφής για ένα κανάλι.

Endpoint​

PUT /subscriptions/contacts/:userId/channels/:channel

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

ΠαράμετροςΤύποςΠεριγραφή
userIdstringId επαφής Joryio
channelstringemail, sms, whatsapp, push ή viber

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

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
channelstringΝαιΠρέπει να ταιριάζει με το κανάλι του URL (αν διαφέρουν, υπερισχύει η τιμή του URL)
statusstringΝαιoptedIn, subscribed ή unsubscribed. Γίνεται δεκτό και το pending (αναμένει επιβεβαίωση).
sourcestringΌχιΑπό πού προήλθε η αλλαγή, π.χ. api, preference_center (προεπιλογή api)
consentTextstringΌχιΤο κείμενο συγκατάθεσης που εμφανίστηκε στο opt-in (αποθηκεύεται για συμμόρφωση)
reasonstringΌχιΛόγος σε ελεύθερο κείμενο, αποθηκεύεται στην εγγραφή του ημερολογίου ελέγχου

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

curl -X PUT https://api-eu1.joryio.com/api/subscriptions/contacts/665f1c2ab3d4e5f6a7b8c9d0/channels/email \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"channel": "email",
"status": "unsubscribed",
"source": "preference_center",
"reason": "User requested via support ticket"
}'

Απόκριση​

Το πλήρες ενημερωμένο αντικείμενο channels της επαφής:

{
"email": {
"status": "unsubscribed",
"optOutDate": "2026-07-12T10:15:00.000Z",
"optInSource": "preference_center",
"isValid": true,
"bounceType": null,
"bounceCount": 0
},
"sms": {
"status": "subscribed",
"optInDate": "2026-05-14T09:21:07.000Z"
}
}

Σημειώσεις συμπεριφοράς​

  • Ένα opt-in στο κανάλι email καθαρίζει την προσωρινή κατάσταση soft bounce, αλλά δεν αναβιώνει ποτέ hard bounce ή καταγγελία spam - μόνο η υποστήριξη του Joryio μπορεί να τα άρει.
  • Ένα unsubscribed σε sms/whatsapp αντικατοπτρίζεται στη λίστα καταστολής με κλειδί τον αριθμό τηλεφώνου (το opt-out ακολουθεί τον αριθμό, σε επίπεδο οργανισμού). Μια αλλαγή κατάστασης email αντικατοπτρίζεται στη λίστα με κλειδί τη διεύθυνση για τον χώρο εργασίας.
  • Η αλλαγή καταγράφεται στο ημερολόγιο ελέγχου με IP, user agent και την ταυτότητα του ενεργούντος διαχειριστή/κλειδιού.

Double opt-in για SMS​

Όταν ο χώρος εργασίας έχει ενεργοποιήσει το Double opt-in για SMS (Ρυθμίσεις > Συνδρομές), ένα PUT .../channels/sms με subscribed ή optedIn για επαφή χωρίς κατάσταση SMS δεν την εγγράφει: η κατάσταση αποθηκεύεται ως pending και η επαφή λαμβάνει ένα μήνυμα "Reply YES". Η απάντηση το δείχνει:

{ "sms": { "status": "pending", "optInSource": "api", "confirmation": { "requestedAt": "2026-10-17T10:00:00.000Z", "expiresAt": "2026-10-24T10:00:00.000Z", "sentAt": "2026-10-17T10:00:01.000Z" } } }
  • Η επαφή γίνεται subscribed (με optInSource: "double_opt_in") μόνο απαντώντας YES (ή START, ή άλλη λέξη εγγραφής) στον αριθμό σας. Καμία κλήση API δεν επιβεβαιώνει επαφή σε αναμονή (409).
  • Νέο αίτημα ενώ η επαφή είναι pending επιστρέφει 200 με το ίδιο ανοιχτό αίτημα - χωρίς δεύτερο μήνυμα.
  • Μια επαφή που έκανε διαγραφή, ή που ο αριθμός της έχει διαγραφή, αντιμετωπίζεται ως νέα εγγραφή (απόφαση ιδιοκτήτη 2026-10-17): pending και ΕΝΑ μήνυμα επιβεβαίωσης, εγγραφή μόνο μετά το YES· χωρίς απάντηση λήγει πίσω σε unsubscribed και δεν στέλνεται τίποτε άλλο. Μια επαφή που είχε στείλει STOP λαμβάνει επίσης τη συνήθη εγγραφή warnings sms_stop_provider_block· αν ο πάροχος απορρίψει το μήνυμα με τον κωδικό STOP του, η επαφή διαγράφεται ξανά. Μια μόνιμη αναπήδηση, καταγγελία spam ή αποκλεισμός σε επίπεδο οργανισμού εξακολουθεί να απορρίπτεται (409).
  • Αιτήματα χωρίς απάντηση λήγουν μετά τις ημέρες που ορίστηκαν (προεπιλογή 7): η κατάσταση SMS αφαιρείται (όχι unsubscribed).
  • Δεν εφαρμόζεται όταν ο αριθμός SMS του χώρου εργασίας είναι σε λογαριασμό Delivyr - το Delivyr έχει δικό του double opt-in.

Δείτε Double opt-in για SMS.


Διπλότυπες επαφές και επανεγγραφή​

  • Μια διαγραφή ισχύει για κάθε επαφή με το ίδιο email ή τηλέφωνο στο workspace: η κατάσταση καθεμίας (ή η συμμετοχή, για λίστα) γίνεται unsubscribed και παίρνει εγγραφή ιστορικού με πηγή shared_identifier.
  • Η επανεγγραφή μέσω API επιτρέπεται και ισχύει μόνο για αυτή την επαφή. Οι άλλες επαφές με το ίδιο email ή τηλέφωνο παραμένουν διαγραμμένες. Η αλλαγή καταγράφεται με πηγή api και το id του API key στο metadata.principal.
  • Ένα source στο σώμα που τελειώνει σε _keyword, ή είναι shared_identifier, complaint_webhook ή staff, καταγράφεται ως api - μόνο το Joryio ορίζει αυτές τις τιμές.
  • Μια διαγραφή STOP μπορεί να παρακαμφθεί (SMS, WhatsApp, Viber, οποιοσδήποτε πάροχος) με αυτή την κανονική ενημέρωση - χωρίς επιπλέον flag. Ισχύει μόνο για αυτή την επαφή, και το ιστορικό καταγράφει ότι παρέκαμψε ένα STOP (metadata.overrodeStop) και το κλειδί API. Μια απάντηση START συνεχίζει να λειτουργεί όπως πριν.
  • Μόνο SMS: η επανεγγραφή επαφής SMS που έστειλε STOP απαντά 200 OK με ένα πεδίο warnings που δεν είναι σφάλμα, επειδή ο πάροχος SMS μπορεί να κρατήσει δικό του μπλοκάρισμα μέχρι η επαφή να στείλει START. Το WhatsApp και το Viber δεν επιστρέφουν προειδοποίηση. Το endpoint λιστών (POST /subscriptions/contacts/:userId/lists/:listId, για λίστα SMS) και το endpoint καναλιού του SDK επιστρέφουν το ίδιο πεδίο.
{
"sms": { "status": "subscribed", "optInSource": "api" },
"warnings": [
{
"code": "sms_stop_provider_block",
"channel": "sms",
"message": "This contact opted out by texting STOP. Your SMS provider may keep blocking messages until they text START."
}
]
}
  • Μια αποστολή που ο πάροχος SMS στη συνέχεια απορρίπτει λόγω του δικού του μπλοκαρίσματος STOP (για παράδειγμα Twilio 21610 ή απόρριψη opted-out του Delivyr) καταγράφεται ως μπλοκαρισμένη από τον πάροχο (διαγραμμένη) - όχι αποτυχία, και δεν μετρά στις ειδοποιήσεις ποσοστού bounce ή αποτυχιών. Η διαγραφή εφαρμόζεται ξανά, με τη σημείωση ιστορικού provider still blocks: re-opted out.
  • Κάποιοι αποκλεισμοί δεν αίρονται με επανεγγραφή. Το αίτημα απορρίπτεται με 409 Conflict και τίποτα δεν αλλάζει:
codemessage
deliverabilityThis address hard-bounced or marked a message as spam. Only Joryio support can lift that block.
organization_blockThis identifier is blocked for the whole organization. Only Joryio support can lift that block.
verified_identity_required403 - Μόνο endpoints του SDK (/v1/subscriptions/channel, /v1/subscriptions/group): επανεγγραφή προσώπου που διαγράφηκε ρητά (δική του διαγραφή ή από λίστα, STOP, διαγραφή στο email ή στο τηλέφωνό του - και από άλλη επαφή) από μη επαληθευμένο υποκείμενο - ένα userId χωρίς SDK Authentication, ή ένα anonymousId που ανήκει σε ταυτοποιημένο πρόσωπο. Η πρώτη εγγραφή γίνεται δεκτή· μια λίστα με διπλό opt-in απαντά pending: true και στέλνει το email επιβεβαίωσης. Η διαγραφή επιτρέπεται πάντα.
{ "statusCode": 409, "error": "Conflict", "code": "deliverability", "message": "This address hard-bounced or marked a message as spam. Only Joryio support can lift that block." }

Το endpoint λιστών (POST /subscriptions/contacts/:userId/lists/:listId) δεν απορρίπτεται ποτέ για αυτά· ούτε μια εγγραφή σε λίστα τα αίρει. Επαφές που μοιράζονται email ή τηλέφωνο.

Καθαρισμός κατάστασης bounce​

Μηδενίζει τους μετρητές soft bounce μιας επαφής. Ένα hard bounce ή μια καταγγελία spam αίρεται μόνο από την υποστήριξη του Joryio: όταν η διεύθυνση έχει κάποιο, το αίτημα απορρίπτεται με 403 και code: "deliverability".

Endpoint​

POST /subscriptions/contacts/:userId/clear-bounce

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

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
reasonstringΌχιΛόγος σε ελεύθερο κείμενο, αποθηκεύεται στην εγγραφή του ημερολογίου ελέγχου

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

curl -X POST https://api-eu1.joryio.com/api/subscriptions/contacts/665f1c2ab3d4e5f6a7b8c9d0/clear-bounce \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "reason": "Mailbox restored, confirmed with customer" }'

Απόκριση​

{ "success": true }

Καθαρίζει τα bounceType, bounceCount και lastBounceAt ενός soft bounce. Δεν διαγράφει γραμμές hard_bounce / complaint από το μητρώο καταστολών.


Λήψη συνδρομών σε λίστες​

Επιστρέφει όλες τις γραμμές συμμετοχής μιας επαφής σε λίστες (εγγεγραμμένες και απεγγραμμένες).

Endpoint​

GET /subscriptions/contacts/:userId/lists

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

curl -X GET https://api-eu1.joryio.com/api/subscriptions/contacts/665f1c2ab3d4e5f6a7b8c9d0/lists \
-H "Authorization: Bearer jry_live_your_api_key"

Απόκριση​

[
{
"_id": "665f2e11aa22bb33cc44dd55",
"organizationId": "org-uuid",
"workspaceId": "ws-uuid",
"contactId": "665f1c2ab3d4e5f6a7b8c9d0",
"listId": "3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b",
"channel": "email",
"status": "subscribed",
"subscribedAt": "2026-05-14T09:21:07.000Z",
"optInSource": "api",
"createdAt": "2026-05-14T09:21:07.000Z",
"updatedAt": "2026-05-14T09:21:07.000Z"
}
]

Η συμμετοχή είναι μοναδική ανά επαφή + λίστα + κανάλι: η ίδια επαφή μπορεί να είναι εγγεγραμμένη σε μια λίστα στο email και απεγγραμμένη από αυτήν στο sms, ως δύο ξεχωριστές γραμμές.


Εγγραφή επαφής σε λίστα​

Εγγράψτε μια επαφή σε μια λίστα σε ένα κανάλι. Είναι idempotent - η επανάληψη της κλήσης επιβεβαιώνει ξανά τη συνδρομή. Είναι επίσης η ρητή, ελεγχόμενη διαδρομή opt-in που μπορεί να επανεγγράψει μια επαφή που είχε προηγουμένως απεγγραφεί από τη λίστα (η μαζική προσθήκη δεν το κάνει ποτέ).

Endpoint​

POST /subscriptions/contacts/:userId/lists/:listId

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

ΠαράμετροςΤύποςΠεριγραφή
userIdstringId επαφής Joryio
listIdstringId λίστας συνδρομών (UUID)

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

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
channelstringΝαιemail, sms, whatsapp, push ή viber
sourcestringΌχιπ.χ. api, form, import, preference_center (προεπιλογή api)
consentTextstringΌχιΚείμενο συγκατάθεσης που εμφανίστηκε στο opt-in

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

curl -X POST https://api-eu1.joryio.com/api/subscriptions/contacts/665f1c2ab3d4e5f6a7b8c9d0/lists/3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "channel": "email", "source": "api", "consentText": "Weekly newsletter signup" }'

Απόκριση​

Η γραμμή συμμετοχής που δημιουργήθηκε ή ενημερώθηκε:

{
"_id": "665f2e11aa22bb33cc44dd55",
"organizationId": "org-uuid",
"workspaceId": "ws-uuid",
"contactId": "665f1c2ab3d4e5f6a7b8c9d0",
"listId": "3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b",
"channel": "email",
"status": "subscribed",
"subscribedAt": "2026-07-12T10:20:00.000Z",
"optInSource": "api",
"consentText": "Weekly newsletter signup",
"createdAt": "2026-07-12T10:20:00.000Z",
"updatedAt": "2026-07-12T10:20:00.000Z"
}

Απεγγραφή επαφής από λίστα​

Απεγγράψτε μια επαφή από μια λίστα σε ένα κανάλι. Το κανάλι περνά στο σώμα του αιτήματος, όχι στο URL.

Endpoint​

DELETE /subscriptions/contacts/:userId/lists/:listId

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

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
channelstringΝαιemail, sms, whatsapp, push ή viber
sourcestringΌχιπ.χ. api, preference_center (προεπιλογή api)

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

curl -X DELETE https://api-eu1.joryio.com/api/subscriptions/contacts/665f1c2ab3d4e5f6a7b8c9d0/lists/3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "channel": "email", "source": "preference_center" }'

Απόκριση​

{ "success": true }

Αν η επαφή δεν είχε γραμμή συμμετοχής για αυτή τη λίστα + κανάλι, δημιουργείται έτσι κι αλλιώς μια ρητή γραμμή unsubscribed - μια ανάκληση συγκατάθεσης δεν χάνεται ποτέ σιωπηλά, και η πύλη αποστολής θα αποκλείει από εκεί και πέρα τις αποστολές λίστας προς αυτή την επαφή.


Λήψη ιστορικού συνδρομών​

Επιστρέφει το ημερολόγιο ελέγχου συγκατάθεσης της επαφής, με τις νεότερες εγγραφές πρώτες.

Endpoint​

GET /subscriptions/contacts/:userId/history

Παράμετροι query​

ΠαράμετροςΤύποςΠροεπιλογήΠεριγραφή
limitnumber50Εγγραφές ανά σελίδα (μη αριθμητικές τιμές επιστρέφουν στην προεπιλογή)
offsetnumber0Μετατόπιση σελιδοποίησης

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

curl -X GET "https://api-eu1.joryio.com/api/subscriptions/contacts/665f1c2ab3d4e5f6a7b8c9d0/history?limit=50&offset=0" \
-H "Authorization: Bearer jry_live_your_api_key"

Απόκριση​

{
"items": [
{
"id": "8a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"organizationId": "org-uuid",
"workspaceId": "ws-uuid",
"contactId": "665f1c2ab3d4e5f6a7b8c9d0",
"channel": "email",
"listId": null,
"action": "unsubscribe",
"previousStatus": "subscribed",
"newStatus": "unsubscribed",
"source": "preference_center",
"ipAddress": "203.0.113.7",
"userAgent": "Mozilla/5.0 ...",
"consentText": null,
"metadata": { "reason": "User requested via support ticket", "unsubscribeSource": "preferences_page", "sinceSendMs": 3600000 },
"createdAt": "2026-07-12T10:15:00.000Z",
"changeKind": "unsubscribed",
"changeLabel": "Unsubscribed",
"sourceKind": "preference_center",
"sourceLabel": "Preference center",
"sourcePlatform": null,
"page": null
}
],
"total": 12
}

Το action είναι ένα από τα subscribe, unsubscribe, resubscribe, bounce, hard_bounce, soft_bounce, complaint, import, api_update. Το listId ορίζεται για αλλαγές επιπέδου λίστας και είναι null για αλλαγές επιπέδου καναλιού.

Κάθε εγγραφή unsubscribe από τις 2026-10-15 φέρει metadata.unsubscribeSource - πώς έφτασε: header_one_click, page_button, preferences_page, page_everything, api, admin, sdk, import, keyword, complaint, esp_unsubscribe, store_sync, other. Το header_one_click είναι το κουμπί διαγραφής της ίδιας της εφαρμογής email (RFC 8058)· το page_button είναι ένα άτομο που πάτησε Κατάργηση εγγραφής στη φιλοξενούμενη σελίδα. Όταν το μήνυμα είναι γνωστό, το metadata.sinceSendMs είναι ο χρόνος από την αποστολή του έως τη διαγραφή. Το userAgent αποθηκεύεται χωρίς χαρακτήρες ελέγχου και περικομμένο στους 256 χαρακτήρες. Οι εγγραφές με metadata.pageMode auto έγιναν από τη φιλοξενούμενη σελίδα χωρίς κλικ, μεταξύ 2026-10-11 και 2026-10-15.

Απόδειξη συναίνεσης (από 2026-11-02). Κάθε καταχώριση φέρει επίσης changeKind / changeLabel - τι έκανε η αλλαγή: subscribed, resubscribed, unsubscribed, pending_order (επιλογή στο ταμείο καταστήματος σε αναμονή έως παραγγελία ή τον σύνδεσμο επιβεβαίωσης), pending_confirmation, withdrawn (αποεπιλέχθηκε στο ίδιο ταμείο), confirmed_by_order, confirmed, confirmation_expired, bounce, complaint, import, updated - και sourceKind / sourceLabel / sourcePlatform - από πού ήρθε: store_checkout, store_registration, store_customer_record, store_newsletter, store_sync (με sourcePlatform woocommerce, shopify, magento ή prestashop), landing_page, in_app_form, website_form, api, admin, sdk, import, unsubscribe_link, preference_center, bounce, complaint, keyword_stop, keyword_start, double_opt_in, push_permission, journey, email_provider, shared_identifier, contact_merge (κατάσταση που μεταφέρθηκε κατά τη συγχώνευση δύο επαφών), support, other. Τα πεδία *Label είναι διατυπώσεις στα αγγλικά. Το page είναι η σελίδα όπου δόθηκε η συναίνεση, όπου αποθηκεύτηκε (URL σελίδας ή καταστήματος, ή slug σελίδας προορισμού), αλλιώς null. Το consentText είναι η ακριβής διατύπωση που είδε το άτομο. Το ipAddress είναι προσωπικό δεδομένο: καλών χωρίς pii:view (κλειδί API μόνο με αυτό το scope) λαμβάνει null και ipHidden: true όταν είχε αποθηκευτεί. Το location είναι το σημείο του καταστήματος όπου συλλέχθηκε η συναίνεση - checkout, block_checkout, registration, customer_record ή newsletter - και το collectedAt πότε συλλέχθηκε (ISO-8601, με το ρολόι του καταστήματος· μπορεί να είναι νωρίτερα από το createdAt όταν η επιλογή κρατήθηκε μέχρι την παραγγελία)· και τα δύο null όταν δεν καταγράφηκαν.


Λίστα πρόσφατων αιτιών απεγγραφής​

Οι πρόσφατες απεγγραφές του χώρου εργασίας που έχουν αιτία ή επισημάνθηκαν ως πιθανώς αυτόματες, με τις νεότερες πρώτες. Μία γραμμή ανά ενέργεια απεγγραφής: όταν μία ενέργεια αφαίρεσε πολλά κανάλια (π.χ. ένας παλιός σύνδεσμος που αφαίρεσε τα πάντα), τα κανάλια ομαδοποιούνται σε μία γραμμή.

Endpoint​

GET /subscriptions/unsubscribe-reasons

Παράμετροι ερωτήματος​

ΠαράμετροςΤύποςΠροεπιλογήΠεριγραφή
limitnumber50Γραμμές ανά σελίδα (μέγιστο 100)
offsetnumber0Μετατόπιση σελιδοποίησης
daysnumber90Πόσες ημέρες πίσω (μέγιστο 365)
flaggedbooleanfalseΤο true επιστρέφει μόνο απεγγραφές που επισημάνθηκαν ως πιθανώς αυτόματες

Παράδειγμα αιτήματος και απόκρισης​

curl -X GET "https://api-eu1.joryio.com/api/subscriptions/unsubscribe-reasons?limit=50&offset=0&days=90" \
-H "Authorization: Bearer jry_live_your_api_key"
{
"items": [
{
"at": "2026-10-11T09:12:44.000Z",
"contactId": "665f1c2ab3d4e5f6a7b8c9d0",
"email": "[email protected]",
"name": "Dana Levi",
"channels": ["email"],
"listId": null,
"reason": "too_frequent",
"campaignId": "3f2a1b0c-9d8e-4f7a-b6c5-d4e3f2a1b0c9",
"source": "one_click",
"suspectedAutomatic": false,
"suspectedAutomaticReasons": []
}
],
"total": 37
}

Το reason είναι η αιτία που επέλεξε το άτομο στη σελίδα προτιμήσεων (null όταν δεν δόθηκε). Το suspectedAutomatic είναι true όταν η απεγγραφή έγινε στη φιλοξενούμενη σελίδα μέσα σε 10 δευτερόλεπτα από την αποστολή του μηνύματος ή όταν το αίτημα έμοιαζε με κίνηση σαρωτή· το suspectedAutomaticReasons λέει ποιο από τα δύο. Η ίδια επισήμανση αποθηκεύεται στο metadata της εγγραφής ελέγχου (δείτε Λήψη ιστορικού συνδρομών). Το name ακολουθεί τους κανόνες pii:view: χωρίς αυτό το δικαίωμα επιστρέφεται καλυμμένο. Απαιτεί compliance:read.


Έλεγχος κατάστασης συνδρομής καναλιού​

Ελαφρύς boolean έλεγχος - μπορεί η επαφή να λάβει μηνύματα σε αυτό το κανάλι από πλευράς συγκατάθεσης;

Endpoint​

GET /subscriptions/contacts/:userId/channels/:channel/status

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

curl -X GET https://api-eu1.joryio.com/api/subscriptions/contacts/665f1c2ab3d4e5f6a7b8c9d0/channels/email/status \
-H "Authorization: Bearer jry_live_your_api_key"

Απόκριση​

{ "subscribed": true }

Το subscribed είναι true εκτός αν η επαφή είναι ρητά unsubscribed στο κανάλι - μια επαφή χωρίς καταγεγραμμένη κατάσταση μετρά ως εγγεγραμμένη. Ένα άγνωστο id επαφής επιστρέφει { "subscribed": false } (όχι 404).


Έλεγχος εγκυρότητας email​

Είναι η διεύθυνση email της επαφής παραδόσιμη (δεν έχει επισημανθεί ως μη έγκυρη από hard bounce);

Endpoint​

GET /subscriptions/contacts/:userId/email-valid

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

curl -X GET https://api-eu1.joryio.com/api/subscriptions/contacts/665f1c2ab3d4e5f6a7b8c9d0/email-valid \
-H "Authorization: Bearer jry_live_your_api_key"

Απόκριση​

{ "valid": true }

Το valid είναι false μόνο όταν ένα hard bounce έχει επισημάνει τη διεύθυνση ως μη έγκυρη. Ένα άγνωστο id επαφής επιστρέφει { "valid": false } (όχι 404). Σημειώστε ότι αυτό αντανακλά παραδοσιμότητα, όχι συγκατάθεση - μια απεγγραμμένη επαφή με λειτουργική διεύθυνση εξακολουθεί να επιστρέφει true.


Λίστες συνδρομών​

Οι λίστες είναι οι κατηγορίες συγκατάθεσης / τα θέματα στα οποία μπορούν να εγγραφούν οι επαφές (newsletter, ενημερώσεις προϊόντος κ.ο.κ.). Οι ορισμοί των λιστών βρίσκονται κάτω από το /lists· η συμμετοχή ανά επαφή διαχειρίζεται με τα endpoints συγκατάθεσης επαφής παραπάνω ή με τα μαζικά endpoints παρακάτω.

Δημιουργία λίστας​

Endpoint​

POST /lists

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

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
namestringΝαιΌνομα λίστας (μέγιστο 255 χαρακτήρες, μοναδικό ανά χώρο εργασίας)
descriptionstringΌχιΠεριγραφή (μέγιστο 1000 χαρακτήρες)
channelsstring[]ΌχιΚανάλια στα οποία ισχύει η λίστα (προεπιλογή ["email"])
isPublicbooleanΌχιΕμφάνιση στο κέντρο προτιμήσεων (προεπιλογή true)
typestringΌχιmarketing ή transactional (προεπιλογή marketing)
requireDoubleOptInbooleanΌχιΑπαίτηση επιβεβαιωμένου opt-in (προεπιλογή false)

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

curl -X POST https://api-eu1.joryio.com/api/lists \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Weekly Newsletter",
"description": "Our weekly digest of product updates",
"channels": ["email"],
"isPublic": true,
"type": "marketing",
"requireDoubleOptIn": false
}'

Απόκριση​

{
"id": "3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b",
"organizationId": "org-uuid",
"workspaceId": "ws-uuid",
"name": "Weekly Newsletter",
"description": "Our weekly digest of product updates",
"channels": ["email"],
"isPublic": true,
"type": "marketing",
"requireDoubleOptIn": false,
"isDefault": false,
"displayOrder": 0,
"senderId": null,
"archivedAt": null,
"createdAt": "2026-07-12T10:30:00.000Z",
"updatedAt": "2026-07-12T10:30:00.000Z"
}

Το isDefault επισημαίνει την αυτόματα δημιουργημένη προεπιλεγμένη κατηγορία Μάρκετινγκ· το senderId ορίζεται όταν η λίστα είναι ομάδα συνδρομών SMS/WhatsApp ανά αριθμό, δεσμευμένη σε συγκεκριμένο αποστολέα.


Λίστα όλων των λιστών​

Endpoint​

GET /lists

Παράμετροι query​

ΠαράμετροςΤύποςΠροεπιλογήΠεριγραφή
includeArchivedstringfalseΠεράστε true για να συμπεριληφθούν οι αρχειοθετημένες λίστες

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

curl -X GET "https://api-eu1.joryio.com/api/lists?includeArchived=false" \
-H "Authorization: Bearer jry_live_your_api_key"

Απόκριση​

Πίνακας αντικειμένων λιστών (ίδια μορφή με τη Δημιουργία λίστας), με τις νεότερες πρώτες, με όριο τις 200.


Λήψη λίστας​

GET /lists/:listId

Επιστρέφει το αντικείμενο της λίστας. 404 Not Found αν η λίστα δεν υπάρχει ή είναι αρχειοθετημένη.


Ενημέρωση λίστας​

PUT /lists/:listId

Σώμα: οποιοδήποτε υποσύνολο των πεδίων της Δημιουργίας λίστας (name, description, channels, isPublic, type, requireDoubleOptIn). Επιστρέφει το ενημερωμένο αντικείμενο της λίστας.


Αρχειοθέτηση λίστας​

DELETE /lists/:listId

Ήπια διαγραφή - ορίζει το archivedAt· οι γραμμές συμμετοχής διατηρούνται. Επιστρέφει 204 No Content. Επαναφέρετε με:

POST /lists/:listId/restore

που επιστρέφει το επαναφερμένο αντικείμενο της λίστας.


Λήψη μελών λίστας​

Endpoint​

GET /lists/:listId/members

Παράμετροι query​

ΠαράμετροςΤύποςΠροεπιλογήΠεριγραφή
channelstring-Προαιρετικό φίλτρο: email, sms, whatsapp, push, viber
statusstring-Προαιρετικό φίλτρο: subscribed ή unsubscribed
limitnumber50Γραμμές ανά σελίδα
offsetnumber0Μετατόπιση σελιδοποίησης

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

curl -X GET "https://api-eu1.joryio.com/api/lists/3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b/members?channel=email&status=subscribed&limit=50" \
-H "Authorization: Bearer jry_live_your_api_key"

Απόκριση​

{
"members": [
{
"_id": "665f2e11aa22bb33cc44dd55",
"contactId": "665f1c2ab3d4e5f6a7b8c9d0",
"listId": "3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b",
"channel": "email",
"status": "subscribed",
"subscribedAt": "2026-05-14T09:21:07.000Z",
"optInSource": "api",
"organizationId": "org-uuid",
"workspaceId": "ws-uuid",
"createdAt": "2026-05-14T09:21:07.000Z",
"updatedAt": "2026-05-14T09:21:07.000Z"
}
],
"total": 1234
}

Λήψη στατιστικών λίστας​

Endpoint​

GET /lists/:listId/stats

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

curl -X GET https://api-eu1.joryio.com/api/lists/3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b/stats \
-H "Authorization: Bearer jry_live_your_api_key"

Απόκριση​

{
"total": 1500,
"byChannel": {
"email": 1180,
"sms": 120,
"whatsapp": 0,
"push": 0,
"viber": 0
},
"subscribed": 1300,
"unsubscribed": 200
}

Το byChannel μετρά τις μη απεγγραμμένες συμμετοχές ανά κανάλι.


Μαζική προσθήκη μελών​

Προσθέστε έως 10.000 επαφές σε μια λίστα σε ένα κανάλι με μία κλήση.

Endpoint​

POST /lists/:listId/members/bulk

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

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
contactIdsstring[]ΝαιIds επαφών Joryio (μέγιστο 10.000)
channelstringΝαιemail, sms, whatsapp, push ή viber
sourcestringΌχιΚαταγράφεται ως το optInSource της συμμετοχής

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

curl -X POST https://api-eu1.joryio.com/api/lists/3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b/members/bulk \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"contactIds": ["665f1c2ab3d4e5f6a7b8c9d0", "665f1c2ab3d4e5f6a7b8c9d1"],
"channel": "email",
"source": "import"
}'

Απόκριση​

{ "added": 2, "updated": 0, "skippedUnsubscribed": 0 }

Η μαζική προσθήκη δημιουργεί μόνο εντελώς νέες συμμετοχές. Οι επαφές που είναι ήδη στη λίστα μένουν ανέγγιχτες, και οι επαφές που απεγγράφηκαν ρητά δεν επανεγγράφονται ποτέ από μαζική προσθήκη - μετριούνται στο skippedUnsubscribed. Η επανεγγραφή μιας απεγγραμμένης επαφής απαιτεί τη ρητή, ελεγχόμενη κλήση Εγγραφή επαφής σε λίστα. Το updated είναι πάντα 0 (διατηρείται για συμβατότητα προς τα πίσω).


Μαζική αφαίρεση μελών​

Απεγγράψτε έως 10.000 επαφές από μια λίστα σε ένα κανάλι.

Endpoint​

DELETE /lists/:listId/members/bulk

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

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
contactIdsstring[]ΝαιIds επαφών Joryio (μέγιστο 10.000)
channelstringΝαιemail, sms, whatsapp, push ή viber

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

curl -X DELETE https://api-eu1.joryio.com/api/lists/3f6c1a2e-9d4b-4f0a-8c7e-1b2d3e4f5a6b/members/bulk \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"contactIds": ["665f1c2ab3d4e5f6a7b8c9d0"],
"channel": "email"
}'

Απόκριση​

{ "removed": 1 }

Η αφαίρεση μετατρέπει τις υπάρχουσες γραμμές συμμετοχής σε unsubscribed (οι γραμμές διατηρούνται για το ίχνος ελέγχου), οπότε οι αφαιρεμένες επαφές αποκλείονται από μελλοντικές αποστολές λίστας.


Φιλοξενούμενη σελίδα προτιμήσεων​

API σύνταξης για τη φιλοξενούμενη σελίδα του κέντρου προτιμήσεων του χώρου εργασίας - τη σελίδα στην οποία καταλήγουν οι παραλήπτες από έναν σύνδεσμο απεγγραφής/προτιμήσεων. Η δημόσια απόδοση της σελίδας εξυπηρετείται από τα δημόσια endpoints με token (χωρίς κλειδί API), τα οποία δεν αποτελούν μέρος αυτής της αναφοράς.

Λήψη του προτύπου του κέντρου προτιμήσεων​

GET /subscriptions/hosted-page/preference-center

Απόκριση​

{
"type": "preference_center",
"mode": "default",
"html": "",
"redirectUrl": "",
"designJson": null,
"updatedAt": null
}

Το mode είναι ένα από τα default (η ενσωματωμένη σελίδα του Joryio), custom (το δικό σας πρότυπο HTML/Liquid), dnd (συντάχθηκε στον οπτικό επεξεργαστή· ίδιο αποδιδόμενο html) ή redirect (καταγραφή του opt-out και έπειτα ανακατεύθυνση στο redirectUrl).

Ενημέρωση του προτύπου του κέντρου προτιμήσεων​

PUT /subscriptions/hosted-page/preference-center

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

ΠεδίοΤύποςΑπαιτείταιΠεριγραφή
modestringΌχιdefault, custom, dnd ή redirect
htmlstringΌχιΣώμα HTML/Liquid για λειτουργία custom / dnd (μέγιστο 100 KB)· πρέπει να περιλαμβάνει την υποδοχή {{ preferences_form }}
redirectUrlstringΌχιΠροορισμός για λειτουργία redirect (μέγιστο 2048 χαρακτήρες)
designJsonobjectΌχιΚατάσταση round-trip του οπτικού επεξεργαστή (μόνο σε λειτουργία dnd· καθαρίζεται στις άλλες λειτουργίες)

Επιστρέφει το αποθηκευμένο πρότυπο στην ίδια μορφή με την απόκριση του GET.

Προεπισκόπηση προτύπου​

POST /subscriptions/hosted-page/preview

Σώμα: { "html": "..." } - το πρότυπο προς απόδοση με δείγματα δεδομένων. Απόκριση: { "html": "<rendered, sanitized html>" }.


Σχετικές επιφάνειες (εκτός αυτής της σελίδας)​

  • Endpoints προς παραλήπτες - η απεγγραφή με ένα κλικ (POST /u/:token, το κουμπί της εφαρμογής email), το κουμπί διαγραφής της φιλοξενούμενης σελίδας (POST /u/:token/confirm, μόνο με κλικ ατόμου) και οι φιλοξενούμενες σελίδες προτιμήσεων είναι δημόσια endpoints με έλεγχο ταυτότητας token για παραλήπτες, όχι endpoints κλειδιού API.
  • Web SDK - τα POST /v1/subscriptions/channel και POST /v1/subscriptions/group ελέγχονται με κλειδί SDK (X-SDK-Key), για UI προτιμήσεων στην πλευρά του πελάτη. Δείτε τον οδηγό Διαχείρισης συνδρομών.
  • Webhooks παρόχων - τα webhooks για bounces και εισερχόμενες λέξεις-κλειδιά SMS (/webhooks/email/..., /webhooks/sms/...) είναι ενσωματώσεις παρόχων με επαλήθευση υπογραφής.
  • Καταστολές - η λίστα «να μην αποσταλεί» σε επίπεδο χώρου εργασίας έχει το δικό της Suppressions API.

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