Query and mutate dealership customer data, vehicle inventory, and dealer information through a standard GraphQL endpoint.
POST https://gql.space-auto.com/graphql
Pass your API key in the Authorization header. Read-only keys can run queries; read+write keys can also run mutations.
Authorization: YOUR_API_KEY
Search customers with pagination, filtering, and sorting. Returns customer profiles with all related data (deals, appointments, trade-ins, credit applications, references, activity, labels, favorites).
| Filter | Type | Description |
|---|---|---|
search | String | Full-text search across name, email, phone, address |
unseenOnly | Boolean | Only customers with unread events |
minDate / maxDate | String | Created-at date range (ISO 8601) |
minUpdatedAt / maxUpdatedAt | String | Updated-at date range (ISO 8601) |
includeIds / excludeIds | [ID] | Include or exclude specific customer IDs |
dealerIds | [ID] | Filter by assigned dealer |
labels | [String] | Filter by customer labels |
Sort fields: firstName, lastName, email, phone, createdAt, updatedAt. Pagination: skip + limit (max 100).
curl -X POST https://gql.space-auto.com/graphql \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_KEY" \
-d '{
"query": "query ($input: SearchCustomersInput!) { searchCustomers(input: $input) { total customers { id firstName lastName email phone deals { vin paymentType } appointments { type status appointmentAt } } } }",
"variables": {
"input": {
"pagination": { "limit": 10, "skip": 0 },
"sort": { "field": "updatedAt", "order": "desc" },
"filters": { "search": "gmail.com" }
}
}
}'const ENDPOINT = "https://gql.space-auto.com/graphql";
const API_KEY = "YOUR_API_KEY";
interface SearchCustomersResponse {
data: {
searchCustomers: {
total: number;
customers: Array<{
id: string;
firstName: string;
lastName: string;
email: string;
phone: string;
}>;
};
};
}
async function searchCustomers(search: string, limit = 10, skip = 0) {
const res = await fetch(ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: API_KEY,
},
body: JSON.stringify({
query: `query ($input: SearchCustomersInput!) {
searchCustomers(input: $input) {
total
customers { id firstName lastName email phone }
}
}`,
variables: {
input: {
pagination: { limit, skip },
sort: { field: "updatedAt", order: "desc" },
filters: { search },
},
},
}),
});
return (await res.json()) as SearchCustomersResponse;
}Search vehicle inventory with rich filtering: make/model/trim hierarchy, condition, price/year/mileage ranges, body style, fuel, transmission, drivetrain, features, and more.
curl -X POST https://gql.space-auto.com/graphql \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_KEY" \
-d '{
"query": "query ($input: SearchVehiclesInput!) { searchVehicles(input: $input) { total vehicles { vin year make model trim condition price mileage status photos } } }",
"variables": {
"input": {
"pagination": { "limit": 10 },
"sort": { "field": "price", "order": "asc" },
"filters": {
"condition": ["new"],
"make": [{ "value": "Toyota", "model": [{ "value": "Camry" }] }],
"price": { "from": 20000, "to": 40000 }
}
}
}
}'async function searchVehicles(filters: Record<string, any>, limit = 10) {
const res = await fetch(ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: API_KEY },
body: JSON.stringify({
query: `query ($input: SearchVehiclesInput!) {
searchVehicles(input: $input) {
total
vehicles { vin year make model trim condition price mileage status photos }
}
}`,
variables: { input: { pagination: { limit }, filters } },
}),
});
return res.json();
}List all dealers (salespeople) for the authorized dealership. No input required.
curl -X POST https://gql.space-auto.com/graphql \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_KEY" \
-d '{ "query": "{ dealers { id email firstName lastName phone jobTitle department isWorking isAutoAssignmentEnabled locations } }" }'All mutations require write permission. Each mutation accepts a customer field for identification (provide at least one of id, email, or phone) plus optional profile fields. Two assignment-related fields apply consistently across all mutations:
customer.location — optional; if it matches a configured dealership location (case-sensitive), it is appended to the customer's locations array. Unknown names are silently ignored.customer.leadSource — optional; applied only when creating a new customer. Never overwrites an existing customer's lead source.label (top-level) — optional; tags the customer with a dealership label (matched case-insensitively; auto-created if it does not exist).Create or update a customer lead, optionally associating a vehicle deal.
VIN deduplication: if the customer already has a deal for the supplied VIN, no new deal is created (the mutation still succeeds and returns the customer with the existing deal).
curl -X POST https://gql.space-auto.com/graphql \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_KEY" \
-d '{
"query": "mutation ($input: SubmitLeadInput!) { submitLead(input: $input) { id firstName lastName email phone deals { vin paymentType } labels { name color } } }",
"variables": {
"input": {
"customer": {
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Doe",
"phone": "+15551234567"
},
"deal": {
"vin": "1HGCG5655WA041389",
"paymentType": "financing",
"notes": "Interested in the 2024 model"
},
"label": "Hot Lead"
}
}
}'Schedule a customer appointment.
type (AppointmentType): sales, service, delivery, otherstatus (AppointmentStatus): set, confirmed, declined, completed, missed, unresolvedcurl -X POST https://gql.space-auto.com/graphql \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_KEY" \
-d '{
"query": "mutation ($input: SubmitAppointmentInput!) { submitAppointment(input: $input) { id firstName lastName appointments { id type status appointmentAt } } }",
"variables": {
"input": {
"customer": { "email": "jane@example.com" },
"appointment": {
"type": "sales",
"status": "set",
"appointmentAt": "2025-03-15T14:00:00Z",
"vin": "1HGCG5655WA041389",
"notes": "Customer prefers afternoon"
},
"label": "Follow-up"
}
}
}'Create a communication log (meeting, text, email, phone) or an internal note for a customer. All entries are attributed to the dealership's crm@space.auto system dealer.
type (SubmitLogType): meeting, text, email, phone (communication logs) or note (internal, dealer-only note).body (required): main text content.transcription and summary (optional): appended to body as separate Transcription: ... / Summary: ... sections.datetime (optional ISO 8601): backdate a log entry. Ignored for notes.subject (optional): stored separately on the activity data.When to use which type: pick meeting/text/email/phone when recording an actual customer interaction so it surfaces in the dealership activity feed with the right filter. Pick note for internal observations, reminders, or context not tied to a customer-facing communication.
curl -X POST https://gql.space-auto.com/graphql \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_KEY" \
-d '{
"query": "mutation ($input: SubmitLogInput!) { submitLog(input: $input) { id firstName lastName activity { id type action createdAt data } } }",
"variables": {
"input": {
"customer": { "email": "jane@example.com" },
"log": {
"type": "phone",
"subject": "Follow-up on 2024 RAV4",
"body": "Customer called to ask about financing options.",
"datetime": "2025-03-15T14:00:00Z",
"transcription": "Agent: Hi Jane... Jane: Hi, I was wondering...",
"summary": "Ready to schedule a test drive next week."
}
}
}
}'curl -X POST https://gql.space-auto.com/graphql \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_API_KEY" \
-d '{
"query": "mutation ($input: SubmitLogInput!) { submitLog(input: $input) { id firstName lastName activity { id type action createdAt data } } }",
"variables": {
"input": {
"customer": { "email": "jane@example.com" },
"log": {
"type": "note",
"body": "Customer prefers afternoon appointments. Works night shifts."
}
}
}
}'type SubmitLogType = "meeting" | "text" | "email" | "phone" | "note";
async function submitLog(params: {
customerEmail?: string;
customerPhone?: string;
customerId?: string;
type: SubmitLogType;
body: string;
subject?: string;
datetime?: string;
transcription?: string;
summary?: string;
label?: string;
}) {
const { customerEmail, customerPhone, customerId, label, ...log } = params;
const res = await fetch(ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: API_KEY },
body: JSON.stringify({
query: `mutation ($input: SubmitLogInput!) {
submitLog(input: $input) {
id firstName lastName
activity { id type action createdAt data }
}
}`,
variables: {
input: {
customer: { id: customerId, email: customerEmail, phone: customerPhone },
log,
...(label ? { label } : {}),
},
},
}),
});
return res.json();
}| Mutation | Description | Key Input Fields |
|---|---|---|
submitCreditApplication | Submit a credit application with personal, employment, and financial info | type ("primary" | "co-signer"), ssn, birthDate, applicantType, homeOwnership, employmentStatus, monthlyIncome |
submitTradein | Record a trade-in vehicle with valuation data | vin, year, make, model, mileage, condition (excellent | good | fair), minTrade, maxTrade, payoffType (neither | loan | lease), payoffAmount |
submitReference | Add a personal/professional reference | firstName, lastName, phone, relationship |
submitLog | Log a customer communication or create an internal note (attributed to crm@space.auto) | type (meeting|text|email|phone|note), body, subject, datetime, transcription, summary |
label)Every mutation accepts an optional top-level label: String. When provided:
"VIP", "vip", and "Vip" all match the same label).Returned labels { name color } selection reflects the customer's full set of labels after the mutation.
location and leadSourceThe shared customer object on every mutation accepts two additional optional fields that govern customer assignment:
location: String — dealership location name. Validated against the dealership's configured locations (case-sensitive exact match on the name). If it matches, the name is appended to the customer's locations array (deduplicated). If it does not match, the value is silently ignored — the mutation still succeeds. Applies to both new and existing customers.leadSource: String — free-form lead-source label. Only applied when a new customer is created. For existing customers this field is ignored to preserve the original attribution.| Enum | Values |
|---|---|
DealPaymentType | cash, leasing, financing |
DealSource | web, phone, walk, other |
DealProcessingStatus | fresh, desking, appointment, closed, archived |
AppointmentType | sales, service, delivery, other |
AppointmentStatus | set, confirmed, declined, completed, missed, unresolved |
TradeinCondition | excellent, good, fair |
TradeinPayoffType | neither, loan, lease |
ApplicantType | self, spouse, relative, registeredDomesticPartner, civilUnion, other |
HomeOwnership | rent, mortgage, own, other |
EmploymentStatus | employed, unemployed, retired, selfemployed, other |
VehicleCondition | new, used, certified |
VehicleStatus | available, unavailable, hidden |
SubmitLogType | meeting, text, email, phone, note |
GraphQL errors are returned in the standard errors array. HTTP status is always 200 for valid GraphQL requests. Check data and errors in the response body.
/space/{dealershipId}/events.
Uses the same API key for authentication.
Receive real-time event notifications via AWS AppSync Events WebSocket. Events are pushed when any data changes — customer updates, new leads, deal status changes, appointments, messages, and more.
WebSocket: wss://gql-events.space-auto.com/event/realtime
Subprotocol: aws-appsync-event-ws
Auth is passed as a WebSocket subprotocol. Base64URL-encode a JSON auth object and prefix with header-:
# 1. Build auth JSON
{ "host": "gql-events.space-auto.com", "Authorization": "YOUR_API_KEY" }
# 2. Base64URL encode (replace + with -, / with _, strip = padding)
# 3. Prefix with "header-"
# 4. Pass as second WebSocket subprotocol alongside "aws-appsync-event-ws"Events are published to channels scoped by dealership:
/space/{dealershipId}/events
Your API key authorizes access only to the dealership it belongs to. Subscribing to a different dealership's channel will be rejected.
| Step | Direction | Message |
|---|---|---|
| 1. Connect | — | Open WebSocket with subprotocols: aws-appsync-event-ws + header-{base64url_auth} |
| 2. Init | Client → Server | { "type": "connection_init" } |
| 3. Ack | Server → Client | { "type": "connection_ack", "connectionTimeoutMs": 300000 } |
| 4. Subscribe | Client → Server | { "type": "subscribe", "id": "uuid", "channel": "/space/{id}/events", "authorization": { "host": "...", "Authorization": "..." } } |
| 5. Subscribed | Server → Client | { "type": "subscribe_success", "id": "uuid" } |
| 6. Events | Server → Client | { "type": "data", "id": "uuid", "event": "{...}" } |
| 7. Keepalive | Server → Client | { "type": "ka" } — server sends periodically; close if not received within connectionTimeoutMs |
| 8. Unsubscribe | Client → Server | { "type": "unsubscribe", "id": "uuid" } |
Each data message contains a JSON-stringified event in the event field. Common event properties:
| Field | Description |
|---|---|
type | Entity type: customer, deal, email, sms, call, internal, tradeins, payments, referents, external-lead, documents, appointments |
action | What happened: create, update, merge, delete, send |
dealershipId | UUID of the dealership |
actorType | "customer" or "dealer" |
actorId | UUID of the actor |
const EVENTS_HOST = "gql-events.space-auto.com";
const API_KEY = "YOUR_API_KEY";
const DEALERSHIP_ID = "YOUR_DEALERSHIP_ID";
function base64url(obj: object): string {
return btoa(JSON.stringify(obj))
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
}
function connect() {
const authProtocol =
"header-" + base64url({ host: EVENTS_HOST, Authorization: API_KEY });
const ws = new WebSocket(
`wss://${EVENTS_HOST}/event/realtime`,
["aws-appsync-event-ws", authProtocol],
);
ws.onopen = () => {
console.log("WebSocket opened, sending connection_init");
ws.send(JSON.stringify({ type: "connection_init" }));
};
ws.onmessage = (evt) => {
const msg = JSON.parse(evt.data as string);
if (msg.type === "connection_ack") {
console.log("Connected, timeout:", msg.connectionTimeoutMs);
ws.send(JSON.stringify({
type: "subscribe",
id: crypto.randomUUID(),
channel: `/space/${DEALERSHIP_ID}/events`,
authorization: { host: EVENTS_HOST, Authorization: API_KEY },
}));
}
if (msg.type === "subscribe_success") {
console.log("Subscribed to channel");
}
if (msg.type === "data") {
const event = JSON.parse(msg.event);
console.log("Event:", event.type, event.action, event);
}
};
ws.onerror = (e) => console.error("WebSocket error", e);
ws.onclose = () => {
console.log("Disconnected — reconnect after delay");
setTimeout(connect, 3000);
};
}
connect();Connections close after the timeout if keepalive is missed, or on network issues. Implement exponential backoff for reconnection (e.g., 1s, 2s, 4s, max 30s). Always re-subscribe after reconnecting.
/mcp.
Authenticate with Authorization: Bearer <api_key>.
Model Context Protocol endpoint for AI agent integration. Implements JSON-RPC 2.0 over HTTP, compatible with Claude, Cursor, and other MCP clients.
POST https://gql.space-auto.com/mcp
All methods except ping require an API key:
Authorization: Bearer YOUR_API_KEY
Note the Bearer prefix — this differs from the GraphQL API which uses the raw key.
All requests use JSON-RPC 2.0 format:
{ "jsonrpc": "2.0", "id": 1, "method": "METHOD_NAME", "params": { ... } }Initialize the MCP session. Returns server capabilities, name, and instructions.
curl -X POST https://gql.space-auto.com/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "my-client", "version": "1.0.0" }
}
}'List available tools. Tools requiring write permission are hidden if your key is read-only.
curl -X POST https://gql.space-auto.com/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }'Execute a tool by name with arguments. Returns the tool result as text content.
curl -X POST https://gql.space-auto.com/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_customers",
"arguments": { "search": "gmail.com", "limit": 5 }
}
}'const MCP_ENDPOINT = "https://gql.space-auto.com/mcp";
const API_KEY = "YOUR_API_KEY";
let requestId = 0;
async function mcpRequest(method: string, params?: Record<string, any>) {
const res = await fetch(MCP_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${API_KEY}`,
},
body: JSON.stringify({
jsonrpc: "2.0",
id: ++requestId,
method,
params,
}),
});
return res.json();
}
// Initialize session
await mcpRequest("initialize", {
protocolVersion: "2024-11-05",
capabilities: {},
clientInfo: { name: "my-app", version: "1.0.0" },
});
// List tools
const tools = await mcpRequest("tools/list");
// Call a tool
const result = await mcpRequest("tools/call", {
name: "search_customers",
arguments: { search: "gmail.com", limit: 5 },
});
// Read a resource
const guide = await mcpRequest("resources/read", {
uri: "docs://api-guide",
});| Tool | Permission | Description |
|---|---|---|
search_customers | Read | Search customers with filtering, sorting, and pagination |
search_vehicles | Read | Search vehicle inventory with rich filters |
fetch_dealers | Read | List dealers with contact info and status |
submit_lead | Write | Create or update a customer lead with optional deal |
submit_credit_application | Write | Submit a credit application |
submit_tradein | Write | Record a trade-in vehicle |
submit_reference | Write | Add a reference for credit verification |
submit_appointment | Write | Schedule a customer appointment |
submit_log | Write | Log a customer communication (meeting|text|email|phone) or create an internal note |
| URI | Name | Description |
|---|---|---|
schema://graphql | GraphQL Schema | Full GraphQL SDL schema |
docs://api-guide | API Usage Guide | Comprehensive API documentation (Markdown) |
curl -X POST https://gql.space-auto.com/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{ "jsonrpc": "2.0", "id": 1, "method": "resources/read", "params": { "uri": "docs://api-guide" } }'| Code | Meaning |
|---|---|
-32700 | Parse error (invalid JSON) |
-32600 | Invalid request (missing method) |
-32601 | Method not found |
-32602 | Invalid params / tool execution failed |
-32603 | Internal error |
-1001 | Unauthorized (missing or invalid API key) |
-1002 | Forbidden (insufficient permissions) |
LLM-optimized integration reference for all Space Auto External API services. Copy and provide to any AI assistant for complete API access.
You have access to the Space Auto External API — a dealership data platform with three integration interfaces. All services share the same API key and are scoped to a single dealership.
| Service | Endpoint | Auth Header | Use When |
|---|---|---|---|
| GraphQL API | POST https://gql.space-auto.com/graphql | Authorization: {key} | Structured queries/mutations with field selection |
| Events WebSocket | wss://gql-events.space-auto.com/event/realtime | Base64 in URL params | Real-time change notifications |
| MCP Server | POST https://gql.space-auto.com/mcp | Authorization: Bearer {key} | AI agent tool calling (JSON-RPC 2.0) |
A single API key grants access to all services. Permission levels:
Authorization: {key} (raw). MCP uses Authorization: Bearer {key} (with Bearer prefix). Events use base64-encoded headers in the WebSocket URL.Endpoint: POST https://gql.space-auto.com/graphql
Content-Type: application/json
Auth: Authorization: {api_key}
Search customers with pagination, filtering, and sorting. Returns profiles with deals, appointments, trade-ins, credit applications, references, activity, labels, favorites.
Input: SearchCustomersInput with optional pagination (skip, limit max 100), sort (field: firstName|lastName|email|phone|createdAt|updatedAt, order: asc|desc), filters (search: string, unseenOnly: bool, minDate/maxDate: ISO string, includeIds/excludeIds: [ID], dealerIds: [ID], labels: [String]).
Search vehicle inventory. Input: SearchVehiclesInput with optional pagination, sort (field: price|mileage|year|mpg|views|likes|make|model|inventoryDate|updatedAt|stock, order: asc|desc), filters (condition: [VehicleCondition!] (new|used|certified), status: [VehicleStatus!] (available|unavailable|hidden), make: [{value, model: [{value, trim}]}], body/fuel/transmission/driveline/color: [String], year/price/mileage: {from, to}, vins: [String], substatus: [String], feature filters: safetyFeatures/technologyFeatures/exteriorFeatures/interiorFeatures/mechanicalFeatures: [String]).
No input. Returns: [{ id, email, status, firstName, lastName, phone, jobTitle, department, isWorking, isAutoAssignmentEnabled, locations }].
All mutations share the same CustomerIdentifierInput. In addition to identity/address fields, it accepts location (validated against dealership locations; appended to customer.locations; unknown values silently ignored) and leadSource (applied only on NEW customers; never overwritten on existing). All mutations also accept an optional top-level label: String that tags the customer with a dealership label (matched case-insensitively; created if missing; de-duplicated for the customer).
Input: customer (at least one of id, email, phone; optional firstName, lastName, address fields, comments), optional deal (vin: String!, paymentType: DealPaymentType (cash|leasing|financing), notes), optional label: String. Deduplicated by (customer, VIN): no duplicate deal is created if the customer already has one for the same VIN.
Input: customer identifier, appointment (type: AppointmentType! (sales|service|delivery|other), status: AppointmentStatus! (set|confirmed|declined|completed|missed|unresolved), optional appointmentAt: AWSDateTime, vin, location, notes), optional label: String.
Input: customer identifier, creditapplication (type: String "primary"|"co-signer" (not enum due to hyphen), applicantType: ApplicantType, personal info: firstName/lastName/ssn/birthDate, current address + homeOwnership: HomeOwnership/homeMonthlyPayment, employmentStatus: EmploymentStatus/employer/jobTitle/monthlyIncome, other income), optional label: String.
Input: customer identifier, tradein (vehicle: vin/year/make/model/trim/mileage, condition: TradeinCondition (excellent|good|fair), valuation: minTrade/averageTrade/maxTrade/allowanceAmount/actualCashValue, payoff: payoffType: TradeinPayoffType (neither|loan|lease)/payoffLender/payoffAmount/equity), optional label: String.
VIN deduplication: if a VIN is provided and the customer already has a trade-in with that VIN, no new record is created. Trade-ins without a VIN are always inserted.
Input: customer identifier, reference (firstName, lastName, phone, email, relationship, address fields), optional label: String.
Input: customer identifier, log (type: SubmitLogType! (meeting|text|email|phone|note), body: String!, optional subject, datetime: AWSDateTime, transcription, summary), optional label: String.
Behavior: note creates an internal note (ActionType.Internal). Other types create communication logs (ActionType.Log) with data.communicationType = type. transcription and summary are appended to body automatically. All entries are attributed to the dealership's crm@space.auto system dealer.
submitLead — first contact / inbound interest; optionally attach a deal.submitAppointment — scheduled future interactions (sales, service, delivery).submitLog (type = phone/email/text/meeting) — record a past communication that already happened.submitLog (type = note) — internal observation or context, not a customer-facing interaction.submitCreditApplication / submitTradein / submitReference — structured records tied to deal closing.Endpoint: wss://gql-events.space-auto.com/event/realtime
SubProtocol: aws-appsync-event-ws
Channel: /space/{dealershipId}/events
Auth is passed as a WebSocket subprotocol. Base64URL-encode { "host": "gql-events.space-auto.com", "Authorization": "{api_key}" } (replace + with -, / with _, strip =), prefix with header-, and pass as a subprotocol alongside aws-appsync-event-ws.
After connection: send { type: "connection_init" }. Receive connection_ack with connectionTimeoutMs. Subscribe: send { type: "subscribe", id: "uuid", channel: "/space/{dealershipId}/events", authorization: { host: "...", Authorization: "..." } }. Receive subscribe_success. Data arrives as { type: "data", id: "...", event: "JSON_STRING" }. Server sends { type: "ka" } keepalive periodically; close connection if not received within timeout. Unsubscribe: send { type: "unsubscribe", id: "..." }.
Events have: type (customer|deal|email|sms|call|internal|tradeins|payments|referents|external-lead|documents|appointments), action (create|update|merge|delete|send), dealershipId, actorType (customer|dealer), actorId.
Endpoint: POST https://gql.space-auto.com/mcp
Protocol: JSON-RPC 2.0
Auth: Authorization: Bearer {api_key} (note the Bearer prefix)
1. Call initialize with { protocolVersion: "2024-11-05", capabilities: {}, clientInfo: { name, version } }. 2. Call tools/list to discover tools. 3. Call tools/call with { name, arguments }. 4. Optionally call resources/list and resources/read with { uri }.
search_customers: args — search, skip, limit, sortField, sortOrder, unseenOnly, minDate, maxDate, includeIds, excludeIds.
search_vehicles: args — condition, make, model, trim, body, fuel, transmission, driveline, color, yearFrom/yearTo, priceFrom/priceTo, mileageFrom/mileageTo, status, limit, skip, sortField, sortOrder.
fetch_dealers: no args.
All write tools accept an optional label arg that tags the customer with a dealership label (case-insensitive match, auto-created if missing).
submit_lead: args — customerId/customerEmail/customerPhone (at least one), firstName, lastName, vin, paymentType (cash|leasing|financing), notes, label.
submit_appointment: args — customer identifier + type (sales|service|delivery|other), status (set|confirmed|declined|completed|missed|unresolved), appointmentAt, vin, location, notes, label.
submit_credit_application: args — customer identifier + credit application fields (type (primary|co-signer), applicantType, homeOwnership, employmentStatus, ssn, birthDate, address, employment, income), label.
submit_tradein: args — customer identifier + vehicle details, condition (excellent|good|fair) + valuation + payoffType (neither|loan|lease) + payoff info, label.
submit_reference: args — customer identifier + reference contact details, label.
submit_log: args — customer identifier + type (meeting|text|email|phone|note) [required], body [required], subject, datetime, transcription, summary, label. Use meeting/text/email/phone for past communications; use note for internal observations. Transcription/summary are appended to body server-side.
schema://graphql: Full GraphQL SDL schema. docs://api-guide: API usage guide (Markdown).
| Task | Best Service | Reason |
|---|---|---|
| Build a search UI with specific fields | GraphQL API | Field selection reduces payload |
| Live dashboard showing updates | Events WebSocket | Push-based, no polling |
| AI assistant answering questions | MCP Server | Tool-calling protocol, structured for LLMs |
| Bulk data export | GraphQL API | Pagination with skip/limit |
| Create leads from chatbot | MCP Server | Natural fit for AI-driven workflows |
| Trigger alerts on new events | Events WebSocket | Real-time notifications |