Skip to main content

Integrations

Third-party CRM, calendar, telephony, and scheduling APIs.

Base URL: https://events.pana.space/api

Product guides: Integrations overview — connect Calendly, Google Calendar, Microsoft Calendar, HubSpot, Attio, Pipedrive, Salesforce, Zoho CRM, Microsoft Dynamics 365, Knowlarity, Slack, and Microsoft Teams from Settings → Integrations. Email sending uses mailboxes.

Full schemas: Interactive API explorer


Workspace-scoped routes require JWT auth and workspace admin for connect; member for callback and list.

Base path:

/api/v1/{workspace_id}/integrations/

Global connection routes (no workspace in path):

/api/v1/integrations/connections/{connection_id}/

List catalog​

GET /api/v1/{workspace_id}/integrations/catalog/
Authorization: Bearer <token>

Response (200 OK)​

{
"version": "a1b2c3d4e5f6g7h8",
"providers": [
{
"key": "hubspot",
"name": "HubSpot",
"category": "crm",
"logo_url": "/integrations/hubspot.svg",
"auth_type": "oauth2",
"tier": 3,
"cardinality": "one_per_workspace",
"capabilities": ["sync_contacts", "push_leads", "receive_webhooks"],
"config_schema": {
"type": "object",
"properties": {
"default_sync_event_id": { "type": "string", "format": "uuid" }
}
},
"oauth": {
"scopes": [
"crm.objects.contacts.read",
"crm.objects.contacts.write",
"crm.objects.deals.read"
]
},
"enabled": true,
"coming_soon": false,
"connected": true
}
]
}

List connections​

GET /api/v1/{workspace_id}/integrations/connections/?page=1&page_size=50
Authorization: Bearer <token>

Credentials are never returned.

Response (200 OK)​

{
"count": 1,
"page": 1,
"page_size": 50,
"results": [
{
"id": "880e8400-e29b-41d4-a716-446655440010",
"provider_key": "hubspot",
"auth_type": "oauth2",
"status": "connected",
"external_account_id": "",
"scopes": ["crm.objects.contacts.read", "oauth"],
"config": {
"hubspot_portal_id": "12345678"
},
"expires_at": "2026-07-06T14:30:00+00:00",
"last_sync_at": "2026-07-06T12:00:00+00:00",
"last_error": null,
"created_at": "2026-06-01T09:00:00+00:00",
"updated_at": "2026-07-06T12:00:00+00:00",
"created_by_id": "660e8400-e29b-41d4-a716-446655440001"
}
]
}

Start OAuth connect​

POST /api/v1/{workspace_id}/integrations/{provider_key}/connect/
Authorization: Bearer <token>
Content-Type: application/json

Provider keys: hubspot, pipedrive, salesforce, calendly, google-calendar, knowlarity, slack

Request body (HubSpot — platform OAuth app)​

Credentials come from backend env (HUBSPOT_CLIENT_ID / HUBSPOT_CLIENT_SECRET). Do not send client_id in the body.

{
"redirect_uri": "https://events.pana.space/auth/oauth/callback?provider=hubspot",
"app_domain": "https://events.pana.space"
}

Request body (Pipedrive — platform OAuth app)​

Credentials come from backend env (PIPEDRIVE_CLIENT_ID / PIPEDRIVE_CLIENT_SECRET).

{
"redirect_uri": "https://events.pana.space/auth/oauth/callback?provider=pipedrive",
"app_domain": "https://events.pana.space"
}

Request body (Google Calendar — platform OAuth app)​

Credentials come from backend env (GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET). Send "provider": "google" so the backend uses the calendar OAuth flow.

{
"provider": "google",
"redirect_uri": "https://events.pana.space/auth/oauth/callback/?provider=google-calendar",
"app_domain": "https://events.pana.space"
}

Request body (Slack — platform OAuth app)​

Credentials come from backend env (SLACK_CLIENT_ID / SLACK_CLIENT_SECRET).

{
"redirect_uri": "https://events.pana.space/auth/oauth/callback?provider=slack",
"app_domain": "https://events.pana.space"
}

Request body (Calendly — backend OAuth callback)​

Calendly redirects to the API host, not the frontend OAuth callback page.

{
"redirect_uri": "https://eventsapi.pana.space/api/v1/integrations/calendly/callback/",
"app_domain": "https://events.pana.space/events/{workspace_id}/settings/integrations"
}

app_domain is where the backend sends the user after OAuth completes (?calendly=connected).

Request body (Salesforce — per-workspace Connected App)​

{
"redirect_uri": "https://events.pana.space/auth/oauth/callback?provider=salesforce",
"client_id": "3MVG9HtWXcDGV.nHyoaWmEQn51.tnGc2WbLMf_UGwN8Rx4xMiJ4P4xLiU8TmU1JuEAGzaHp8nPLdvijJT90m1",
"client_secret": "YOUR_CONSUMER_SECRET"
}

Request body (Knowlarity — API key)​

{
"knowlarity_number": "+919876543210",
"sr_api_key": "your-super-receptionist-key",
"x_api_key": "your-channel-api-key"
}

Response (200 OK)​

{
"auth_url": "https://app.hubspot.com/oauth/authorize?client_id=…&redirect_uri=…&state=…"
}

Redirect the user to auth_url in the browser.

Calendly exception: OAuth completes on the backend (GET …/calendly/callback/). The user is redirected to app_domain?calendly=connected — no frontend POST …/callback/ step. See Calendly guide.


Complete OAuth callback​

After the provider redirects to your frontend callback page, POST the authorization code:

POST /api/v1/{workspace_id}/integrations/{provider_key}/callback/
Authorization: Bearer <token>
Content-Type: application/json

Request body (HubSpot)​

{
"code": "authorization_code_from_provider",
"state": "oauth_state_from_connect_response",
"redirect_uri": "https://events.pana.space/auth/oauth/callback?provider=hubspot"
}

Request body (Pipedrive)​

{
"code": "authorization_code_from_provider",
"state": "oauth_state_from_connect_response",
"redirect_uri": "https://events.pana.space/auth/oauth/callback?provider=pipedrive"
}

Request body (Google Calendar)​

Include "provider": "google".

{
"code": "authorization_code_from_google",
"state": "oauth_state_from_connect_response",
"redirect_uri": "https://events.pana.space/auth/oauth/callback/?provider=google-calendar",
"provider": "google"
}

Response (200 OK) — Google Calendar​

{
"connected": true,
"connection_id": "880e8400-e29b-41d4-a716-446655440010",
"message": "Google Calendar connected successfully",
"app_domain": "https://events.pana.space"
}

Salesforce may include:

{
"webhook_base_url": "https://eventsapi.pana.space"
}

Response (200 OK)​

{
"connected": true,
"connection_id": "880e8400-e29b-41d4-a716-446655440010",
"message": "HubSpot connected successfully",
"app_domain": "https://events.pana.space"
}

Sync connection​

POST /api/v1/integrations/connections/{connection_id}/sync/
Authorization: Bearer <token>
Content-Type: application/json

Request body (CRM sync to event)​

{
"event_id": "550e8400-e29b-41d4-a716-446655440000"
}

Queue async sync (Celery):

{
"event_id": "550e8400-e29b-41d4-a716-446655440000",
"background": true
}

Response (200 OK)​

{
"created": 12,
"updated": 5,
"total": 17,
"connection": {
"id": "880e8400-e29b-41d4-a716-446655440010",
"provider_key": "hubspot",
"status": "connected",
"last_sync_at": "2026-07-06T12:05:00+00:00"
}
}

Response (202 Accepted) — background sync​

{
"status": "queued",
"connection_id": "880e8400-e29b-41d4-a716-446655440010"
}

Disconnect​

DELETE /api/v1/integrations/connections/{connection_id}/
Authorization: Bearer <token>

Returns 204 No Content on success.


Register CRM webhook (HubSpot / Pipedrive)​

After connect, register the inbound webhook with the provider (Pana UI does this for Pipedrive automatically; HubSpot uses Copy webhook or this API):

POST /api/v1/integrations/connections/{connection_id}/actions/register-webhook/
Authorization: Bearer <token>
Content-Type: application/json

Request body​

{
"webhook_base_url": "https://eventsapi.pana.space"
}

Optional — omit to derive the URL from the incoming request host.

Response (200 OK)​

{
"registered": true,
"webhook_url": "https://eventsapi.pana.space/api/v1/integrations/webhooks/pipedrive/550e8400-e29b-41d4-a716-446655440000/"
}

Inbound webhooks (from CRM / telephony)​

POST /api/v1/integrations/webhooks/{provider_key}/{workspace_id}/

Public — no JWT. Provider-specific payload and signature verification.

ProviderExample URL
HubSpothttps://eventsapi.pana.space/api/v1/integrations/webhooks/hubspot/{workspace_id}/
Pipedrivehttps://eventsapi.pana.space/api/v1/integrations/webhooks/pipedrive/{workspace_id}/
Calendlyhttps://eventsapi.pana.space/api/v1/integrations/calendly/webhook/

Legacy aliases (/api/v1/integrations/hubspot/webhook/{workspace_id}/, etc.) still work but prefer the unified HubSpot/Pipedrive paths above. Calendly uses the dedicated /calendly/webhook/ route.

Set INTEGRATIONS_ASYNC_WEBHOOKS=true on the backend to queue processing via Celery.


OAuth redirect URLs​

Frontend callback (HubSpot, Pipedrive, Salesforce, Google Calendar, Slack)​

Register these in each provider’s developer console (production):

ProviderCallback URL
HubSpothttps://events.pana.space/auth/oauth/callback?provider=hubspot
Pipedrivehttps://events.pana.space/auth/oauth/callback?provider=pipedrive
Salesforcehttps://events.pana.space/auth/oauth/callback?provider=salesforce
Google Calendarhttps://events.pana.space/auth/oauth/callback/?provider=google-calendar
Slackhttps://events.pana.space/auth/oauth/callback?provider=slack

Local development: replace host with http://localhost:3000.

Backend callback (Calendly only)​

Calendly OAuth completes on the API host:

https://eventsapi.pana.space/api/v1/integrations/calendly/callback/

Local: http://localhost:8000/api/v1/integrations/calendly/callback/

Set API_BASE_URL or CALENDLY_CALLBACK_URL on the backend if the public API origin differs from the request host. See Calendly guide.


Connect flow summary​

Standard OAuth (HubSpot, Pipedrive, Salesforce, Google Calendar, Slack):

  1. POST …/{provider_key}/connect/ → { "auth_url": "…" }
  2. User completes OAuth in browser
  3. Frontend receives code + state at /auth/oauth/callback?provider=…
  4. POST …/{provider_key}/callback/ → { "connected": true, "connection_id": "…" }
  5. GET …/connections/ → list connections (no secrets)
  6. POST …/connections/{id}/sync/ → sync data (CRM contacts or Calendly bookings)

Calendly:

  1. POST …/calendly/connect/ with backend redirect_uri and app_domain
  2. User completes OAuth at Calendly
  3. GET …/calendly/callback/ on the API (backend exchanges code, registers webhook)
  4. Browser redirect to app_domain?calendly=connected

Knowlarity: API-key connect via connect body — no OAuth redirect.


Legacy per-provider routes​

These remain for backward compatibility. New clients should use the platform API above.

Base path: /api/v1/integrations/

Most routes require JWT auth. OAuth callbacks and provider webhooks are public.

Google Places​

GET /api/v1/integrations/google-places/autocomplete/
GET /api/v1/integrations/google-places/details/

Google Calendar​

Prefer platform connect/callback with provider_key=google-calendar and "provider": "google" in the body.

Legacy calendar routes (Google / Outlook):

POST /api/v1/integrations/calendar/connect/
POST /api/v1/integrations/calendar/callback/
GET /api/v1/integrations/calendar/status/
POST /api/v1/integrations/calendar/disconnect/
POST /api/v1/integrations/calendar/create-demo-event/

Connect (platform) — returns { "auth_url": "https://accounts.google.com/o/oauth2/v2/auth?…" }.

Callback (platform) — include "provider": "google".

Create demo event — { "workspace_id": "<uuid>", "start_time": "…", "end_time": "…", "attendee_email": "…" } creates a Google Calendar event with Meet link.

Pana event sync — when a workspace event has calendar_sync_enabled, create/update triggers Google Calendar sync. Virtual, hybrid, and webinar events also receive a Google Meet link on the calendar entry. The Meet URL is saved on the event as custom_fields_data.google_calendar_meet_link.

Setup guide: Google Calendar integration

Calendly​

Prefer platform connect (POST …/calendly/connect/) with backend redirect_uri. OAuth callback is GET on the API — not the frontend OAuth page.

POST /api/v1/{workspace_id}/integrations/calendly/connect/
GET /api/v1/integrations/calendly/callback/
GET /api/v1/integrations/calendly/status/
POST /api/v1/integrations/calendly/disconnect/
GET /api/v1/integrations/calendly/sync/
POST /api/v1/integrations/calendly/webhook/
GET /api/v1/integrations/calendly/event-types/
GET /api/v1/integrations/calendly/available-times/
POST /api/v1/integrations/calendly/create-meeting/
POST /api/v1/integrations/calendly/create-booking/

Connect — { "redirect_uri": "https://eventsapi.pana.space/api/v1/integrations/calendly/callback/", "app_domain": "https://events.pana.space/…" }.

Sync — GET …/sync/?workspace_id=<uuid> or platform POST …/connections/{id}/sync/.

Webhook — Calendly POSTs invitee events to …/calendly/webhook/ (registered automatically on connect).

Setup guide: Calendly integration

HubSpot​

Legacy workspace-agnostic routes. Prefer platform connect/callback with provider_key=hubspot.

POST /api/v1/integrations/hubspot/connect/
POST /api/v1/integrations/hubspot/callback/
GET /api/v1/integrations/hubspot/status/
POST /api/v1/integrations/hubspot/disconnect/
POST /api/v1/integrations/hubspot/sync/
GET /api/v1/integrations/hubspot/meetings/
POST /api/v1/integrations/hubspot/webhook/{workspace_id}/
POST /api/v1/integrations/hubspot/register-webhook/

Connect — same body as platform API; returns { "auth_url": "…" }.

Sync — { "event_id": "<uuid>", "auto_sync": true } to set default 30-minute auto-sync event.

Meetings — GET …/meetings/?workspace_id=<uuid>&start=<iso>&end=<iso>&sync_demo_bookings=true returns HubSpot CRM meetings for the date range. When sync_demo_bookings=true (default), upserts matching rows in Demo Bookings (source=hubspot, keyed by hubspot_meeting_id). Response includes optional demo_booking_sync: { created, updated }.

Setup guide: HubSpot integration

Pipedrive​

Legacy workspace-agnostic routes. Prefer platform connect/callback with provider_key=pipedrive.

POST /api/v1/integrations/pipedrive/connect/
POST /api/v1/integrations/pipedrive/callback/
GET /api/v1/integrations/pipedrive/status/
POST /api/v1/integrations/pipedrive/disconnect/
POST /api/v1/integrations/pipedrive/sync/
POST /api/v1/integrations/pipedrive/webhook/{workspace_id}/
POST /api/v1/integrations/pipedrive/register-webhook/

Connect — same body as platform API; returns { "auth_url": "https://oauth.pipedrive.com/oauth/authorize?…" }.

Sync — { "event_id": "<uuid>" } imports persons as leads on that event.

Setup guide: Pipedrive integration

Salesforce​

POST /api/v1/integrations/salesforce/connect/
POST /api/v1/integrations/salesforce/callback/
GET /api/v1/integrations/salesforce/status/
POST /api/v1/integrations/salesforce/disconnect/
POST /api/v1/integrations/salesforce/sync/
POST /api/v1/integrations/salesforce/webhook/{workspace_id}/
POST /api/v1/integrations/salesforce/setup-webhook/

Knowlarity (telephony)​

POST /api/v1/integrations/knowlarity/connect/
GET /api/v1/integrations/knowlarity/status/
POST /api/v1/integrations/knowlarity/disconnect/
POST /api/v1/integrations/knowlarity/register-notifications/
POST /api/v1/integrations/knowlarity/webhook/{workspace_id}/

Slack​

Legacy workspace-agnostic routes. Prefer platform connect/callback with provider_key=slack.

POST /api/v1/integrations/slack/connect/
POST /api/v1/integrations/slack/callback/
GET /api/v1/integrations/slack/status/
POST /api/v1/integrations/slack/disconnect/
GET /api/v1/integrations/slack/channels/
POST /api/v1/integrations/slack/test-notification/
POST /api/v1/integrations/webhooks/slack/{workspace_id}/

Connect — body includes redirect_uri (frontend callback with ?provider=slack). Returns { "auth_url": "https://slack.com/oauth/v2/authorize?…" }.

Callback — exchange code + state after OAuth. Stores bot token and default_channel from Slack’s incoming_webhook payload in Connection.config.

Test notification — POST …/test-notification/ with { "workspace_id": "<uuid>", "channel": "<channel_id>", "message": "…" }. Requires an active Slack connection.

Inbound webhook — optional Events API endpoint at POST …/webhooks/slack/{workspace_id}/. Requires SLACK_SIGNING_SECRET for signature verification in production.

Setup guide: Slack integration


Environment variables​

Backend operator configuration is documented in backend/.env.example. Key variables:

VariableProviders
HUBSPOT_CLIENT_ID, HUBSPOT_CLIENT_SECRETHubSpot
PIPEDRIVE_CLIENT_ID, PIPEDRIVE_CLIENT_SECRETPipedrive
SALESFORCE_CLIENT_ID, SALESFORCE_CLIENT_SECRETSalesforce (optional fallback)
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRETGoogle Calendar (prefer over GOOGLE_OAUTH_*)
CALENDLY_CLIENT_ID, CALENDLY_CLIENT_SECRETCalendly
API_BASE_URLCalendly OAuth/webhook public API origin (e.g. https://eventsapi.pana.space)
CALENDLY_CALLBACK_URLCalendly OAuth redirect override (optional)
CALENDLY_WEBHOOK_SIGNING_KEYCalendly inbound webhook signature verification
SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, SLACK_SIGNING_SECRETSlack

Salesforce workspaces can also store per-workspace Consumer Key/Secret via the connect API.


Outbound webhooks (your app)​

For your webhook subscriptions (lead.created, etc.), use Developers → Webhooks — separate from CRM inbound webhooks above.