List CRM and scheduler partners
List the active CRM, service scheduler or DMS partners a rooftop can pick from.
GET
AuthBearer token (console user)Rate limitNot documentedProcessingOne database read.
Each item's _id is the partnerId you send when you save a CRM or service scheduler integration. Stored partner credentials (config) are left out. Without providerType, every active partner of every type is returned.
Before you call it
- You need the bearer token of a signed-in console user.
- The UI sends
providerType=crmon the CRM page andproviderType=service-scheduleron the service scheduler page. The value must match the stored provider type exactly. - One database read. The list comes back in the response. Rate limit: not documented.
Request parameters
Requiredalways sendOptionalcan be left out
| Parameter | Type | Required | Description |
|---|---|---|---|
| Header | — | — | — |
Authorization | string | Required | Bearer YOUR_TOKEN |
| Query | — | — | — |
providerType | string | Optional | Provider type to filter on, for example crm, service-scheduler, dms. Exact match. Leave it out to get all active partners. |
Request checklist
- Authenticate: set
Authorization: Bearer YOUR_TOKEN. - Filter: pass
providerType. - Keep the pick: keep
_id,providerNameandlogofrom the item the user picks. You send them aspartnerId,partnerNameandlogowhen you save.
Sample request
curl -X GET "https://api.spyne.ai/integrations/registry?providerType=crm" \
-H "Authorization: Bearer YOUR_TOKEN"import requests
res = requests.get(
"https://api.spyne.ai/integrations/registry",
params={"providerType": "crm"},
headers={"Authorization": "Bearer YOUR_TOKEN"},
)
partners = res.json()const res = await fetch(
"https://api.spyne.ai/integrations/registry?providerType=service-scheduler",
{ headers: { Authorization: "Bearer YOUR_TOKEN" } }
);
const partners = await res.json();Sample response
[
{
"_id": "<partnerId>",
"providerName": "examplecrm",
"providerType": "crm",
"method": { "API": { "<operation>": "<method config>" } },
"logo": "https://example.com/logo.png",
"pocEmails": ["[email protected]"],
"isActive": true,
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
]{
"statusCode": 401,
"message": "Authentication failed: Invalid Token - Bearer token required",
"errorCode": "AUTHENTICATION_ERROR",
"timestamp": "2026-01-01T00:00:00.000Z",
"requestId": "<requestId>",
"context": { "reason": "Invalid Token - Bearer token required" },
"path": "/integrations/registry?providerType=crm",
"method": "GET"
}{
"statusCode": 500,
"message": "Internal server error",
"errorCode": "INTERNAL_SERVER_ERROR",
"timestamp": "2026-01-01T00:00:00.000Z",
"requestId": "<requestId>",
"path": "/integrations/registry",
"method": "GET"
}Response parameters
The body is a JSON array. It is not wrapped in data.
| Parameter | Type | Description |
|---|---|---|
[]._id | string | Partner id. Send it as partnerId when you save. |
[].providerName | string | Partner name. Send it as partnerName. Service scheduler matching on the server uses the exact lowercase name. |
[].providerType | string | Provider type, for example crm. |
[].method | object | How the partner is connected, as stored. |
[].logo | string | Logo URL. Send it as logo. |
[].pocEmails | string[] | Partner contact emails. |
[].apiResponseMapping | object | Optional. Field mapping for the partner's API responses. |
[].ingest | object | Optional. Which data pulls are switched on for this partner. |
[].isActive | boolean | Always true here. Inactive partners are not returned. |
[].createdAt, [].updatedAt | string | Timestamps. |
Errors
| Status | Code | When it happens |
|---|---|---|
401 | AUTHENTICATION_ERROR | No Bearer token, or user management rejects the token. |
500 | INTERNAL_SERVER_ERROR | Unexpected server error. |
An unknown providerType returns 200 with an empty array.
What happens next
Show the list to the user. When they pick a partner, collect the rooftop's dealer id at that partner and save the integration.
Updated about 1 hour ago
Did this page help you?
