Discussions

Ask a Question
Back to all

Go High Level to ServiceM8 API Calls

We're trying to automatically create a new client (Company) in ServiceM8 from a Go High Level webhook.

What We’re Trying to Do:
When a form is submitted or event is triggered in Go High Level (GHL), a webhook sends the contact data to our Wix backend (Velo).

Our Wix backend (http-functions.js) parses that data and makes a POST request to the ServiceM8 /Company.json endpoint.

The goal is to create a new client in ServiceM8 with:

  • Company name
  • Contact name
  • Email
  • Phone
  • Address

Setup Details:
GHL webhook β†’ Wix backend (custom function) β†’ ServiceM8 API.

Using fetch() in Wix to post data to https://api.servicem8.com/api_1.0/Company.json.

Authentication via API key (sent in X-API-Key header).


The Problem:

❌ We keep receiving this error from ServiceM8:

{"errorCode":400,"message":"Bad Request. No data received in POST"}
import { ok, serverError } from 'wix-http-functions';
import { fetch } from 'wix-fetch';
import { Buffer } from 'buffer';

const SERVICE_M8_API_TOKEN = "XXXX"; // Replace with your actual key

export function post_ghlWebhook(request) {
    console.log("πŸ”₯ Webhook Triggered");

    return request.body.text()
        .then(raw => {
            console.log("🧾 Raw body text:", raw);
            let data;

            try {
                data = JSON.parse(raw);
                console.log("πŸ“¦ Parsed Data:", data);
            } catch (err) {
                console.error("❌ JSON Parse Error:", err.message);
                return serverError({ error: "Invalid JSON", details: err.message });
            }

            const name = data.customData?.name || data.full_name || '';
            const email = data.customData?.email || data.email || '';
            const phone = data.customData?.phone || data.phone || '';
            const address = data.full_address || `${data.address1 || ''}, ${data.city || ''} ${data.state || ''} ${data.postal_code || ''}`.trim();

            console.log("πŸ”‘ Extracted:", { name, email, phone, address });

            return createCompanyOnly({ name, email, phone, address });
        });
}

function toFormEncoded(obj) {
    return Object.entries(obj)
        .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
        .join('&');
}

async function createCompanyOnly({ name, email, phone, address }) {
    try {
        const companyPayload = {
            company_name: name,
            contact_name: name,
            email,
            phone,
            address_line1: address
        };

        const encodedBody = toFormEncoded(companyPayload);
        console.log("πŸ“€ Payload to Company API:", companyPayload);
        console.log("πŸ”’ Encoded Body:", encodedBody);

        const response = await fetch("https://api.servicem8.com/api_1.0/Company.json", {
            method: "POST",
            headers: {
                "X-API-Key": SERVICE_M8_API_TOKEN,
                "Content-Type": "application/x-www-form-urlencoded",
                "Accept": "application/json"
            },
            body: Buffer.from(encodedBody, 'utf8')
        });

        const responseText = await response.text();
        console.log("πŸ‘€ Company API Response:", responseText);

        if (!response.ok) {
            return serverError({ error: "Company creation failed", response: responseText });
        }

        return ok({ message: "Company created successfully", response: responseText });

    } catch (error) {
        console.error("πŸ’₯ Error:", error.message);
        return serverError({ error: error.message });
    }
}