Error codes

Every error code the API returns, what it means and what to do about it.

When a request fails, the response body is a problem object with a stable code. Check code in your program; the detail text is for people and may change. The API overview shows the full shape.

JSON

{
  "type": "https://docs.blackgumlabs.com/errors/alias.taken",
  "title": "Conflict",
  "status": 409,
  "detail": "“spring-sale” is already in use on this domain. Try another back-half.",
  "code": "alias.taken",
  "traceId": "00-68e8a002645c783ee9ceb0fb177c10ea-b45bb3b99037b204-00"
}

Errors without a code:

StatusWhenWhat to do
401The Authorization header is missing, isn't a bgl_ key, or the key is wrong, revoked or expired. The body is empty.Check the header is Authorization: Bearer bgl_… and the key is active in API keys.
404The path doesn't exist, or a QR image format isn't png, svg or pdf.Check the method and path against this reference.
413A QR code logo is larger than 256 KB, or a request body is larger than 1 MB.Send a smaller file or split the request.
429You're sending requests faster than the rate limit. The body is empty.Wait a few seconds and try again, slowing down. See rate limits.
500Something went wrong on our side.Try again. If it keeps happening, contact us with the traceId from the response.

Any request

CodeStatusMeaningWhat to do
workspace.not_found404The workspace ID in the path doesn't exist, or your key or account can't use it.Check the workspace ID in Settings → Workspace. An API key only works for the workspace it was created in.
access.forbidden403Your role in the workspace, or the key's scopes, don't allow this.Give the key the scope listed for the endpoint, or ask an Administrator for a role that allows it.
apikey.owner_removed403The person who created this API key is no longer in the workspace.Create a new key while signed in as a current member.
plan.feature_required403The feature isn't included in the organisation's plan. API access itself needs the Business plan.Upgrade in Usage and plan, or leave out the option that needs it.
organisation.mfa_required403The organisation requires two-factor authentication and the key's creator (or you) hasn't turned it on.Turn on two-factor authentication in Settings, then try again.
account.email_unverified403The account that owns the key hasn't confirmed its email address, so it can't create links.Confirm the email address from the message we sent, or ask for a new one from the sign-in page.
account.suspended403The organisation is suspended, usually after a failed payment, so new links and QR codes can't be made.The owner can settle the payment in Usage and plan. Existing links keep working.
installation.read_only403This installation of the platform has no valid licence, so links, QR codes and other settings can't be created or changed. Reading still works.Existing short links keep redirecting. Ask the platform's administrator to install a licence key in Admin › Licence.
csrf.header_missing403A signed-in browser request changed something without the X-BGL-Request: 1 header.Only affects calls made with a browser session. Calls with an API key don't need it.
CodeStatusMeaningWhat to do
alias.required422A custom back-half was expected but was empty.Send a back-half, or leave alias out to get a random one.
alias.too_short422The back-half is shorter than the minimum (usually 3 characters).Use a longer back-half.
alias.too_long422The back-half is longer than the maximum (usually 64 characters).Use a shorter back-half.
alias.invalid_characters422The back-half has characters other than letters, numbers, hyphens and underscores.Remove spaces, slashes, dots and other symbols.
alias.invalid_edges422The back-half starts or ends with a hyphen or underscore.Move or remove the hyphen or underscore.
alias.reserved409The back-half is a word this service uses itself, such as admin or docs.Choose another back-half.
alias.prohibited422The back-half contains a word that isn't allowed.Choose another back-half.
alias.taken409Another link on that domain already uses the back-half, including archived and deleted links.Choose another back-half. Check first with GET /aliases/availability.
alias.generation_failed409We couldn't generate a unique random back-half.Try the request again.
destination.required422destinationUrl is missing or empty.Send the full address the link should go to.
destination.too_long422The destination is longer than 4,096 characters.Shorten the address, for example by removing tracking parameters.
destination.invalid422The destination isn't a valid web address.Send a full address such as https://example.com/page.
destination.scheme422Only http and https addresses can be shortened.Use an http:// or https:// address.
destination.credentials422The address contains a username or password (user:pass@host).Remove the credentials from the address.
destination.private422The address points to a private network, localhost or an internal name.Links must point to a public website.
destination.loop422The address is itself a short link on this service, which would loop.Use the final destination instead.
routing.too_many_rules422routing has more than 20 rules.Combine rules: one rule can list several countries, devices and languages.
routing.rule_invalid422A rule in routing.rules is null.Send each rule as an object.
routing.rule_condition_required422A rule has no countries, devices or languages, so it would catch everyone.Give the rule at least one condition, or use the link's own destination for everyone.
routing.too_many_countries422A rule lists more than 60 countries.Split the countries across two rules with the same destination.
routing.country_invalid422A country isn't a two-letter ISO 3166 code.Use codes such as AU, NZ or GB.
routing.device_invalid422A device isn't one of ios, android, windows, macos or other.Use one of those values.
routing.too_many_languages422A rule lists more than 20 languages.Split the languages across two rules.
routing.language_invalid422A language isn't a two- or three-letter code.Use the primary language code only, such as en, fr or zh (not en-AU).
routing.split_size422routing.split has one destination, or more than five.Split traffic between 2 and 5 destinations, or send an empty split.
routing.variant_invalid422A destination in routing.split is null.Send each destination as an object.
routing.weight_invalid422A split weight isn't a whole number from 1 to 1,000.Use weights such as 50 and 50, or 80 and 20.
routing.name_too_long422A rule or split name is longer than 100 characters.Use a shorter name.
routing.id_invalid422A rule or split id isn't up to 12 lower-case letters and digits.Send back the id you were given, or leave it out to get a new one.
routing.id_duplicate422Two rules or split destinations have the same id.Give each its own id, or leave ids out.
routing.app_url_invalid422An app link isn't an app address (myapp://…), an Android intent: link or an https address.Use the link your app registers, such as myapp://product/42. javascript:, data: and file: links aren't allowed.
tags.too_many422More than 20 tags on one link.Use 20 tags or fewer.
tags.too_long422A tag is longer than 50 characters.Shorten the tag.
idempotency.key_too_long422The Idempotency-Key is longer than 200 characters.Use a shorter key, such as a UUID.
idempotency.key_reused409The Idempotency-Key was already used for a different request in the last 48 hours.Use a new key for each different link. Reuse a key only to retry exactly the same request.
idempotency.target_deleted409The link created by this Idempotency-Key has since been deleted.Use a new key to create the link again.
platform.no_default_domain409The service has no default short domain set up yet.Contact support.
bulk.empty422The bulk request had no links in it.Send at least one link in links.
bulk.too_many429The bulk request has more links than your plan allows in one go (1,000 on Business).Split the links into smaller requests.

Folders, tags, saved views and bulk changes

CodeStatusMeaningWhat to do
folder.not_found404No folder with that ID in this workspace.Check the folder ID with GET /folders.
folder.name_required422The folder has no name.Send a name.
folder.name_too_long422The name is longer than 100 characters.Use a shorter name.
folder.name_taken409Another folder in the same place already has that name (case doesn't matter).Choose another name, or put the folder somewhere else.
folder.too_deep409The folder would be more than 3 levels deep, or would leave one of its folders more than 3 levels deep.Put it higher up, or move its folders up first.
folder.into_itself409A folder can't move into itself or one of its own folders.Choose a folder outside it, or moveToTop.
folder.too_many409The workspace already has 500 folders.Delete folders you no longer use.
tag.not_found404No tag with that name in this workspace.Check the name with GET /tags. URL-encode it in the path.
tag.name_required422The new name is empty.Send the new name in name.
view.not_found404No saved view with that ID that you can see.Check the ID with GET /saved-views. Other people's private views aren't visible.
view.not_yours403Someone else saved this view, so only they can change it.Save your own copy instead.
view.name_required422The view has no name.Send a name.
view.name_too_long422The name is longer than 100 characters.Use a shorter name.
view.share_forbidden403Only people who can edit links can share views with the workspace.Save it without shared, or ask a Manager to share one.
view.too_many409You already have 50 saved views in this workspace.Delete views you no longer use.
utm_template.not_found404No UTM template with that ID in this workspace.Check the ID with GET /utm-templates.
utm_template.name_required422The template has no name.Send a name.
utm_template.name_too_long422The name is longer than 100 characters.Use a shorter name.
utm_template.name_taken409Another template in the workspace already has that name (case doesn't matter).Choose another name, or change the existing template.
utm_template.empty422Every UTM tag is empty.Fill in at least one of utmSource, utmMedium, utmCampaign, utmTerm or utmContent.
utm_template.value_too_long422A UTM tag is longer than 200 characters.Shorten it.
utm_template.too_many409The workspace already has 100 UTM templates.Delete templates you no longer use.
bulk.action_invalid422action isn't one of move, addTags, removeTags, pause, resume, setExpiry, clearExpiry or delete.Check the spelling; it's case-insensitive.
bulk.selection_invalid422The request sent both linkIds and filter, or neither, or an empty linkIds.Send exactly one of them.
bulk.too_many_ids422linkIds has more than 1,000 IDs.Send them in several requests, or use filter.
bulk.too_many_matches409The filter matches more than 10,000 links.Narrow the filter, for example by createdFrom and createdTo, and send several requests.
bulk.count_changed409The filter now matches a different number of links than expectedCount, so nothing was changed. count says how many it matches now.Check the list again, then send the new count.
bulk.tags_required422addTags or removeTags was sent without any tags.List the tags in tags.
bulk.ends_at_required422setExpiry was sent without endsAt.Send the time the links should stop working.

QR codes

CodeStatusMeaningWhat to do
qr.not_found404No QR code with that ID in this workspace.Check the QR code ID.
quota.qr_exhausted429The organisation has used this month's allowance of new QR codes. The response has limit and resetsAt fields.Wait until resetsAt, or upgrade. Existing QR codes keep working.
qr.colour_invalid422A colour isn't a six-digit hex value.Send colours like #15181C.
qr.inverted422The foreground is lighter than the background. Many scanners can't read that.Use a dark foreground on a light background.
qr.low_contrast422The colours are too close together to scan reliably (contrast below 4:1).Use a darker foreground or a lighter background.
qr.quiet_zone_invalid422The margin is outside 2 to 10 modules.Use a quietZone between 2 and 10. 4 is standard.
qr.error_correction_invalid422errorCorrection isn't one of the allowed values.Use Low, Medium, Quartile or High.
qr.logo_needs_high422Codes with a logo must use High error correction.Remove the logo first, or keep High.
qr.logo_size422The logo is empty or larger than 256 KB.Send a PNG of 256 KB or less.
qr.logo_invalid422The logo isn't a PNG we can read.Export the logo again as a standard PNG.
qr.logo_small422The logo is smaller than 16 × 16 pixels.Use a larger image; square with a transparent background works best.
qr.id_generation_failed409We couldn't generate a unique QR code ID.Try the request again.

Analytics and chart notes

CodeStatusMeaningWhat to do
analytics.time_zone_invalid422timeZone isn't a time zone we know.Use an IANA name such as Australia/Sydney or America/New_York, or UTC.
analytics.time_zone_history422A report in a zone other than the workspace's is counted from raw clicks, and the period starts before the oldest raw clicks kept.Start the period later, as the message says, or leave out timeZone to use the workspace's zone.
note.not_found404No note with that ID in this workspace.Check the ID with GET /notes.
note.text_required422text is missing or blank.Write the note, such as "Newsletter sent".
note.text_too_long422text is longer than 200 characters.Shorten the note.
note.date_required422date is missing.Send the date as YYYY-MM-DD, in the workspace's time zone.
note.date_invalid422date is before 2000 or after 2100.Check the year.
note.time_invalid422time isn't a 24-hour time.Send HH:MM, such as 09:30, or leave time out.
note.target_conflict422Both linkId and campaignId were sent.A note is for one link, one campaign or the whole workspace: send at most one of them.
CodeStatusMeaningWhat to do

Conversions

CodeStatusMeaningWhat to do
conversion.click_invalid422The click value isn't a bgl_click ID we issued, or it was changed.Send the bgl_click value exactly as it arrived on your page, without decoding or trimming it.
conversion.click_not_found404The click ID is for a link in another workspace.Use an API key for the workspace that owns the link.
conversion.event_required422event is missing.Name the event, such as signup or purchase.
conversion.event_too_long422event is longer than 64 characters.Use a shorter event name.
conversion.event_invalid422event contains control characters such as line breaks.Use plain text.
conversion.event_id_too_long422eventId is longer than 200 characters.Use a shorter ID, such as your order number.
conversion.value_required422currency was sent without value.Send both, or neither.
conversion.currency_required422value was sent without currency.Add a three-letter currency code, such as AUD.
conversion.currency_invalid422currency isn't a three-letter code.Use an ISO 4217 code, such as AUD, NZD or USD.
conversion.value_too_large422value is too large to store.Check the amount; send it in whole currency units, such as 49.95, not cents.
conversion.in_future422occurredAt is in the future.Leave occurredAt out to use the current time, or check your server's clock.
conversion.before_click422occurredAt is before the click happened.Send the time the conversion happened, or leave it out.
conversion.outside_window422The conversion happened more than 90 days after the click, so it no longer counts towards the link.Nothing to fix; conversions are only counted within 90 days of the click.

Webhooks

CodeStatusMeaningWhat to do
webhook.not_found404No webhook with that ID in this workspace.Check the webhook ID with GET /webhooks.
webhook.delivery_not_found404No delivery with that ID for this webhook.Check the delivery ID with GET /webhooks/{webhookId}/deliveries. Deliveries are kept for 30 days.
webhook.url_required422url is missing.Send the full https:// address to post events to.
webhook.url_invalid422url isn't a full web address, or it includes a user name or password.Send an address such as https://example.com/hooks/blackgum.
webhook.url_https422url starts with http://.Use https://, so events are encrypted on the way.
webhook.url_private422url points at a local or private network address.Use an address on the public internet. To test on your own computer, use a tunnelling tool that gives you a public https address.
webhook.url_not_slack422format is slack, but url isn't a Slack incoming webhook address.Copy the address from your Slack app's Incoming Webhooks page. It starts with https://hooks.slack.com/.
webhook.url_not_teams422format is teams, but url isn't a Microsoft Teams webhook address.Copy the address from the Teams workflow "Post to a channel when a webhook request is received".
webhook.description_too_long422description is longer than 200 characters.Use a shorter description.
webhook.format_invalid422format isn't one of the allowed values.Use Json, Slack or Teams.
webhook.events_required422events is empty.Choose at least one event type.
webhook.event_unknown422events contains a name we don't send.Use the event names listed in the webhooks guide, such as link.created.
webhook.threshold_invalid422A click milestone isn't a whole number from 1 to 1,000,000,000.Send numbers such as 100 and 1000.
webhook.too_many_thresholds422More than 10 click milestones.Keep the ones that matter most.
webhook.thresholds_required422link.click_threshold is chosen but there are no click milestones.Add clickThresholds, such as [100, 1000], or leave out link.click_threshold.
webhook.limit_reached409The workspace already has 10 webhooks.Remove one you no longer use. One webhook can receive several event types.
webhook.disabled409The webhook is turned off, so it can't be sent a test or a repeat.Turn it on with PATCH (enabled: true) first.

Campaigns

CodeStatusMeaningWhat to do
campaign.not_found404No campaign with that ID in this workspace. When you add a link to a campaign, an archived one counts as missing.Check the campaign ID with GET /campaigns.
campaign.name_required422The campaign has no name.Send a name.
campaign.name_too_long422The name is longer than 200 characters.Use a shorter name.
campaign.utm_too_long422A UTM value is longer than 200 characters.Use shorter UTM values.

Custom domains

CodeStatusMeaningWhat to do
domain.not_found404No domain with that ID in this workspace, or it isn't available to it.Check the domain ID with GET /domains.
domain.invalid422The hostname isn't a valid domain or subdomain.Send a hostname such as go.example.com, without https:// or a path.
domain.reserved409The hostname belongs to this service.Use a domain you own.
domain.taken409Another workspace has already added this hostname.If you own it, contact support.
domain.limit_reached429The organisation has as many custom domains as its plan allows.Remove a domain you no longer use, or upgrade.
domain.not_ready409The domain isn't verified and active yet, so links can't use it.Finish the DNS set-up and check the domain until it shows Active.
domain.in_use409Links still use the domain, so it can't be removed.Delete or archive those links first.

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