Campaigns

Group links into campaigns that add UTM tags to every destination.

Campaigns need the Pro plan or above. Add a link to a campaign with campaignId when you create or change it.

Every path below starts with https://bgum.me/api/v1/workspaces/{workspaceId}. Send your API key in the Authorization header as described in the API overview.

OperationMethod and path
List campaignsGET /campaigns
Create a campaignPOST /campaigns
Get a campaignGET /campaigns/{campaignId}
Change a campaignPUT /campaigns/{campaignId}
Archive a campaignDELETE /campaigns/{campaignId}

List campaigns

GET /campaigns

Lists campaigns, newest first (up to 500), with how many links each has and their clicks from people in the last 30 days.

Full path
/api/v1/workspaces/{workspaceId}/campaigns
API key scope
links:read
Role needed
Viewer or above

Path parameters

NameTypeRequiredDescription
workspaceId string Yes Your workspace ID, from Settings → Workspace.

Query parameters

NameTypeRequiredDescription
includeArchived boolean No true includes archived campaigns. Default false.

Example request

curl

curl "https://bgum.me/api/v1/workspaces/$WORKSPACE_ID/campaigns" \
  -H "Authorization: Bearer $BGL_API_KEY"

JavaScript

const res = await fetch(`https://bgum.me/api/v1/workspaces/${process.env.WORKSPACE_ID}/campaigns`, {
  headers: {
    Authorization: `Bearer ${process.env.BGL_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json();
console.log(data);

Python

import os
import requests

res = requests.get(
    f"https://bgum.me/api/v1/workspaces/{os.environ['WORKSPACE_ID']}/campaigns",
    headers={
        "Authorization": f"Bearer {os.environ['BGL_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())

Response

200 OK · application/json

JSON

{
  "items": [
    {
      "id": "aiQrz1XgekFP",
      "name": "Spring sale",
      "utmSource": "newsletter",
      "utmMedium": "email",
      "utmCampaign": "spring-2026",
      "linkCount": 12,
      "humanClicks30Days": 431,
      "createdAt": "2026-10-14T22:49:33.6455044+00:00",
      "archived": false
    }
  ]
}

Errors

Any request can also return the general errors: 401 for a missing or wrong key, 403 for a missing scope or plan feature, 404 for an unknown workspace and 429 when you're sending too fast.

Create a campaign

POST /campaigns

Creates a campaign. Its UTM values are added to the destination of every link in it, unless the destination already sets them.

Full path
/api/v1/workspaces/{workspaceId}/campaigns
API key scope
campaigns:write
Role needed
Manager or above
Plan
Needs campaigns in your plan (compare plans)

Path parameters

NameTypeRequiredDescription
workspaceId string Yes Your workspace ID, from Settings → Workspace.

Request body

JSON (Content-Type: application/json). Leave out fields you don't need.

NameTypeRequiredDescription
name string Yes Up to 200 characters.
utmSource string No Value for utm_source, e.g. newsletter. Up to 200 characters.
utmMedium string No Value for utm_medium, e.g. email.
utmCampaign string No Value for utm_campaign, e.g. spring-2026.

Example request

curl

curl -X POST "https://bgum.me/api/v1/workspaces/$WORKSPACE_ID/campaigns" \
  -H "Authorization: Bearer $BGL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Spring sale",
  "utmSource": "newsletter",
  "utmMedium": "email",
  "utmCampaign": "spring-2026"
}'

JavaScript

const res = await fetch(`https://bgum.me/api/v1/workspaces/${process.env.WORKSPACE_ID}/campaigns`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BGL_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "Spring sale",
    "utmSource": "newsletter",
    "utmMedium": "email",
    "utmCampaign": "spring-2026"
  }),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json();
console.log(data);

Python

import os
import requests

res = requests.post(
    f"https://bgum.me/api/v1/workspaces/{os.environ['WORKSPACE_ID']}/campaigns",
    headers={
        "Authorization": f"Bearer {os.environ['BGL_API_KEY']}",
    },
    json={
        "name": "Spring sale",
        "utmSource": "newsletter",
        "utmMedium": "email",
        "utmCampaign": "spring-2026",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())

Response

201 Created · application/json

JSON

{
  "id": "aiQrz1XgekFP",
  "name": "Spring sale",
  "utmSource": "newsletter",
  "utmMedium": "email",
  "utmCampaign": "spring-2026",
  "linkCount": 0,
  "humanClicks30Days": 0,
  "createdAt": "2026-10-14T22:49:33.6455044+00:00",
  "archived": false
}

Errors

StatusCodeMeaning
422campaign.name_requiredThe campaign has no name.
422campaign.name_too_longThe name is longer than 200 characters.
422campaign.utm_too_longA UTM value is longer than 200 characters.

Any request can also return the general errors: 401 for a missing or wrong key, 403 for a missing scope or plan feature, 404 for an unknown workspace and 429 when you're sending too fast.

Get a campaign

GET /campaigns/{campaignId}

Returns one campaign, archived or not.

Full path
/api/v1/workspaces/{workspaceId}/campaigns/{campaignId}
API key scope
links:read
Role needed
Viewer or above

Path parameters

NameTypeRequiredDescription
workspaceId string Yes Your workspace ID, from Settings → Workspace.
campaignId string Yes The campaign's ID, as returned when it was created or listed.

Example request

curl

curl "https://bgum.me/api/v1/workspaces/$WORKSPACE_ID/campaigns/aiQrz1XgekFP" \
  -H "Authorization: Bearer $BGL_API_KEY"

JavaScript

const res = await fetch(`https://bgum.me/api/v1/workspaces/${process.env.WORKSPACE_ID}/campaigns/aiQrz1XgekFP`, {
  headers: {
    Authorization: `Bearer ${process.env.BGL_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json();
console.log(data);

Python

import os
import requests

res = requests.get(
    f"https://bgum.me/api/v1/workspaces/{os.environ['WORKSPACE_ID']}/campaigns/aiQrz1XgekFP",
    headers={
        "Authorization": f"Bearer {os.environ['BGL_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())

Response

200 OK · application/json

JSON

{
  "id": "aiQrz1XgekFP",
  "name": "Spring sale",
  "utmSource": "newsletter",
  "utmMedium": "email",
  "utmCampaign": "spring-2026",
  "linkCount": 12,
  "humanClicks30Days": 431,
  "createdAt": "2026-10-14T22:49:33.6455044+00:00",
  "archived": false
}

Errors

StatusCodeMeaning
404campaign.not_foundNo campaign with that ID in this workspace. When you add a link to a campaign, an archived one counts as missing.

Any request can also return the general errors: 401 for a missing or wrong key, 403 for a missing scope or plan feature, 404 for an unknown workspace and 429 when you're sending too fast.

Change a campaign

PUT /campaigns/{campaignId}

Replaces the campaign's name and UTM values. Leaving a UTM value out removes it. Links in the campaign use the new values straight away.

Full path
/api/v1/workspaces/{workspaceId}/campaigns/{campaignId}
API key scope
campaigns:write
Role needed
Manager or above
Plan
Needs campaigns in your plan (compare plans)

Path parameters

NameTypeRequiredDescription
workspaceId string Yes Your workspace ID, from Settings → Workspace.
campaignId string Yes The campaign's ID, as returned when it was created or listed.

Request body

JSON (Content-Type: application/json). Leave out fields you don't need.

NameTypeRequiredDescription
name string Yes Up to 200 characters.
utmSource string No Value for utm_source.
utmMedium string No Value for utm_medium.
utmCampaign string No Value for utm_campaign.

Example request

curl

curl -X PUT "https://bgum.me/api/v1/workspaces/$WORKSPACE_ID/campaigns/aiQrz1XgekFP" \
  -H "Authorization: Bearer $BGL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Spring sale",
  "utmSource": "newsletter",
  "utmMedium": "email",
  "utmCampaign": "spring-2026-extended"
}'

JavaScript

const res = await fetch(`https://bgum.me/api/v1/workspaces/${process.env.WORKSPACE_ID}/campaigns/aiQrz1XgekFP`, {
  method: "PUT",
  headers: {
    Authorization: `Bearer ${process.env.BGL_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "Spring sale",
    "utmSource": "newsletter",
    "utmMedium": "email",
    "utmCampaign": "spring-2026-extended"
  }),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json();
console.log(data);

Python

import os
import requests

res = requests.put(
    f"https://bgum.me/api/v1/workspaces/{os.environ['WORKSPACE_ID']}/campaigns/aiQrz1XgekFP",
    headers={
        "Authorization": f"Bearer {os.environ['BGL_API_KEY']}",
    },
    json={
        "name": "Spring sale",
        "utmSource": "newsletter",
        "utmMedium": "email",
        "utmCampaign": "spring-2026-extended",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())

Response

200 OK · application/json

JSON

{
  "id": "aiQrz1XgekFP",
  "name": "Spring sale",
  "utmSource": "newsletter",
  "utmMedium": "email",
  "utmCampaign": "spring-2026-extended",
  "linkCount": 12,
  "humanClicks30Days": 431,
  "createdAt": "2026-10-14T22:49:33.6455044+00:00",
  "archived": false
}

Errors

StatusCodeMeaning
404campaign.not_foundNo campaign with that ID in this workspace. When you add a link to a campaign, an archived one counts as missing.
422campaign.name_requiredThe campaign has no name.
422campaign.name_too_longThe name is longer than 200 characters.
422campaign.utm_too_longA UTM value is longer than 200 characters.

Any request can also return the general errors: 401 for a missing or wrong key, 403 for a missing scope or plan feature, 404 for an unknown workspace and 429 when you're sending too fast.

Archive a campaign

DELETE /campaigns/{campaignId}

Archives the campaign. Its links keep working and keep their UTM tags; new links can't be added to it.

Full path
/api/v1/workspaces/{workspaceId}/campaigns/{campaignId}
API key scope
campaigns:write
Role needed
Manager or above

Path parameters

NameTypeRequiredDescription
workspaceId string Yes Your workspace ID, from Settings → Workspace.
campaignId string Yes The campaign's ID, as returned when it was created or listed.

Example request

curl

curl -X DELETE "https://bgum.me/api/v1/workspaces/$WORKSPACE_ID/campaigns/aiQrz1XgekFP" \
  -H "Authorization: Bearer $BGL_API_KEY"

JavaScript

const res = await fetch(`https://bgum.me/api/v1/workspaces/${process.env.WORKSPACE_ID}/campaigns/aiQrz1XgekFP`, {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.BGL_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
// 204 No Content: nothing to read.

Python

import os
import requests

res = requests.delete(
    f"https://bgum.me/api/v1/workspaces/{os.environ['WORKSPACE_ID']}/campaigns/aiQrz1XgekFP",
    headers={
        "Authorization": f"Bearer {os.environ['BGL_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
# 204 No Content: nothing to read.

Response

204 No Content

Errors

StatusCodeMeaning
404campaign.not_foundNo campaign with that ID in this workspace. When you add a link to a campaign, an archived one counts as missing.

Any request can also return the general errors: 401 for a missing or wrong key, 403 for a missing scope or plan feature, 404 for an unknown workspace and 429 when you're sending too fast.

Something missing or unclear? Tell us and we'll improve this page.