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

Αναφορά API / Σφάλματα

Κάθε κωδικός σφάλματος, σε ένα σημείο

Κάθε απάντηση του API του HyperCRM, επιτυχής ή αποτυχημένη, ακολουθεί μία από δύο μορφές φακέλου, με τις λίγες εξαιρέσεις που αναφέρονται παρακάτω. Αυτή η σελίδα παραθέτει και τις δύο μορφές, πώς λειτουργούν τα request id, και τον πλήρη πίνακα κωδικών σφάλματος και καταστάσεων HTTP που μπορεί να επιστρέψει ένα endpoint.

Οι δύο φάκελοι

Κάθε απάντηση του API ακολουθεί έναν από τους δύο φακέλους, με τρεις εξαιρέσεις: τα endpoints OAuth /oauth/token και /oauth/register χρησιμοποιούν το τυπικό σώμα σφάλματος OAuth (error, error_description), και οι εξαγωγές CSV επιστρέφουν αρχείο.

Οι επιτυχείς απαντήσεις (2xx) μοιάζουν πάντα έτσι, με το data να κρατά τον πόρο και το requestId για συσχέτιση:

{
  "data": { "...": "resource-specific shape" },
  "requestId": "req_5f2c1e40-..."
}

Τα endpoints POST που δημιουργούν πόρο επιστρέφουν 201 με την ίδια μορφή. Οι απαντήσεις σφάλματος (4xx/5xx) μοιράζονται το αντίστροφο σχήμα, με σταθερό code, ένα ασφαλές προς εμφάνιση message, το ίδιο requestId, και προαιρετικό πίνακα details. Κάθε καταχώριση έχει ένα message και μπορεί να έχει path, field και ένα αναγνώσιμο από μηχανή code (για παράδειγμα invalid_json, ή chair_booked σε σύγκρουση κράτησης):

{
  "error": {
    "code": "validation_failed",
    "message": "Request validation failed.",
    "requestId": "req_5f2c1e40-...",
    "details": [ { "path": ["firstName"], "message": "firstName is required" } ]
  }
}

Το αντικείμενο detail

Ξεχωριστά από τον πίνακα details, μια άρνηση στην οποία μπορεί να αντιδράσει ο client φέρει ένα αντικείμενο detail με τον αναγνώσιμο από μηχανή λόγο, για παράδειγμα detail.feature σε άρνηση πακέτου ή detail.limit και detail.used σε όριο. Τα κλειδιά που χρησιμοποιούνται είναι feature, resource, limit, used, requiredPlan, cost, remaining, resetsAt, reason, since, mode, practiceName και practiceLogoUrl. Διαβάστε τα με το όνομά τους και αγνοήστε ένα κλειδί που δεν γνωρίζετε: προστίθενται καθώς τα χρειάζονται νέες αρνήσεις.

Κεφαλίδες ορίων ρυθμού

Μια απάντηση 429 φέρει Retry-After σε δευτερόλεπτα, ποτέ κάτω από 1, μαζί με RateLimit-Limit, RateLimit-Remaining και RateLimit-Reset (δευτερόλεπτα μέχρι να μηδενιστεί το παράθυρο). Μια επιτυχής απάντηση δεν φέρει κανένα από αυτά, οπότε διαβάστε το υπόλοιπο από το 429 που έτσι κι αλλιώς χειρίζεστε. Ανά λεπτό, το REST επιτρέπει 300 αιτήματα ανά χρήστη, από τα οποία 120 εγγραφές, και 600 ανά διεύθυνση IP· το endpoint MCP επιτρέπει 120 ανά access token.

Τα endpoints OAuth είναι διαφορετικά

Τα /oauth/token, /oauth/register και /oauth/revoke απαντούν στη γραμματική του OAuth αντί στον φάκελο παραπάνω: error και error_description, με την κατάσταση στη γραμμή απάντησης. Οι κωδικοί είναι οι καταχωρισμένοι του OAuth, οπότε μια τυπική βιβλιοθήκη client τους καταλαβαίνει ήδη: invalid_request, invalid_client, invalid_grant, unsupported_grant_type και invalid_target (400), server_error για οτιδήποτε 5xx, και temporarily_unavailable για αίτημα που κόπηκε από όριο, το οποίο διατηρεί την κατάσταση 429 ώστε ένας client που ξέρει μόνο τη λίστα του OAuth να επιβραδύνει σωστά.

Request id

Κάθε απάντηση φέρει κεφαλίδα x-request-id, και η ίδια τιμή εμφανίζεται ως requestId στο σώμα. Αν το εισερχόμενο αίτημα προμηθεύει τη δική του κεφαλίδα x-request-id (ή x-correlation-id) που ταιριάζει σε ασφαλές μοτίβο, αυτή η τιμή επιστρέφεται αυτούσια για συσχέτιση αρχείων καταγραφής από την πλευρά του πελάτη· διαφορετικά ο διακομιστής παράγει μία της μορφής req_<uuid>.

Πίσω στον κόμβο αναφοράς API για τις υπόλοιπες σελίδες πόρων.

Όλοι οι κωδικοί σφάλματος

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

ΚωδικόςΚατάστασηΠότε συμβαίνει
validation_failed400Ένα πεδίο απέτυχε στην επικύρωση, στάλθηκε άγνωστο πεδίο, ή το JSON ήταν κακοσχηματισμένο. Συνοδεύεται από details.
bad_request400Κακοσχηματισμένο αίτημα που δεν είναι αποτυχία επικύρωσης πεδίου.
unauthorized401Επιστρέφεται μόνο από εσωτερικά endpoints webhook και εργασιών. Ένας καλών του API παίρνει τους κωδικούς bearer token παρακάτω.
forbidden403Ταυτοποιημένος, αλλά χωρίς δικαίωμα: για παράδειγμα εξαγωγή δεδομένων χωρίς ρόλο ιδιοκτήτη.
pack_feature_unavailable403Η λειτουργία ανήκει σε άλλο είδος ιατρείου, για παράδειγμα το οδοντόγραμμα σε ιατρείο που δεν είναι οδοντιατρείο. Κανένα πρόγραμμα δεν την ξεκλειδώνει. Το detail.feature την ονομάζει.
subscription_read_only403Το ιατρείο δεν έχει ενεργό πακέτο, οπότε οι εγγραφές απορρίπτονται· η ανάγνωση και οι εξαγωγές λειτουργούν. Το `detail.reason` λέει τον λόγο (έληξε η δοκιμή, απέτυχε η πληρωμή, ακυρώθηκε).
plan_feature_required403Η ενέργεια χρειάζεται λειτουργία που δεν περιλαμβάνει το πακέτο του ιατρείου. Το `detail.feature` την ονομάζει και το `detail.requiredPlan` το πακέτο που την έχει.
plan_limit_reached403Συμπληρώθηκε ένα όριο του πακέτου. Τα `detail.limit` και `detail.used` δίνουν το όριο και το τρέχον πλήθος, και το `detail.resource` ονομάζει τι περιορίστηκε.
credits_exhausted403Η ενέργεια κοστίζει μονάδες και το υπόλοιπο δεν αρκεί. Τα `detail.cost` και `detail.remaining` δίνουν το κόστος και το υπόλοιπο.
feature_unavailable403Η λειτουργία είναι απενεργοποιημένη για αυτό το ιατρείο από feature flag, όχι από το πακέτο του.
email_not_verified403Η ενέργεια χρειάζεται επιβεβαιωμένη διεύθυνση email στον λογαριασμό που καλεί, για παράδειγμα μια εξαγωγή CSV.
mfa_required403Το ιατρείο απαιτεί επαλήθευση με passkey, κάτι που ένα bearer token από μόνο του δεν καλύπτει.
reauth_required403Η ενέργεια χρειάζεται πρόσφατη σύνδεση (μέσα σε 10 λεπτά), για παράδειγμα η έγκριση ενός client OAuth.
practice_email_unverified403Αποστολή email σε ασθενή πριν ένας ιδιοκτήτης του ιατρείου επιβεβαιώσει τη δική του διεύθυνση email.
not_found404Δεν υπάρχει τέτοιος πόρος στο ιατρείο σας. Επιστρέφεται και για κακοσχηματισμένο id διαδρομής, ώστε οι δύο περιπτώσεις να μη διακρίνονται.
conflict409Το αίτημα συγκρούεται με την τρέχουσα κατάσταση, π.χ. διπλότυπος τίτλος ετικέτας.
already_submitted409Δημόσιος σύνδεσμος φόρμας που έχει ήδη υποβληθεί.
entries_not_billable409Έκδοση απόδειξης ή τιμολογίου για επιλεγμένες χρεώσεις, όταν κάποια δεν είναι ανεξόφλητη χρέωση του ίδιου ασθενή.
appointment_already_charged409Χρέωση ραντεβού που έχει ήδη χρέωση χωρίς ακύρωση. Ακυρώστε πρώτα εκείνη τη χρέωση.
appointment_not_chargeable409Χρέωση ραντεβού που δεν είναι επιβεβαιωμένο ραντεβού ασθενή: αίτημα, απορριφθέν, ακυρωμένο ή ληγμένο ραντεβού, υπενθύμιση ή κλειστό διάστημα.
appointment_not_charged409Πληρωμή που αναφέρει ραντεβού χωρίς χρέωση σε ισχύ. Χρεώστε πρώτα το ραντεβού και μετά καταχωρίστε την πληρωμή.
charge_has_instalments409Ακύρωση χρέωσης που έχει ακόμη δόσεις σε ισχύ. Ακυρώστε πρώτα τις δόσεις.
instalment_parent_locked409Ακύρωση δόσης της οποίας η χρέωση είναι ακυρωμένη ή σε παραστατικό, οπότε το ποσό δεν μπορεί να επιστρέψει σε αυτήν. Ακυρώστε πρώτα εκείνο το παραστατικό.
invoice_voided409Αποστολή με email απόδειξης ή τιμολογίου που έχει ακυρωθεί.
token_expired410Ο δημόσιος σύνδεσμος έχει λήξει.
auth_email_conflict409Μια άλλη ταυτότητα σύνδεσης κατέχει ήδη αυτή τη διεύθυνση email.
import_limit_reached409Το ιατρείο έφτασε στο όριο εισαγωγών ασθενών.
invitation_already_yours409Η πρόσκληση που γίνεται αποδεκτή ανήκει ήδη στον συνδεδεμένο λογαριασμό.
receipt_not_paid409Ζητήθηκε απόδειξη για καταχώριση που δεν έχει πληρωθεί.
payload_too_large413Το σώμα του αιτήματος ξεπερνά το μέγιστο αποδεκτό μέγεθος.
recipient_tax_id_required422Ζητήθηκε τιμολόγιο για ασθενή χωρίς ΑΦΜ. Προσθέστε τον ΑΦΜ ή εκδώστε απόδειξη.
patient_email_missing422Αποστολή με email απόδειξης ή τιμολογίου χωρίς διεύθυνση παραλήπτη: ο ασθενής δεν έχει email στην καρτέλα, η καρτέλα διαγράφηκε ή το παραστατικό δεν συνδέεται με ασθενή. Το detail.reason λέει ποιο από τα τρία.
rate_limit_exceeded429Συμπληρώθηκε ένα όριο ρυθμού. Φέρει τις κεφαλίδες ορίων που περιγράφονται παραπάνω, και το `Retry-After` για το πόσο να περιμένετε.
patient_phone_missing422Ζητήθηκε αποστολή με SMS και ο ασθενής δεν έχει κινητό.
consent_expired400Η απόδειξη συγκατάθεσης για μια έγκριση OAuth έληξε· συνδεθείτε ξανά και επαναλάβετε.
session_ended401Μια συνεδρία σύνδεσης προσωπικού έχει λήξει.
internal_error500Απρόσμενο σφάλμα διακομιστή. Δεν επιστρέφεται τίποτα για την αιτία· αναφέρετε το requestId.
service_unavailable503Μια εξάρτηση δεν είναι προσωρινά διαθέσιμη.
email_not_configured503Η αποστολή email δεν έχει ρυθμιστεί σε αυτόν τον διακομιστή.
missing_authorization401Δεν στάλθηκε κεφαλίδα Authorization.
sms_not_configured503Ο διακομιστής δεν έχει ρυθμισμένο πάροχο SMS.
refund_unavailable503Δεν ήταν δυνατή η επικοινωνία με τον πάροχο πληρωμών για επιστροφή χρημάτων.
invalid_authorization_header401Η κεφαλίδα υπήρχε αλλά όχι στη μορφή Bearer <token>.
invalid_auth_token401Το token δεν είναι έγκυρο.
expired_auth_token401Το token έχει λήξει. Ανανεώστε το και δοκιμάστε ξανά.
revoked_auth_token401Το token έχει ανακληθεί.
auth_token_verification_failed401Το token δεν επαληθεύτηκε για λόγο χωρίς πιο συγκεκριμένο κωδικό.
disabled_auth_token403Το token επαληθεύεται, αλλά η ταυτότητα πίσω του είναι απενεργοποιημένη, εξ ου 403 και όχι 401.
unsupported_auth_provider403Ο συγκεκριμένος πάροχος σύνδεσης δεν γίνεται δεκτός για πρόσβαση στο API.
auth_provider_email_required403Δεσμευμένο. Ορίζεται για πάροχο σύνδεσης που δεν δίνει email· σήμερα δεν το επιστρέφει τίποτα.
user_disabled403Δεσμευμένο. Ένας απενεργοποιημένος λογαριασμός HyperCRM απορρίπτεται ως `forbidden`. Το `user_disabled` είναι όνομα ενέργειας στο ιστορικό, όχι κωδικός απάντησης.
auth_configuration_missing503Η ταυτοποίηση δεν είναι ρυθμισμένη στον διακομιστή.

Συχνές ερωτήσεις

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

Όχι. Περιλαμβάνεται μόνο όταν υπάρχουν δομημένα ζητήματα σε επίπεδο πεδίου, όπως αποτυχίες επικύρωσης πεδίων, καθεμία με διαδρομή και μήνυμα. Όταν δεν υπάρχει κάτι συγκεκριμένο για πεδίο, το κλειδί παραλείπεται εντελώς από το σώμα της απάντησης αντί να στέλνεται ως κενός πίνακας.

Χρησιμοποιήστε την τιμή requestId από το σώμα της απάντησης, ή την ταυτόσημη κεφαλίδα απάντησης x-request-id. Αν το δικό σας αίτημα έστειλε ήδη κεφαλίδα x-request-id ή x-correlation-id στην αναμενόμενη μορφή, η ίδια τιμή επιστρέφεται αυτούσια, οπότε μπορείτε να παράγετε το δικό σας id εκ των προτέρων και να το ταιριάζετε από άκρη σε άκρη.

Επειδή το ίδιο το bearer token εξακολουθεί να είναι έγκυρο και επαληθεύεται σωστά. Η ταυτότητα πίσω του είναι απενεργοποιημένη, κάτι που το HyperCRM αντιμετωπίζει ως αποτυχία εξουσιοδότησης αντί για αποτυχία αυθεντικοποίησης. Είναι σκόπιμη εξαίρεση από τη συνηθέστερη σύμβαση, τεκμηριωμένη ρητά στη σελίδα αναφοράς αυθεντικοποίησης.