bublliodocs
API

Bubllio CRM API και Postman

Δοκιμάστε το authenticated, organization-scoped API με τα Postman files του repository.

Αυτός ο οδηγός εξηγεί πώς να χρησιμοποιήσετε με Postman το API, το οποίο απαιτεί authentication και περιορίζει τα δεδομένα ανά Organization. Τα σχετικά αρχεία βρίσκονται στο docs/postman/.

Προετοιμασία

Εγκαταστήστε τις dependencies, εφαρμόστε τις migrations, δημιουργήστε τοπικό χρήστη και ξεκινήστε το Django:

uv sync
uv run python src/manage.py migrate
uv run python src/manage.py createsuperuser
uv run python src/manage.py runserver

Κατεβάστε και εισαγάγετε και τα δύο Postman files. Έπειτα επιλέξτε το environment Bubllio CRM Local:

Στο environment, ορίστε τα username και password στα τοπικά Django credentials. Η collection ζητά JWT pair και στέλνει το access token ως Bearer token. Εκτός localhost χρησιμοποιήστε HTTPS.

Environment variables

VariableΣκοπός
base_urlΤοπικό Django origin
api_versionAPI version, αυτή τη στιγμή v1
username, passwordCredentials τοπικού Django user
access_token, refresh_tokenTokens που συμπληρώνονται από το Authentication/Login request
organization_idUUID του Organization που δημιουργήθηκε
membership_idMembership που θα ενημερωθεί ή θα αφαιρεθεί
company_idUUID της Company που δημιουργήθηκε
automation_idUUID του Automation που δημιουργήθηκε
email_account_idUUID του SMTP account που δημιουργήθηκε
company_search, contact_searchΤιμές αναζήτησης

Για δοκιμή SMTP από το UI, ορίστε και το BUBLLIO_EMAIL_ENCRYPTION_KEYS στο .env του server. Το Postman δεν αποθηκεύει αυτό το encryption key.

Τα requests δημιουργίας Organization, Company και Automation αποθηκεύουν αυτόματα τα IDs που επιστρέφονται στο environment.

Προτεινόμενη ροή

  1. Συνδεθείτε ως Installation admin και δημιουργήστε Organization. Αν δεν ορίσετε διαφορετικό owner_email, ο δημιουργός γίνεται Owner.
  2. Κάντε list τα Organizations και επιβεβαιώστε ότι εμφανίζονται μόνο όσα είναι ορατά μέσω των memberships του χρήστη.
  3. Στείλτε invitation σε συνεργάτη από το Members και ζητήστε του να την αποδεχτεί. Έπειτα θα εμφανιστεί το workspace στη λίστα των Organizations του.
  4. Δημιουργήστε και αναζητήστε Companies μέσα στο Organization.
  5. Δημιουργήστε και αναζητήστε Contacts. Η Company ενός Contact πρέπει να ανήκει στο ίδιο Organization.
  6. Ως Owner ή Admin, δημιουργήστε email Automation με trigger company.created.
  7. Δημιουργήστε άλλη Company για να ενεργοποιήσετε το event. Ελέγξτε το email στο console και το run history. Οι προϋπάρχουσες Companies δεν επεξεργάζονται αναδρομικά.
  8. Προαιρετικά, εκτελέστε Test Automation για να εκτελέσετε ξανά απευθείας την ενέργεια. Αυτό δεν δημιουργεί Company ούτε ελέγχει το event dispatch.
  9. Προαιρετικά, διαγράψτε το Organization ως Owner. Διαγράφονται μαζί του και τα automation rules και το run history.

Για τα αναμενόμενα αποτελέσματα κάθε βήματος, ακολουθήστε τον οδηγό Πρώτο automation.

Για να δοκιμάσετε το owner handoff, συνδεθείτε ως Installation admin, δημιουργήστε workspace με διαφορετικό owner_email και ελέγξτε το GET /api/v1/organizations/provisioning/. Το workspace δεν εμφανίζεται στην κανονική λίστα Organizations μέχρι να αποδεχτεί την πρόσκληση ο προτεινόμενος Owner. Ο Installation admin μπορεί να ξαναστείλει (POST) ή να ακυρώσει (DELETE) το pending provisioning request. Χρειάζεται λειτουργικό installation fallback SMTP, επειδή αποστέλλεται πραγματικό email πρόσκλησης.

Authentication

Ζητήστε tokens με POST /api/v1/auth/token/, στέλνοντας username και password σε JSON. Χρησιμοποιήστε το access στην κεφαλίδα Authorization: Bearer <access>. Για ανανέωση καλέστε POST /api/v1/auth/token/refresh/· για logout καλέστε POST /api/v1/auth/logout/.

Responses authentication και authorization

Τα προστατευμένα API routes απαιτούν authentication. Εξαιρούνται σκόπιμα το setup, η έκδοση token, το preview και acceptance invitations και το password reset. Με JWT authentication, ανώνυμο request σε προστατευμένο route επιστρέφει 401 Unauthorized. Αν ο χρήστης είναι authenticated αλλά δεν έχει membership ή το απαιτούμενο capability, συνήθως επιστρέφεται 404 Not Found, ώστε να μην αποκαλύπτεται η ύπαρξη Organization στο οποίο δεν έχει πρόσβαση.

Endpoints

Organizations:

GET    /api/v1/organizations/
POST   /api/v1/organizations/
GET    /api/v1/organizations/<organization_id>/
DELETE /api/v1/organizations/<organization_id>/

Memberships — Owner/Admin, με περιορισμούς ανά role:

GET    /api/v1/organizations/<organization_id>/members/
POST   /api/v1/organizations/<organization_id>/members/
PATCH  /api/v1/organizations/<organization_id>/members/<membership_id>/
DELETE /api/v1/organizations/<organization_id>/members/<membership_id>/

Settings και email accounts:

GET   /api/v1/organizations/<organization_id>/settings/
PATCH /api/v1/organizations/<organization_id>/settings/
GET   /api/v1/organizations/settings/options/

GET    /api/v1/organizations/<organization_id>/email-accounts/
POST   /api/v1/organizations/<organization_id>/email-accounts/
GET    /api/v1/organizations/<organization_id>/email-accounts/<account_id>/
PATCH  /api/v1/organizations/<organization_id>/email-accounts/<account_id>/
DELETE /api/v1/organizations/<organization_id>/email-accounts/<account_id>/
POST   /api/v1/organizations/<organization_id>/email-accounts/<account_id>/test/

Το GET /api/v1/organizations/settings/options/ επιστρέφει διαθέσιμα timezones και locales ως ζεύγη {value, label}. Τα timezones προέρχονται από την IANA database του runtime και τα locales από το LANGUAGES του Django. Είναι επιλογές κώδικα/ρύθμισης, όχι εγγραφές database, ώστε όλοι οι clients να εμφανίζουν τις ίδιες επιλογές χωρίς συγχρονισμό reference data.

Παράδειγμα δημιουργίας SMTP account:

{
  "name": "Company SMTP",
  "provider": "smtp",
  "host": "smtp.example.com",
  "port": 587,
  "username": "mailer@example.com",
  "password": "provider-password",
  "use_tls": true,
  "use_ssl": false,
  "from_email": "mailer@example.com",
  "from_name": "Bubllio CRM",
  "is_default": true
}

Για δοκιμαστικό email:

{ "recipient": "you@example.com" }

Το password γίνεται δεκτό μόνο κατά τη δημιουργία ή ενημέρωση του account και δεν επιστρέφεται ποτέ από το API.

Companies και Contacts:

GET   /api/v1/organizations/<organization_id>/companies/
GET   /api/v1/organizations/<organization_id>/companies/?search=<term>
GET   /api/v1/organizations/<organization_id>/companies/?lifecycle_stage=<stage>
POST  /api/v1/organizations/<organization_id>/companies/
GET   /api/v1/organizations/<organization_id>/companies/<company_id>/
PATCH /api/v1/organizations/<organization_id>/companies/<company_id>/
DELETE /api/v1/organizations/<organization_id>/companies/<company_id>/

GET   /api/v1/organizations/<organization_id>/contacts/
GET   /api/v1/organizations/<organization_id>/contacts/?search=<term>
POST  /api/v1/organizations/<organization_id>/contacts/

Automations:

GET  /api/v1/organizations/<organization_id>/automations/
POST /api/v1/organizations/<organization_id>/automations/
GET  /api/v1/organizations/<organization_id>/automations/runs/
POST /api/v1/organizations/<organization_id>/automations/<automation_id>/test/

Μην περιλαμβάνετε organization στα request bodies για Company, Contact ή Automation. Μετά τον έλεγχο membership, ο server καθορίζει την ιδιοκτησία από το <organization_id>. Τα response bodies περιλαμβάνουν το read-only Organization UUID. Η αναζήτηση Company καλύπτει name, tax ID, industry, στοιχεία επικοινωνίας, city, country και notes. Το lifecycle_stage δέχεται lead, prospect, customer ή inactive.

Παραδείγματα request bodies

Δημιουργία Organization:

{
  "name": "Nerds Lab",
  "slug": "nerds-lab"
}

Πρόσκληση μέλους μέσω email:

{
  "email": "teammate@example.com",
  "role": "member"
}

Δημιουργία Company:

{
  "name": "Acme Inc",
  "email": "hello@acme.test",
  "lifecycle_stage": "lead"
}

Δημιουργία Contact:

{
  "company": "<company UUID>",
  "first_name": "Maria",
  "last_name": "Papadopoulou",
  "email": "maria@acme.test"
}

Δημιουργία Automation:

{
  "name": "Notify accounting",
  "trigger": "company.created",
  "action_type": "send_email",
  "action_config": {
    "to": ["accounting@example.com"],
    "subject": "New company",
    "body": "A company was added to Bubllio CRM."
  },
  "is_active": true
}

Τα Automation emails χρησιμοποιούν το console backend του Django και εμφανίζονται στο terminal όπου τρέχει το runserver. Το SMTP account test endpoint δοκιμάζει πραγματική παράδοση. Η επιλογή account ως default δεν το συνδέει με τα Automations.

Προς το παρόν, μόνο το company.created εκπέμπεται αυτόματα. Οι άλλες αποδεκτές επιλογές trigger δεν είναι ακόμη συνδεδεμένες. Δεν υπάρχει endpoint ενημέρωσης ή διαγραφής Automation.

Το Test Automation εκτελεί την ενέργεια ακόμη και όταν το rule είναι inactive και επιστρέφει HTTP 201 και σε καταγεγραμμένη αποτυχία. Ελέγξτε τα status και run.error_message. Το payload αποθηκεύεται στο history, αλλά δεν εισάγεται στο email. Για τις λεπτομέρειες, δείτε τα Automations.

Για όλους τους κανόνες authorization, δείτε το docs/architecture/authentication-and-roles.md.