Custom event endpoints use flat reporting query parameters: GET https://data.goodmetrics.io/{gmID}/events/custom/{resource}?start={start}&end={end}.
Use the event_type_is filter to select events by name or ID. If omitted, custom-event endpoints use all available events for the site.
curl "https://data.goodmetrics.io/{gmID}/events/custom/top-events?start=1771872000&end=1772476799&event_type_is=signup%2Cupgrade_to_paid" \ -H "Authorization: Bearer YOUR_API_KEY"const gmID = '{gmID}';const apiKey = 'YOUR_API_KEY';const params = new URLSearchParams({ "start": "1771872000", "end": "1772476799", "event_type_is": "signup,upgrade_to_paid"});
const response = await fetch(`https://data.goodmetrics.io/${gmID}/events/custom/top-events?${params}`, { headers: { Authorization: `Bearer ${apiKey}` }});
console.log(await response.json());import jsonimport urllib.parseimport urllib.request
gm_id = "{gmID}"api_key = "YOUR_API_KEY"params = urllib.parse.urlencode({ "start": "1771872000", "end": "1772476799", "event_type_is": "signup,upgrade_to_paid"})
request = urllib.request.Request( f"https://data.goodmetrics.io/{gm_id}/events/custom/top-events?{params}", headers={"Authorization": f"Bearer {api_key}"},)
with urllib.request.urlopen(request) as response: print(json.load(response))import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
class GoodMetricsExample { public static void main(String[] args) throws Exception { var gmID = "{gmID}"; var apiKey = "YOUR_API_KEY"; var url = "https://data.goodmetrics.io/" + gmID + "/events/custom/top-events?start=1771872000&end=1772476799&event_type_is=signup%2Cupgrade_to_paid";
var request = HttpRequest.newBuilder() .uri(URI.create(url)) .header("Authorization", "Bearer " + apiKey) .GET() .build();
var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); }}using System;using System.Collections.Generic;using System.Linq;using System.Net.Http;using System.Net.Http.Headers;
var gmID = "{gmID}";var apiKey = "YOUR_API_KEY";var query = new Dictionary<string, string>{ ["start"] = "1771872000", ["end"] = "1772476799", ["event_type_is"] = "signup,upgrade_to_paid"};var queryString = string.Join("&", query.Select(parameter => $"{Uri.EscapeDataString(parameter.Key)}={Uri.EscapeDataString(parameter.Value)}"));
var url = $"https://data.goodmetrics.io/{gmID}/events/custom/top-events?{queryString}";
using var client = new HttpClient();using var request = new HttpRequestMessage(HttpMethod.Get, url);request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
using var response = await client.SendAsync(request);Console.WriteLine(await response.Content.ReadAsStringAsync());<?php$gmID = "{gmID}";$apiKey = "YOUR_API_KEY";$params = http_build_query([ "start" => "1771872000", "end" => "1772476799", "event_type_is" => "signup,upgrade_to_paid"]);
$url = "https://data.goodmetrics.io/{$gmID}/events/custom/top-events?{$params}";
$context = stream_context_create([ "http" => [ "method" => "GET", "header" => "Authorization: Bearer {$apiKey}\r\n", ],]);
$response = file_get_contents($url, false, $context);echo $response;package main
import ( "fmt" "io" "net/http" "net/url")
func main() { gmID := "{gmID}" apiKey := "YOUR_API_KEY"
params := url.Values{} params.Set("start", "1771872000") params.Set("end", "1772476799") params.Set("event_type_is", "signup,upgrade_to_paid")
request, _ := http.NewRequest( "GET", "https://data.goodmetrics.io/"+gmID+"/events/custom/top-events?"+params.Encode(), nil, ) request.Header.Set("Authorization", "Bearer "+apiKey)
response, _ := http.DefaultClient.Do(request) defer response.Body.Close()
body, _ := io.ReadAll(response.Body) fmt.Println(string(body))}Overview endpoints
Section titled “Overview endpoints”| Endpoint | Description |
|---|---|
GET /{gmID}/events/custom/overview/chart | Custom event chart. |
GET /{gmID}/events/custom/overview/cities | City overview for custom events. |
GET /{gmID}/events/custom/overview/completion-locations | Completion location overview. |
GET /{gmID}/events/custom/overview/countries | Country overview for custom events. |
GET /{gmID}/events/custom/overview/devices | Device overview for custom events. |
GET /{gmID}/events/custom/overview/initial-landing-pages | Initial landing page overview for custom events. |
GET /{gmID}/events/custom/overview/initial-referrers | Initial referrer overview for custom events. |
GET /{gmID}/events/custom/overview/landing-pages | Landing page overview for custom events. |
GET /{gmID}/events/custom/overview/referrers | Referrer overview for custom events. |
GET /{gmID}/events/custom/overview/utm-source-mediums | UTM source/medium overview for custom events. |
GET /{gmID}/events/custom/overview/top-events | Top event overview. |
Table endpoints
Section titled “Table endpoints”| Endpoint | Alignment key |
|---|---|
GET /{gmID}/events/custom/cities | city |
GET /{gmID}/events/custom/completion-locations | page |
GET /{gmID}/events/custom/countries | country |
GET /{gmID}/events/custom/devices | device |
GET /{gmID}/events/custom/initial-landing-pages | page |
GET /{gmID}/events/custom/initial-referrers | initialReferrer |
GET /{gmID}/events/custom/landing-pages | page |
GET /{gmID}/events/custom/referrers | referrer |
GET /{gmID}/events/custom/utm-source-mediums | utmSourceMedium |
GET /{gmID}/events/custom/top-events | name |
Custom event responses often include meta.events, eventCompletions, eventValue, and eventConversionRate. Conversion responses also expose conversionNumerator and conversionDenominator, making the inputs to each rounded conversion rate explicit. Overall totals use the selected site-wide cohort, while dimension rows use the sessions or visitors attributed to that row.
See Common Recipes for more request examples.