This is the Golang SDK for Convoy. It makes it easy to interact with the Convoy API. You can view the full API Reference here
$ go get github.com/frain-dev/convoy-go/v2The client subpackage is generated from Convoy's OpenAPI spec via
oapi-codegen and covers the
full /api/v1 surface with typed requests and responses:
import "github.com/frain-dev/convoy-go/v2/client"
c, err := client.NewClientWithResponses("https://us.getconvoy.cloud/api",
client.WithRequestEditorFn(func(_ context.Context, req *http.Request) error {
req.Header.Set("Authorization", "Bearer "+apiKey)
// Pin the API version this client was generated from.
req.Header.Set("X-Convoy-Version", "2025-11-24")
return nil
}))
data := map[string]interface{}{"amount": 100, "currency": "USD"}
endpointID, eventType := "endpoint-id", "invoice.paid"
resp, err := c.CreateEndpointEventWithResponse(ctx, projectID,
client.CreateEndpointEventJSONRequestBody{
EndpointId: &endpointID,
EventType: &eventType,
Data: &data,
})Do not edit client/client.gen.go by hand; regenerate with
./scripts/generate.sh (CI on frain-dev/convoy dispatches this when the
spec changes). The hand-written client below and webhook verify are never
touched by generation.
To begin you need to define a Client.
Below are the several ways you can configure a client depending on your needs.
// Convoy Cloud (US): https://us.getconvoy.cloud/api/v1
// Convoy Cloud (EU): https://eu.getconvoy.cloud/api/v1
// Self-hosted: https://your-instance/api/v1
baseURL := "https://us.getconvoy.cloud/api/v1"
// Regular Client
c := convoy.New(baseURL, apiKey, projectID)
// Add a Custom HTTP Client
client := &http.Client{}
c := convoy.New(baseURL, apiKey, projectID,
convoy.OptionHTTPClient(client))
// Add a SQS Client
so := &convoy.SQSOptions{
Client: sqs.New(),
QueueUrl: "queue-url",
}
c := convoy.New(baseURL, apiKey, projectID,
convoy.OptionSQSOptions(so))
// Add a Kafka Client
ko := &convoy.KafkaOptions{
Client: &kafka.Client{},
Topic: "kafka-topic",
}
c := convoy.New(baseURL, apiKey, projectID,
convoy.OptionKafkaOptions(ko))Please see go reference for other options available to use to configure your client.
body := &convoy.CreateEndpointRequest{
Name: "endpoint-name",
// Get a test ingest URL from https://playground.getconvoy.io
URL: "https://us.getconvoy.cloud/ingest/DQzxCcNKTB7SGqzm",
Secret: "endpoint-secret",
SupportEmail: "notifications@getconvoy.io",
}
endpoint, err := c.Endpoints.Create(ctx, body, nil)
if err != nil {
return err
}Store the Endpoint ID, so you can use it in subsequent requests for creating subscriptions or sending events.
body := &convoy.CreateSubscriptionRequest{
Name: "endpoint-subscription",
EndpointID: "endpoint-id",
FilterConfig: &convoy.FilterConfiguration{
EventTypes: []string{"*"},
},
}
subscription, err := c.Subscriptions.Create(ctx, body)
if err != nil {
return err
}You can send events to Convoy via HTTP or via any supported message broker. See here to see the list of supported brokers.
// Send an event to a single endpoint.
body := &CreateEventRequest{
EventType: "event.type",
EndpointID: "endpoint-id",
IdempotencyKey: "unique-event-id",
Data: []byte(`{"version": "Convoy v24.0.0"}`),
}
event, err := c.Events.Create(ctx, body)
if err != nil {
return err
}
// Send event to multiple endpoints.
body := &CreateFanoutEventRequest{
EventType: "event.type",
OwnerID: "unique-user-id",
IdempotencyKey: "unique-event-id",
Data: []byte(`{"version": "Convoy v24.0.0"}`),
}
event, err := c.Events.FanoutEvent(ctx, body)
if err != nil {
return err
}Note: The body struct used above is the same used for the message brokers below.
// Send event to a single endpoint.
err := c.SQS.WriteEvent(ctx, body)
if err != nil {
return err
}
// Send event to multiple endpoints.
err := c.SQS.WriteFanoutEvent(ctx, body)
if err != nil {
return err
}This library depends on kafka-go to configure Kafka Clients.
// Send event to a single endpoint.
err := c.Kafka.WriteEvent(ctx, body)
if err != nil {
return err
}
// Send event to multiple endpoints.
err := c.Kafka.WriteFanoutEvent(ctx, body)
if err != nil {
return err
}This client supports verifying simple and advanced webhook signatures. Verify with the raw request body, before parsing it.
webhook := convoy.NewWebhook(&convoy.WebhookOpts{
Secret: "endpoint-secret",
})
// Verify an incoming *http.Request. This reads the request body; read it
// yourself first and use VerifyPayload if you need the body afterwards.
func handler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "failed to read body", http.StatusBadRequest)
return
}
if err := webhook.VerifyPayload(body, r.Header.Get("X-Convoy-Signature")); err != nil {
http.Error(w, "invalid signature", http.StatusBadRequest)
return
}
// signature is valid; process the event using body
w.WriteHeader(http.StatusOK)
}The following table identifies which version of the Convoy API is supported by this (and past) versions of this repo (convoy-go)
| convoy-go Version | Convoy API Version |
|---|---|
| v2.1.5 | 0001-01-01 |
| v2.1.6 | 0001-01-01 |
| v2.1.7 | 0001-01-01 |
| v2.2.0 | 2025-11-24 |
The MIT License (MIT). Please see License File for more information.