Developer API

Build against the available scoped API.

Choose a service in the reference navigation to focus its endpoints, scopes, and examples. Each Bearer key remains limited by its explicit scope and the permissions of the account that created it.

Getting started

Authentication

Send the one-time API key as a Bearer token. The key is automatically limited to the account that created it, so requests never include an account or tenant ID.

Authorization: Bearer hbe_your_key
Content-Type: application/json
Available services only

The reference lists the current public catalog. A hidden service route returns not_found to customer keys even when an older key still carries its scope.

Email confirmation required

The account must confirm its email before any API or sandbox request can run; otherwise every endpoint returns email_verification_required.

Save keys once

Handlebe cannot reveal a plaintext key again. Rotate it before revoking an old credential.

Authorization

Scopes

A matching scope permits the route family, while the key creator’s current account permission remains authoritative.

links.read
Read links, targeting rules, and the safe sandbox response.
links.write
Create and publish links, reserve and change drafts, add targets, change lifecycle state, and soft-delete links.
analytics.read
Read account and link analytics and export aggregate CSV data.
webhooks.read
Read link webhook summaries and delivery history without signing material.
webhooks.write
Register and disable link webhook endpoints and retry failed deliveries.
subdomains.read
List branded subdomains and selectable Enterprise root domains. Developer keys cannot change them.
all
Use every developer capability above without opening browser-only, account, billing, or platform routes.
Endpoint group

Analytics

Read privacy-safe aggregate delivery data without exposing raw IP addresses or precise locations.

GET/analytics/summary

Account summary

Return current and previous redirect totals, daily buckets, recent links, and coarse location groups; country code ZZ keeps redirects whose location is unavailable visible.

Required scope analytics.read

Request fields

daysqueryinteger 1–366optional

Server-bounded reporting window; defaults to 30.

Example request

Success response

{
  "current": {
    "active_links": 1,
    "unique_visitors": 1,
    "visits": 1
  },
  "delivery_activity": [],
  "geographies": [
    {
      "country_code": "ZZ",
      "region_code": null,
      "visits": 1
    }
  ],
  "previous": {
    "active_links": 0,
    "unique_visitors": 0,
    "visits": 0
  },
  "recent_links": []
}

Possible errors

  • 401authentication_required
  • 403forbidden
Try it against this environment

Requests use this page origin under /api and may affect live data available to your key.

GET/analytics/export.csv

Export analytics CSV

Download privacy-safe redirect rows as CSV without raw IP or precise location.

Required scope analytics.read

Request fields

daysqueryinteger 1–366optional

Server-bounded reporting window; defaults to 30.

Example request

Success response

occurred_at,short_link_id,browser,os,country_code,region_code
2026-07-18T12:00:00Z,00000000-0000-0000-0000-000000000000,Chrome,Linux,US,IL

Possible errors

  • 401authentication_required
  • 403forbidden
Try it against this environment

Requests use this page origin under /api and may affect live data available to your key.

Endpoint group

Webhooks

Register paid public HTTPS endpoints and inspect their asynchronous visit deliveries.

Outbound request

Payload sent to your endpoint

After each recorded visit, the worker POSTs this JSON request to the registered endpoint_url. The link_id and webhook_id path values below identify management records; they are not the outbound request body.

Headers sent to your endpoint

Content-Typeheaderapplication/jsonsent

The body is JSON encoded.

X-{product-slug}-Eventheadervisit.createdsent

The event name; product-slug is the safe lowercase slug derived from the configured product name.

X-{product-slug}-Event-Idheadersame UUID as event_idsent

Use this stable identifier to ignore duplicate retry deliveries.

X-{product-slug}-Signatureheadersha256=<lowercase hexadecimal HMAC>sent

HMAC-SHA256 of the exact raw request body using the one-time signing secret.

JSON body fields

eventbodystringsent

Always visit.created for the currently supported delivery.

event_idbodyUUIDsent

The idempotency identifier retained across every retry.

short_link_idbodyUUIDsent

The visited link that owns the registered endpoint.

{
  "event": "visit.created",
  "event_id": "00000000-0000-0000-0000-000000000002",
  "short_link_id": "00000000-0000-0000-0000-000000000003"
}
GET/links/{link_id}/webhooks

List link webhooks

Return safe endpoint summaries without encrypted or plaintext signing material; an unknown or unowned link returns an empty list.

Required scope webhooks.read

Request fields

link_idpathUUIDrequired

The owning link identifier.

Example request

Success response

[
  {
    "endpoint_url": "https://hooks.example.test/visits",
    "id": "00000000-0000-0000-0000-000000000000",
    "status": "active"
  }
]

Possible errors

  • 401authentication_required
  • 403forbidden
Try it against this environment

Requests use this page origin under /api and may affect live data available to your key.

POST/links/{link_id}/webhooks

Register a webhook

Register a plan-gated public HTTPS endpoint and reveal its signing secret in this response only.

Required scope webhooks.write

Request fields

link_idpathUUIDrequired

The owned link that emits visit events.

endpoint_urlbodypublic HTTPS URLrequired

A DNS-resolved endpoint that must not reach a private or internal network.

Example request

Success response

{
  "signing_secret": "save-this-one-time-secret",
  "webhook": {
    "endpoint_url": "https://example.com/handlebe-events",
    "id": "00000000-0000-0000-0000-000000000000",
    "status": "active"
  }
}

Possible errors

  • 401authentication_required
  • 403forbidden
  • 404not_found
  • 422plan_required
  • 422unsafe_destination
  • 422validation_failed
Try it against this environment

Requests use this page origin under /api and may affect live data available to your key.

GET/links/{link_id}/webhooks/{webhook_id}/deliveries

List webhook deliveries

Return up to 100 recent queued, successful, retrying, and dead-letter outcomes; unknown or unowned identifiers return an empty list.

Required scope webhooks.read

Request fields

link_idpathUUIDrequired

The owning link identifier.

webhook_idpathUUIDrequired

The owned webhook identifier.

Example request

Success response

[
  {
    "attempts": 1,
    "event_id": "00000000-0000-0000-0000-000000000002",
    "id": "00000000-0000-0000-0000-000000000001",
    "payload": {
      "event": "visit.created",
      "event_id": "00000000-0000-0000-0000-000000000002",
      "short_link_id": "00000000-0000-0000-0000-000000000003"
    },
    "response_status": 200,
    "status": "delivered"
  }
]

Possible errors

  • 401authentication_required
  • 403forbidden
Try it against this environment

Requests use this page origin under /api and may affect live data available to your key.

POST/links/{link_id}/webhooks/{webhook_id}/deliveries/{delivery_id}/retry

Retry a webhook delivery

Queue one owned retrying or dead-letter delivery immediately without changing its event ID.

Required scope webhooks.write

Request fields

link_idpathUUIDrequired

The owning link identifier.

webhook_idpathUUIDrequired

The owned webhook identifier.

delivery_idpathUUIDrequired

A failed delivery identifier.

Example request

Success response

{
  "message": "Webhook delivery queued for retry"
}

Possible errors

  • 401authentication_required
  • 403forbidden
  • 404not_found
Try it against this environment

Requests use this page origin under /api and may affect live data available to your key.

POST/links/{link_id}/webhooks/{webhook_id}/disable

Disable a webhook

Stop future sends and move pending deliveries to dead letter while keeping history readable.

Required scope webhooks.write

Request fields

link_idpathUUIDrequired

The owning link identifier.

webhook_idpathUUIDrequired

The active webhook identifier.

Example request

Success response

{
  "message": "Webhook disabled"
}

Possible errors

  • 401authentication_required
  • 403forbidden
  • 404not_found
Try it against this environment

Requests use this page origin under /api and may affect live data available to your key.

Endpoint group

Domains

Developer credentials receive read-only access to branded prefixes and Enterprise root-domain choices used during link creation.

GET/subdomains

List subdomains

List active and term-ending branded subdomains owned by the account, including which active address is the automatic default.

Required scope subdomains.read

Example request

Success response

[
  {
    "id": "00000000-0000-0000-0000-000000000000",
    "is_default": true,
    "label": "acme",
    "status": "active"
  }
]

Possible errors

  • 401authentication_required
  • 403forbidden
Try it against this environment

Requests use this page origin under /api and may affect live data available to your key.

GET/short-domains/selectable

List selectable short domains

List active root domains allowed for Enterprise manual selection. A zero-percent domain remains selectable but receives no automatic traffic; inactive and plan-disallowed domains are omitted.

Required scope subdomains.read

Example request

Success response

[
  {
    "effective_percent": 30,
    "hostname": "handlebe.com",
    "id": "00000000-0000-0000-0000-000000000000"
  }
]

Possible errors

  • 401authentication_required
  • 403forbidden
Try it against this environment

Requests use this page origin under /api and may affect live data available to your key.

Endpoint group

Sandbox

Inspect a representative link without creating data, consuming credit, or exposing account records.

Error contract

Stable errors

Every JSON failure uses one envelope. Branch on error.code; the human message may become clearer over time.

{
  "success": false,
  "error": { "code": "payment_method_required", "message": "Add a verified card before publishing." }
}

Available codes include authentication_required, forbidden, validation_failed, not_found, conflict, email_verification_required, payment_method_required, billing_blocked, safety_pending, unsafe_destination, plan_required.