Skip to content

Connections API

All connection endpoints require Executive access level.

List all configured connections with status info (no tokens exposed).

Response:

{
"connections": [
{
"provider": "xero",
"org_name": "DotCollective Pty Ltd",
"connected_by": "uuid",
"connected_at": "2026-03-01T10:00:00",
"token_expires_at": "2026-03-01T10:30:00"
}
]
}

Generate a Xero OAuth2 authorization URL. Opens in a popup window.

Response: { "url": "https://login.xero.com/identity/connect/authorize?..." }

Exchange the OAuth2 authorization code for tokens. Fetches tenant info, encrypts tokens, and stores in the connections table.

Body:

{
"code": "authorization_code_from_xero"
}

Disconnect Xero. Removes the stored connection.

Save an encrypted Productive API token.

Body:

{
"api_token": "string (required)"
}

Disconnect Productive.

Save an encrypted Slack bot token and target channel ID.

Body:

{
"bot_token": "xoxb-... (required)",
"channel_id": "C0123456789 (required)"
}

Disconnect Slack.

PUT /api/admin/connections/google-workspace

Section titled “PUT /api/admin/connections/google-workspace”

Save Google Workspace service account key and calendar ID.

Body:

{
"service_account_key": "{ ... } (required for new, optional for update)",
"calendar_id": "calendar-id@group.calendar.google.com (required)",
"admin_email": "admin@example.com (optional)"
}

DELETE /api/admin/connections/google-workspace

Section titled “DELETE /api/admin/connections/google-workspace”

Disconnect Google Workspace.

GET /api/admin/connections/google-workspace/status

Section titled “GET /api/admin/connections/google-workspace/status”

Check if Google Calendar integration is configured.

Response: { "configured": true, "calendar_id": "..." }

Remote.com is used as the Employer of Record (EOR) for international employees. It provides leave types, time-off management, and compensation data.

Save an encrypted Remote API token with optional configuration.

Body:

{
"api_token": "string (required for new, optional for update)",
"company_id": "string (optional)",
"environment": "production | sandbox (default: production)",
"org_name": "string (optional)"
}

Disconnect Remote. Also clears remote_employment_id from all people.

Health check — verifies the API token works by fetching company info.

Response:

{
"configured": true,
"company_name": "DotCollective",
"company_status": "active",
"environment": "production"
}

Scrapin provides LinkedIn profile enrichment for recruitment candidates and people.

Save an encrypted Scrapin API key.

Body:

{
"api_key": "string (required for new, optional for update)",
"org_name": "string (optional)"
}

Disconnect Scrapin.

GET /api/admin/connections/scrapin/alerts-config

Section titled “GET /api/admin/connections/scrapin/alerts-config”

Check if the Scrapin change alerts webhook is configured.

Response: { "configured": true, "webhook_url": "https://..." }

POST /api/admin/connections/scrapin/alerts-config

Section titled “POST /api/admin/connections/scrapin/alerts-config”

Configure the Scrapin webhook URL for profile change alerts.

Response: { "ok": true, "webhook_url": "https://..." }

Map internal users to their external IDs in Xero, Productive, and Remote.

List all active people with their external ID mappings.

Response:

{
"users": [
{
"person_id": "uuid",
"user_id": "uuid",
"name": "Name",
"email": "name@dotcollective.com.au",
"xero_id": "xero-employee-id",
"productive_id": "productive-person-id",
"remote_id": "remote-employment-id",
"google_id": "user-uuid"
}
]
}

PUT /api/admin/connections/user-mappings/:personId

Section titled “PUT /api/admin/connections/user-mappings/:personId”

Set an external ID for a person. Uses a provider-based approach.

Body:

{
"provider": "xero | productive | remote (required)",
"external_id": "string (required)"
}

POST /api/admin/connections/user-mappings/sync

Section titled “POST /api/admin/connections/user-mappings/sync”

Bulk-match people to an external service by email address.

Body:

{
"provider": "xero | productive | remote (required)",
"mappings": [
{ "email": "name@example.com", "external_id": "ext-id" }
]
}

Response: { "ok": true, "matched": 5, "total": 8 }