Logo
Search
API Docs

Go & Gin Server Integration

Framework Integrations

Go & Gin Server Integration: Handling Webhooks in a Go Server

Overview

If your assistant's server URL points at a Go application built with the Gin framework, you can handle webhook events by binding the JSON payload, switching on the event type, and returning a Gin JSON response. This page covers a worked handler, the response rules, and local testing.


Webhook Handler

func handleWebhook(c *gin.Context) {
    var data map[string]interface{}
    if err := c.ShouldBindJSON(&data); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }

    eventType := data["type"].(string)
    fmt.Printf("Webhook received: %s\n", eventType)

    switch eventType {
    case "call-started":
        call := data["call"].(map[string]interface{})
        fmt.Printf("Call %s started\n", call["id"])

    case "speech-update":
        fmt.Printf("User said: %s\n", data["transcript"])

    case "function-call":
        functionCall := data["functionCall"].(map[string]interface{})
        result := processFunction(
            functionCall["functionName"].(string),
            functionCall["parameters"],
        )
        c.JSON(200, gin.H{"result": result})
        return

    case "call-ended":
        fmt.Println("Call ended")
    }

    c.JSON(200, gin.H{"status": "ok"})
}

func main() {
    router := gin.Default()
    router.POST("/webhook", handleWebhook)
    router.Run(":3000")
}

Event Types & Response Codes

The handler above covers the most common categories — call lifecycle (call-started, call-ended, call-failed), speech (speech-update, transcript), and assistant events (function-call, conversation-update). For the complete event catalog, see Webhooks & Events.

Return the appropriate HTTP status from your handler:

Status CodeMeaning
200–299Success, event processed
400–499Client error, event rejected (not retried)
500–599Server error (will be retried)

For function-call events specifically, return the result in the response body (as shown above) rather than a bare status code. See Webhook Delivery: Retries, Timeouts & Debugging for the full retry mechanics and the 10-second response window.


Testing Locally

Use the core system's CLI listener with a tunneling service to send real events to your local Gin server:

# Terminal 1: Start your Go Gin server
go run main.go  # Your app on localhost:3000

# Terminal 2: Start a tunnel
ngrok http 4242

# Terminal 3: Start the webhook listener
core-system listen --forward-to localhost:3000/webhook

Then update your Sulus dashboard webhook URL to the tunnel's public URL. The data flow is: core system > tunnel > core-system listen (port 4242) > your Go Gin server. Remember core-system listen only forwards — it does not create a public URL itself. For CLI authentication across multiple accounts, see CLI Key Rotation & Multi-Account.