Αναφορά 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_failed | 400 | Ένα πεδίο απέτυχε στην επικύρωση, στάλθηκε άγνωστο πεδίο, ή το JSON ήταν κακοσχηματισμένο. Συνοδεύεται από details. |
| bad_request | 400 | Κακοσχηματισμένο αίτημα που δεν είναι αποτυχία επικύρωσης πεδίου. |
| unauthorized | 401 | Επιστρέφεται μόνο από εσωτερικά endpoints webhook και εργασιών. Ένας καλών του API παίρνει τους κωδικούς bearer token παρακάτω. |
| forbidden | 403 | Ταυτοποιημένος, αλλά χωρίς δικαίωμα: για παράδειγμα εξαγωγή δεδομένων χωρίς ρόλο ιδιοκτήτη. |
| pack_feature_unavailable | 403 | Η λειτουργία ανήκει σε άλλο είδος ιατρείου, για παράδειγμα το οδοντόγραμμα σε ιατρείο που δεν είναι οδοντιατρείο. Κανένα πρόγραμμα δεν την ξεκλειδώνει. Το detail.feature την ονομάζει. |
| subscription_read_only | 403 | Το ιατρείο δεν έχει ενεργό πακέτο, οπότε οι εγγραφές απορρίπτονται· η ανάγνωση και οι εξαγωγές λειτουργούν. Το `detail.reason` λέει τον λόγο (έληξε η δοκιμή, απέτυχε η πληρωμή, ακυρώθηκε). |
| plan_feature_required | 403 | Η ενέργεια χρειάζεται λειτουργία που δεν περιλαμβάνει το πακέτο του ιατρείου. Το `detail.feature` την ονομάζει και το `detail.requiredPlan` το πακέτο που την έχει. |
| plan_limit_reached | 403 | Συμπληρώθηκε ένα όριο του πακέτου. Τα `detail.limit` και `detail.used` δίνουν το όριο και το τρέχον πλήθος, και το `detail.resource` ονομάζει τι περιορίστηκε. |
| credits_exhausted | 403 | Η ενέργεια κοστίζει μονάδες και το υπόλοιπο δεν αρκεί. Τα `detail.cost` και `detail.remaining` δίνουν το κόστος και το υπόλοιπο. |
| feature_unavailable | 403 | Η λειτουργία είναι απενεργοποιημένη για αυτό το ιατρείο από feature flag, όχι από το πακέτο του. |
| email_not_verified | 403 | Η ενέργεια χρειάζεται επιβεβαιωμένη διεύθυνση email στον λογαριασμό που καλεί, για παράδειγμα μια εξαγωγή CSV. |
| mfa_required | 403 | Το ιατρείο απαιτεί επαλήθευση με passkey, κάτι που ένα bearer token από μόνο του δεν καλύπτει. |
| reauth_required | 403 | Η ενέργεια χρειάζεται πρόσφατη σύνδεση (μέσα σε 10 λεπτά), για παράδειγμα η έγκριση ενός client OAuth. |
| practice_email_unverified | 403 | Αποστολή email σε ασθενή πριν ένας ιδιοκτήτης του ιατρείου επιβεβαιώσει τη δική του διεύθυνση email. |
| not_found | 404 | Δεν υπάρχει τέτοιος πόρος στο ιατρείο σας. Επιστρέφεται και για κακοσχηματισμένο id διαδρομής, ώστε οι δύο περιπτώσεις να μη διακρίνονται. |
| conflict | 409 | Το αίτημα συγκρούεται με την τρέχουσα κατάσταση, π.χ. διπλότυπος τίτλος ετικέτας. |
| already_submitted | 409 | Δημόσιος σύνδεσμος φόρμας που έχει ήδη υποβληθεί. |
| entries_not_billable | 409 | Έκδοση απόδειξης ή τιμολογίου για επιλεγμένες χρεώσεις, όταν κάποια δεν είναι ανεξόφλητη χρέωση του ίδιου ασθενή. |
| appointment_already_charged | 409 | Χρέωση ραντεβού που έχει ήδη χρέωση χωρίς ακύρωση. Ακυρώστε πρώτα εκείνη τη χρέωση. |
| appointment_not_chargeable | 409 | Χρέωση ραντεβού που δεν είναι επιβεβαιωμένο ραντεβού ασθενή: αίτημα, απορριφθέν, ακυρωμένο ή ληγμένο ραντεβού, υπενθύμιση ή κλειστό διάστημα. |
| appointment_not_charged | 409 | Πληρωμή που αναφέρει ραντεβού χωρίς χρέωση σε ισχύ. Χρεώστε πρώτα το ραντεβού και μετά καταχωρίστε την πληρωμή. |
| charge_has_instalments | 409 | Ακύρωση χρέωσης που έχει ακόμη δόσεις σε ισχύ. Ακυρώστε πρώτα τις δόσεις. |
| instalment_parent_locked | 409 | Ακύρωση δόσης της οποίας η χρέωση είναι ακυρωμένη ή σε παραστατικό, οπότε το ποσό δεν μπορεί να επιστρέψει σε αυτήν. Ακυρώστε πρώτα εκείνο το παραστατικό. |
| invoice_voided | 409 | Αποστολή με email απόδειξης ή τιμολογίου που έχει ακυρωθεί. |
| token_expired | 410 | Ο δημόσιος σύνδεσμος έχει λήξει. |
| auth_email_conflict | 409 | Μια άλλη ταυτότητα σύνδεσης κατέχει ήδη αυτή τη διεύθυνση email. |
| import_limit_reached | 409 | Το ιατρείο έφτασε στο όριο εισαγωγών ασθενών. |
| invitation_already_yours | 409 | Η πρόσκληση που γίνεται αποδεκτή ανήκει ήδη στον συνδεδεμένο λογαριασμό. |
| receipt_not_paid | 409 | Ζητήθηκε απόδειξη για καταχώριση που δεν έχει πληρωθεί. |
| payload_too_large | 413 | Το σώμα του αιτήματος ξεπερνά το μέγιστο αποδεκτό μέγεθος. |
| recipient_tax_id_required | 422 | Ζητήθηκε τιμολόγιο για ασθενή χωρίς ΑΦΜ. Προσθέστε τον ΑΦΜ ή εκδώστε απόδειξη. |
| patient_email_missing | 422 | Αποστολή με email απόδειξης ή τιμολογίου χωρίς διεύθυνση παραλήπτη: ο ασθενής δεν έχει email στην καρτέλα, η καρτέλα διαγράφηκε ή το παραστατικό δεν συνδέεται με ασθενή. Το detail.reason λέει ποιο από τα τρία. |
| rate_limit_exceeded | 429 | Συμπληρώθηκε ένα όριο ρυθμού. Φέρει τις κεφαλίδες ορίων που περιγράφονται παραπάνω, και το `Retry-After` για το πόσο να περιμένετε. |
| patient_phone_missing | 422 | Ζητήθηκε αποστολή με SMS και ο ασθενής δεν έχει κινητό. |
| consent_expired | 400 | Η απόδειξη συγκατάθεσης για μια έγκριση OAuth έληξε· συνδεθείτε ξανά και επαναλάβετε. |
| session_ended | 401 | Μια συνεδρία σύνδεσης προσωπικού έχει λήξει. |
| internal_error | 500 | Απρόσμενο σφάλμα διακομιστή. Δεν επιστρέφεται τίποτα για την αιτία· αναφέρετε το requestId. |
| service_unavailable | 503 | Μια εξάρτηση δεν είναι προσωρινά διαθέσιμη. |
| email_not_configured | 503 | Η αποστολή email δεν έχει ρυθμιστεί σε αυτόν τον διακομιστή. |
| missing_authorization | 401 | Δεν στάλθηκε κεφαλίδα Authorization. |
| sms_not_configured | 503 | Ο διακομιστής δεν έχει ρυθμισμένο πάροχο SMS. |
| refund_unavailable | 503 | Δεν ήταν δυνατή η επικοινωνία με τον πάροχο πληρωμών για επιστροφή χρημάτων. |
| invalid_authorization_header | 401 | Η κεφαλίδα υπήρχε αλλά όχι στη μορφή Bearer <token>. |
| invalid_auth_token | 401 | Το token δεν είναι έγκυρο. |
| expired_auth_token | 401 | Το token έχει λήξει. Ανανεώστε το και δοκιμάστε ξανά. |
| revoked_auth_token | 401 | Το token έχει ανακληθεί. |
| auth_token_verification_failed | 401 | Το token δεν επαληθεύτηκε για λόγο χωρίς πιο συγκεκριμένο κωδικό. |
| disabled_auth_token | 403 | Το token επαληθεύεται, αλλά η ταυτότητα πίσω του είναι απενεργοποιημένη, εξ ου 403 και όχι 401. |
| unsupported_auth_provider | 403 | Ο συγκεκριμένος πάροχος σύνδεσης δεν γίνεται δεκτός για πρόσβαση στο API. |
| auth_provider_email_required | 403 | Δεσμευμένο. Ορίζεται για πάροχο σύνδεσης που δεν δίνει email· σήμερα δεν το επιστρέφει τίποτα. |
| user_disabled | 403 | Δεσμευμένο. Ένας απενεργοποιημένος λογαριασμός HyperCRM απορρίπτεται ως `forbidden`. Το `user_disabled` είναι όνομα ενέργειας στο ιστορικό, όχι κωδικός απάντησης. |
| auth_configuration_missing | 503 | Η ταυτοποίηση δεν είναι ρυθμισμένη στον διακομιστή. |
Συχνές ερωτήσεις
Οι καρτέλες ασθενών κρυπτογραφούνται, και εκεί που φυλάσσονται και καθώς έρχονται στην οθόνη σας. Τα αρχεία είναι ιδιωτικά, και ο σύνδεσμος προς ένα αρχείο σταματά να δουλεύει μετά από λίγο. Οι αλλαγές στις καρτέλες των ασθενών καταγράφονται, με το ποιος τις έκανε και πότε. Δεν υπάρχει κοινός κωδικός ιατρείου: ο καθένας έχει τον δικό του λογαριασμό. Στο πακέτο Complete, ο ιδιοκτήτης του ιατρείου μπορεί επίσης να απαιτεί σύνδεση σε δύο βήματα για όλη την ομάδα.
Όχι. Περιλαμβάνεται μόνο όταν υπάρχουν δομημένα ζητήματα σε επίπεδο πεδίου, όπως αποτυχίες επικύρωσης πεδίων, καθεμία με διαδρομή και μήνυμα. Όταν δεν υπάρχει κάτι συγκεκριμένο για πεδίο, το κλειδί παραλείπεται εντελώς από το σώμα της απάντησης αντί να στέλνεται ως κενός πίνακας.
Χρησιμοποιήστε την τιμή requestId από το σώμα της απάντησης, ή την ταυτόσημη κεφαλίδα απάντησης x-request-id. Αν το δικό σας αίτημα έστειλε ήδη κεφαλίδα x-request-id ή x-correlation-id στην αναμενόμενη μορφή, η ίδια τιμή επιστρέφεται αυτούσια, οπότε μπορείτε να παράγετε το δικό σας id εκ των προτέρων και να το ταιριάζετε από άκρη σε άκρη.
Επειδή το ίδιο το bearer token εξακολουθεί να είναι έγκυρο και επαληθεύεται σωστά. Η ταυτότητα πίσω του είναι απενεργοποιημένη, κάτι που το HyperCRM αντιμετωπίζει ως αποτυχία εξουσιοδότησης αντί για αποτυχία αυθεντικοποίησης. Είναι σκόπιμη εξαίρεση από τη συνηθέστερη σύμβαση, τεκμηριωμένη ρητά στη σελίδα αναφοράς αυθεντικοποίησης.