Getting Started# The Beckon API is a RESTful JSON API that lets you manage every aspect of your account programmatically. All requests are made over HTTPS to https://usebeckon.com/api/v1.
Request and response bodies are JSON-encoded. All timestamps are returned as ISO 8601 strings in UTC.
Quick example Create a short link in a single request:
cURL
curl -X POST https://usebeckon.com/api/v1/links \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/my-very-long-page",
"code": "demo",
"tags": ["marketing"]
}'Response
{
"data" : {
"id" : "lnk_abc123" ,
"code" : "demo" ,
"short_url" : "https://gtg.sh/demo" ,
"url" : "https://example.com/my-very-long-page" ,
"clicks" : 0 ,
"tags" : ["marketing"],
"created_at" : "2026-03-14T12: 00 : 00 Z"
}
} Authentication# All API requests require a valid API key sent in the Authorization header as a Bearer token.
Header
Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxxAPI keys are scoped to your team and carry the same permissions as the team member who created them. Keys always start with the gtg_sk_ prefix.
Rate Limits# Rate limits are applied per API key based on your subscription tier.
Plan Requests / minute Free 30 Pro 300
Every response includes rate-limit headers:
Parameter Type Required Description X-RateLimit-Limit integer No Maximum requests allowed per window. X-RateLimit-Remaining integer No Requests remaining in the current window. X-RateLimit-Reset integer No Unix timestamp (seconds) when the window resets.
When you exceed the limit you will receive a 429 Too Many Requests response. Use the X-RateLimit-Reset header to wait before retrying.
Error Handling# Errors follow a consistent format across all endpoints:
Response
{
"error" : {
"code" : "validation_error" ,
"message" : "The url field is required." ,
"details" : {
"field" : "url"
}
}
}HTTP Status Error Code Description 400 validation_error Invalid or missing request parameters. 401 unauthenticated Missing or invalid API key. 403 forbidden API key lacks permission for this action. 404 not_found The requested resource does not exist. 409 conflict Resource already exists (e.g., duplicate short code). 429 rate_limited Too many requests. Slow down and retry. 500 server_error An unexpected error occurred on our end.
List endpoints use cursor-based pagination. Pass cursor and limit as query parameters.
Parameter Type Required Description cursor string No Opaque cursor from a previous response. Omit for the first page. limit integer No Number of items to return. Default 20, max 100.
Response
{
"data" : [ "..." ],
"meta" : {
"cursor_next" : "eyJpZCI6MTAwfQ" ,
"has_more" : true
}
}When has_more is false, you have reached the last page.
Links# Create, read, update, and delete short links. Each link belongs to a team and can optionally have a custom code, password, expiration, and tags.
Parameter Type Required Description cursor string No Pagination cursor. limit integer No Items per page (default 20, max 100). search string No Filter by URL or code. tag string No Filter by tag name. domain string No Filter by custom domain.
cURL
curl https://usebeckon.com/api/v1/links?limit=5 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : [
{
"id" : "lnk_abc123" ,
"code" : "demo" ,
"short_url" : "https://gtg.sh/demo" ,
"url" : "https://example.com" ,
"clicks" : 142 ,
"tags" : ["marketing"],
"password_protected" : false ,
"expires_at" : null ,
"created_at" : "2026-03-10T08: 30 : 00 Z" ,
"updated_at" : "2026-03-12T14: 22 : 00 Z"
}
],
"meta" : {
"cursor_next" : "eyJpZCI6MTAwfQ" ,
"has_more" : true
}
}Parameter Type Required Description url string Yes The destination URL to shorten. code string No Custom short code (7 chars max). Auto-generated if omitted. domain string No Custom domain (must be verified). Defaults to the default short URL domain. tags string[] No Array of tag names. password string No Require this password before redirecting. expires_at string No ISO 8601 expiration date. max_clicks integer No Disable the link after this many clicks. utm_source string No UTM source parameter to append. utm_medium string No UTM medium parameter to append. utm_campaign string No UTM campaign parameter to append.
cURL
curl -X POST https://usebeckon.com/api/v1/links \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/launch",
"code": "launch",
"tags": ["product", "launch"],
"expires_at": "2026-12-31T23:59:59Z"
}'Response
{
"data" : {
"id" : "lnk_xyz789" ,
"code" : "launch" ,
"short_url" : "https://gtg.sh/launch" ,
"url" : "https://example.com/launch" ,
"clicks" : 0 ,
"tags" : ["product", "launch"],
"password_protected" : false ,
"expires_at" : "2026-12-31T23: 59 : 59 Z" ,
"max_clicks" : null ,
"created_at" : "2026-03-14T12: 00 : 00 Z" ,
"updated_at" : "2026-03-14T12: 00 : 00 Z"
}
}Parameter Type Required Description id string Yes Link ID (lnk_...) or short code.
cURL
curl https://usebeckon.com/api/v1/links/lnk_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Parameter Type Required Description id string Yes Link ID. url string No New destination URL. code string No New short code. tags string[] No Replace tags. password string | null No Set or remove password (null to remove). expires_at string | null No Set or remove expiration. max_clicks integer | null No Set or remove click limit.
cURL
curl -X PATCH https://usebeckon.com/api/v1/links/lnk_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "url": "https://example.com/updated" }'Parameter Type Required Description id string Yes Link ID.
cURL
curl -X DELETE https://usebeckon.com/api/v1/links/lnk_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{ "data" : { "deleted" : true } }Archives a link by setting is_active to false. Archived links stop redirecting but are not deleted and can be restored.
Parameter Type Required Description id string Yes Link ID.
cURL
curl -X POST https://usebeckon.com/api/v1/links/lnk_abc123/archive \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"id" : "lnk_abc123" ,
"code" : "demo" ,
"is_active" : false ,
"archived_at" : "2026-03-14T12: 00 : 00 Z"
}
}Create up to 100 links in a single request. Each item in the array follows the same schema as POST /v1/links .
Parameter Type Required Description links object[] Yes Array of link objects (max 100).
cURL
curl -X POST https://usebeckon.com/api/v1/links/bulk \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"links": [
{ "url": "https://example.com/a" },
{ "url": "https://example.com/b", "code": "custom-b" },
{ "url": "https://example.com/c", "tags": ["batch"] }
]
}'Response
{
"data" : [
{ "id" : "lnk_001" , "code" : "a7xKm2q" , "short_url" : "https://gtg.sh/a7xKm2q" , "url" : "https://example.com/a" },
{ "id" : "lnk_002" , "code" : "custom-b" , "short_url" : "https://gtg.sh/custom-b" , "url" : "https://example.com/b" },
{ "id" : "lnk_003" , "code" : "p3rTn8v" , "short_url" : "https://gtg.sh/p3rTn8v" , "url" : "https://example.com/c" }
],
"meta" : {
"created" : 3 ,
"errors" : 0
}
}Parameter Type Required Description id string Yes Link ID. period string No 1h, 24h, 7d, 30d, 90d, all (default 30d). group_by string No hour, day, country, device, browser, referrer.
cURL
curl "https://usebeckon.com/api/v1/links/lnk_abc123/analytics?period=7d&group_by=day" \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"total_clicks" : 847 ,
"unique_clicks" : 623 ,
"timeseries" : [
{ "date" : "2026-03-08" , "clicks" : 102 , "unique" : 78 },
{ "date" : "2026-03-09" , "clicks" : 134 , "unique" : 99 },
{ "date" : "2026-03-10" , "clicks" : 118 , "unique" : 85 },
{ "date" : "2026-03-11" , "clicks" : 97 , "unique" : 72 },
{ "date" : "2026-03-12" , "clicks" : 145 , "unique" : 110 },
{ "date" : "2026-03-13" , "clicks" : 128 , "unique" : 92 },
{ "date" : "2026-03-14" , "clicks" : 123 , "unique" : 87 }
],
"top_countries" : [
{ "country" : "US" , "clicks" : 312 },
{ "country" : "GB" , "clicks" : 187 },
{ "country" : "DE" , "clicks" : 98 }
],
"top_referrers" : [
{ "referrer" : "twitter.com" , "clicks" : 234 },
{ "referrer" : "linkedin.com" , "clicks" : 156 }
]
}
}Create and manage forms. Each form belongs to a team and contains an array of fields with configurable types, validation, and logic.
Parameter Type Required Description cursor string No Pagination cursor. limit integer No Items per page (default 20, max 100). status string No Filter by status: draft, published, archived.
cURL
curl https://usebeckon.com/api/v1/forms?status=published \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : [
{
"id" : "frm_abc123" ,
"name" : "Contact Form" ,
"status" : "published" ,
"submissions_count" : 42 ,
"fields_count" : 5 ,
"created_at" : "2026-02-01T10: 00 : 00 Z" ,
"updated_at" : "2026-03-10T15: 30 : 00 Z"
}
],
"meta" : {
"cursor_next" : null ,
"has_more" : false
}
}Parameter Type Required Description name string Yes Form name. description string No Description displayed at the top of the form. fields object[] Yes Array of field definitions (see field types below). settings object No Form settings: thank-you message, redirect URL, notifications. status string No draft or published (default draft).
cURL
curl -X POST https://usebeckon.com/api/v1/forms \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Feedback Form",
"status": "published",
"fields": [
{ "type": "short_text", "label": "Name", "required": true },
{ "type": "email", "label": "Email", "required": true },
{ "type": "long_text", "label": "Message", "required": false },
{ "type": "rating", "label": "How would you rate us?", "max": 5 }
],
"settings": {
"thank_you_message": "Thanks for your feedback!",
"notification_email": "team@example.com"
}
}'Response
{
"data" : {
"id" : "frm_xyz789" ,
"name" : "Feedback Form" ,
"status" : "published" ,
"url" : "https://gtg.sh/f/frm_xyz789" ,
"fields_count" : 4 ,
"submissions_count" : 0 ,
"created_at" : "2026-03-14T12: 00 : 00 Z"
}
}Parameter Type Required Description id string Yes Form ID (frm_...).
cURL
curl https://usebeckon.com/api/v1/forms/frm_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Parameter Type Required Description id string Yes Form ID. name string No New form name. fields object[] No Replace all fields. settings object No Merge with existing settings. status string No draft, published, or archived.
cURL
curl -X PATCH https://usebeckon.com/api/v1/forms/frm_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "status": "archived" }'Parameter Type Required Description id string Yes Form ID.
cURL
curl -X DELETE https://usebeckon.com/api/v1/forms/frm_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{ "data" : { "deleted" : true } }Retrieve and manage submissions for a specific form.
Parameter Type Required Description id string Yes Form ID. cursor string No Pagination cursor. limit integer No Items per page (default 20, max 100). status string No Filter: new, read, starred, spam, archived. since string No ISO 8601 date. Only submissions after this date. until string No ISO 8601 date. Only submissions before this date.
cURL
curl "https://usebeckon.com/api/v1/forms/frm_abc123/submissions?status=new&limit=10" \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : [
{
"id" : "sub_001" ,
"form_id" : "frm_abc123" ,
"status" : "new" ,
"data" : {
"name" : "Jane Doe" ,
"email" : "jane@example.com" ,
"message" : "Love the product!"
},
"metadata" : {
"ip_country" : "US" ,
"browser" : "Chrome" ,
"referrer" : "https://google.com"
},
"created_at" : "2026-03-14T09: 15 : 00 Z"
}
],
"meta" : {
"cursor_next" : null ,
"has_more" : false
}
}Parameter Type Required Description id string Yes Form ID. sub_id string Yes Submission ID (sub_...).
cURL
curl https://usebeckon.com/api/v1/forms/frm_abc123/submissions/sub_001 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Parameter Type Required Description id string Yes Form ID. sub_id string Yes Submission ID. status string Yes new, read, starred, spam, or archived.
cURL
curl -X PATCH https://usebeckon.com/api/v1/forms/frm_abc123/submissions/sub_001 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "status": "read" }'Parameter Type Required Description id string Yes Form ID. sub_id string Yes Submission ID.
cURL
curl -X DELETE https://usebeckon.com/api/v1/forms/frm_abc123/submissions/sub_001 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{ "data" : { "deleted" : true } } Pages# Create, read, update, and delete landing pages. Each page belongs to a team and has a slug, template, theme configuration, and an ordered list of content blocks.
Parameter Type Required Description cursor string No Pagination cursor. limit integer No Items per page (default 20, max 100). status string No Filter: draft or published.
cURL
curl https://usebeckon.com/api/v1/pages \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : [
{
"id" : "pg_abc123" ,
"title" : "My Link-in-Bio" ,
"slug" : "my-links" ,
"url" : "https://gtg.sh/p/my-links" ,
"status" : "published" ,
"template" : "link-in-bio" ,
"views" : 1234 ,
"created_at" : "2026-02-15T08: 00 : 00 Z" ,
"updated_at" : "2026-03-10T12: 00 : 00 Z"
}
],
"meta" : {
"cursor_next" : null ,
"has_more" : false
}
}GET /v1/pages/{id}Get a page Try it Parameter Type Required Description id string Yes Page ID (pg_...) or slug.
cURL
curl https://usebeckon.com/api/v1/pages/pg_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"id" : "pg_abc123" ,
"title" : "My Link-in-Bio" ,
"slug" : "my-links" ,
"url" : "https://gtg.sh/p/my-links" ,
"status" : "published" ,
"template" : "link-in-bio" ,
"theme" : {
"preset" : "midnight" ,
"font" : "Inter" ,
"primary_color" : "#3b82f6"
},
"blocks" : [
{ "type" : "hero" , "heading" : "Hey, I'm Alex" , "subheading" : "Creator & developer" },
{ "type" : "links" , "items" : [
{ "label" : "My Blog" , "url" : "https://example.com/blog" },
{ "label" : "YouTube" , "url" : "https://youtube.com/@example" }
]},
{ "type" : "social" , "links" : { "twitter" : "example" , "github" : "example" } }
],
"seo" : {
"meta_title" : "Alex — Links" ,
"meta_description" : "All my links in one place." ,
"og_image" : "https://gtg.sh/og/my-links.png"
},
"views" : 1234 ,
"created_at" : "2026-02-15T08: 00 : 00 Z" ,
"updated_at" : "2026-03-10T12: 00 : 00 Z"
}
}POST /v1/pagesCreate a page Try it Parameter Type Required Description title string Yes Page title. slug string Yes URL slug (unique within your team). description string No Short description of the page. template_id string No Template to base the page on (e.g., link-in-bio, portfolio). theme_config object No Theme configuration: preset, font, primary_color, etc.
cURL
curl -X POST https://usebeckon.com/api/v1/pages \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"title": "My Portfolio",
"slug": "portfolio",
"description": "My personal portfolio page",
"template_id": "portfolio",
"theme_config": {
"preset": "midnight",
"font": "Inter",
"primary_color": "#3b82f6"
}
}'Response
{
"data" : {
"id" : "pg_new123" ,
"title" : "My Portfolio" ,
"slug" : "portfolio" ,
"url" : "https://gtg.sh/p/portfolio" ,
"status" : "draft" ,
"template" : "portfolio" ,
"views" : 0 ,
"created_at" : "2026-03-14T12: 00 : 00 Z" ,
"updated_at" : "2026-03-14T12: 00 : 00 Z"
}
}PATCH /v1/pages/{id}Update a page Try it Parameter Type Required Description id string Yes Page ID. title string No New page title. slug string No New URL slug. description string No Page description. status string No draft or published. seo_title string No SEO meta title override. seo_description string No SEO meta description override. og_image_url string No Open Graph image URL. robots_index boolean No Whether search engines should index this page. theme_config object No Theme configuration to merge with existing.
cURL
curl -X PATCH https://usebeckon.com/api/v1/pages/pg_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Portfolio",
"seo_title": "Alex — Portfolio",
"seo_description": "Check out my latest work.",
"robots_index": true
}'Response
{
"data" : {
"id" : "pg_abc123" ,
"title" : "Updated Portfolio" ,
"slug" : "my-links" ,
"status" : "published" ,
"seo" : {
"meta_title" : "Alex — Portfolio" ,
"meta_description" : "Check out my latest work." ,
"og_image" : null ,
"robots_index" : true
},
"updated_at" : "2026-03-14T14: 00 : 00 Z"
}
}DELETE /v1/pages/{id}Delete a page Try it Parameter Type Required Description id string Yes Page ID.
cURL
curl -X DELETE https://usebeckon.com/api/v1/pages/pg_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{ "data" : { "deleted" : true } }POST /v1/pages/{id}/publishPublish a page Try it Publishes a draft page, making it publicly accessible at its URL.
Parameter Type Required Description id string Yes Page ID.
cURL
curl -X POST https://usebeckon.com/api/v1/pages/pg_abc123/publish \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"id" : "pg_abc123" ,
"status" : "published" ,
"published_at" : "2026-03-14T12: 00 : 00 Z"
}
}POST /v1/pages/{id}/unpublishUnpublish a page Try it Unpublishes a live page, reverting it to draft status. The public URL will return a 404.
Parameter Type Required Description id string Yes Page ID.
cURL
curl -X POST https://usebeckon.com/api/v1/pages/pg_abc123/unpublish \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"id" : "pg_abc123" ,
"status" : "draft" ,
"unpublished_at" : "2026-03-14T12: 00 : 00 Z"
}
} Page Blocks# Manage the content blocks within a page. Blocks are ordered and can be of various types (hero, links, text, image, social, form, etc.).
GET /v1/pages/{id}/blocksList blocks Try it Parameter Type Required Description id string Yes Page ID.
cURL
curl https://usebeckon.com/api/v1/pages/pg_abc123/blocks \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : [
{
"id" : "blk_001" ,
"type" : "hero" ,
"visible" : true ,
"position" : 0 ,
"config" : {
"heading" : "Hey, I'm Alex" ,
"subheading" : "Creator & developer"
}
},
{
"id" : "blk_002" ,
"type" : "links" ,
"visible" : true ,
"position" : 1 ,
"config" : {
"items" : [
{ "label" : "My Blog" , "url" : "https://example.com/blog" },
{ "label" : "YouTube" , "url" : "https://youtube.com/@example" }
]
}
}
]
}POST /v1/pages/{id}/blocksAdd a block Try it Parameter Type Required Description id string Yes Page ID. type string Yes Block type: hero, links, text, image, social, form, etc. config object Yes Block configuration (varies by type). visible boolean No Whether the block is visible (default true).
cURL
curl -X POST https://usebeckon.com/api/v1/pages/pg_abc123/blocks \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"type": "text",
"config": {
"content": "Welcome to my page! Here you will find all my links."
},
"visible": true
}'Response
{
"data" : {
"id" : "blk_003" ,
"type" : "text" ,
"visible" : true ,
"position" : 2 ,
"config" : {
"content" : "Welcome to my page! Here you will find all my links."
}
}
}PATCH /v1/pages/{id}/blocks/{blockId}Update a block Try it Parameter Type Required Description id string Yes Page ID. blockId string Yes Block ID (blk_...). config object No Updated block configuration. visible boolean No Show or hide the block. type string No Change the block type.
cURL
curl -X PATCH https://usebeckon.com/api/v1/pages/pg_abc123/blocks/blk_001 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"config": {
"heading": "Hey, I am Alex!",
"subheading": "Developer & creator"
}
}'DELETE /v1/pages/{id}/blocks/{blockId}Delete a block Try it Parameter Type Required Description id string Yes Page ID. blockId string Yes Block ID.
cURL
curl -X DELETE https://usebeckon.com/api/v1/pages/pg_abc123/blocks/blk_001 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{ "data" : { "deleted" : true } }POST /v1/pages/{id}/blocks/reorderReorder blocks Try it Set the display order of all blocks by passing an ordered array of block IDs.
Parameter Type Required Description id string Yes Page ID. block_ids string[] Yes Ordered array of block IDs.
cURL
curl -X POST https://usebeckon.com/api/v1/pages/pg_abc123/blocks/reorder \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"block_ids": ["blk_002", "blk_003", "blk_001"]
}'Response
{
"data" : {
"reordered" : true ,
"block_ids" : ["blk_002", "blk_003", "blk_001"]
}
} Analytics# Access platform-wide and resource-specific analytics for links, forms, and pages. For per-link analytics, also see GET /v1/links/{id}/analytics above.
Returns aggregate statistics across all your links for the given time period.
Parameter Type Required Description period string No 1h, 24h, 7d, 30d, 90d, all (default 30d).
cURL
curl "https://usebeckon.com/api/v1/analytics/summary?period=30d" \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"total_links" : 156 ,
"total_clicks" : 24893 ,
"unique_clicks" : 18342 ,
"total_forms" : 8 ,
"total_submissions" : 1247 ,
"total_pages" : 3 ,
"total_page_views" : 5621 ,
"top_links" : [
{ "id" : "lnk_abc123" , "code" : "demo" , "clicks" : 847 },
{ "id" : "lnk_def456" , "code" : "launch" , "clicks" : 623 },
{ "id" : "lnk_ghi789" , "code" : "blog" , "clicks" : 412 }
],
"clicks_by_day" : [
{ "date" : "2026-02-13" , "clicks" : 782 },
{ "date" : "2026-02-14" , "clicks" : 834 }
]
}
}Returns aggregate analytics across all links, including timeseries data and breakdowns.
Parameter Type Required Description period string No 1h, 24h, 7d, 30d, 90d, all (default 30d). group_by string No hour, day, country, device, browser, referrer.
cURL
curl "https://usebeckon.com/api/v1/analytics/links?period=7d&group_by=day" \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"total_clicks" : 12483 ,
"unique_clicks" : 8921 ,
"timeseries" : [
{ "date" : "2026-03-08" , "clicks" : 1702 , "unique" : 1280 },
{ "date" : "2026-03-09" , "clicks" : 1834 , "unique" : 1399 },
{ "date" : "2026-03-10" , "clicks" : 1618 , "unique" : 1185 }
]
}
}Returns aggregate analytics across all forms, including submission counts and conversion rates.
Parameter Type Required Description period string No 1h, 24h, 7d, 30d, 90d, all (default 30d).
cURL
curl "https://usebeckon.com/api/v1/analytics/forms?period=30d" \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"total_submissions" : 1247 ,
"total_views" : 8432 ,
"conversion_rate" : 14 .8,
"submissions_by_day" : [
{ "date" : "2026-03-12" , "submissions" : 42 },
{ "date" : "2026-03-13" , "submissions" : 38 },
{ "date" : "2026-03-14" , "submissions" : 51 }
]
}
}GET /v1/analytics/pagesAggregate page analytics Try it Returns aggregate analytics across all landing pages, including view counts and engagement metrics.
Parameter Type Required Description period string No 1h, 24h, 7d, 30d, 90d, all (default 30d).
cURL
curl "https://usebeckon.com/api/v1/analytics/pages?period=30d" \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"total_views" : 5621 ,
"unique_visitors" : 4102 ,
"views_by_day" : [
{ "date" : "2026-03-12" , "views" : 187 },
{ "date" : "2026-03-13" , "views" : 203 },
{ "date" : "2026-03-14" , "views" : 195 }
]
}
}Parameter Type Required Description id string Yes Form ID (frm_...). period string No 1h, 24h, 7d, 30d, 90d, all (default 30d).
cURL
curl "https://usebeckon.com/api/v1/forms/frm_abc123/analytics?period=7d" \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"total_submissions" : 142 ,
"total_views" : 1083 ,
"conversion_rate" : 13 .1,
"submissions_by_day" : [
{ "date" : "2026-03-08" , "submissions" : 18 },
{ "date" : "2026-03-09" , "submissions" : 22 },
{ "date" : "2026-03-10" , "submissions" : 19 }
],
"top_countries" : [
{ "country" : "US" , "submissions" : 64 },
{ "country" : "GB" , "submissions" : 31 }
]
}
}GET /v1/pages/{id}/analyticsPage-specific analytics Try it Parameter Type Required Description id string Yes Page ID (pg_...). period string No 1h, 24h, 7d, 30d, 90d, all (default 30d).
cURL
curl "https://usebeckon.com/api/v1/pages/pg_abc123/analytics?period=7d" \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"total_views" : 1234 ,
"unique_visitors" : 892 ,
"avg_time_on_page" : 45 ,
"views_by_day" : [
{ "date" : "2026-03-08" , "views" : 167 },
{ "date" : "2026-03-09" , "views" : 189 },
{ "date" : "2026-03-10" , "views" : 174 }
],
"top_referrers" : [
{ "referrer" : "instagram.com" , "views" : 342 },
{ "referrer" : "twitter.com" , "views" : 218 }
]
}
} Webhooks# Receive real-time HTTP callbacks when events happen in your account. Configure webhook endpoints, choose which events to subscribe to, and verify signatures for security.
Event types Event Description link.created A new short link was created. link.updated A link was updated. link.deleted A link was deleted. link.clicked A short link was clicked. form.created A new form was created. form.updated A form was updated. form.deleted A form was deleted. form.submission.created A new form submission was received. page.created A new page was created. page.published A page was published. page.unpublished A page was unpublished. page.updated A page was updated. page.deleted A page was deleted.
Signature verification Every webhook delivery includes a Gtg-Signature header containing a timestamp and HMAC-SHA256 signature. Always verify signatures to ensure the payload was sent by Beckon.
Header format
Gtg-Signature: t=1710421200,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bdNode.js verification
import crypto from 'crypto';
function verifyWebhookSignature(payload, header, secret) {
const [tPart, v1Part] = header.split(',');
const timestamp = tPart.split('=')[1];
const signature = v1Part.split('=')[1];
const signedPayload = timestamp + '.' + payload;
const expected = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Retry schedule If your endpoint returns a non-2xx status code, Beckon will retry delivery with exponential backoff:
Attempt Delay 1 Immediate 2 1 minute 3 5 minutes 4 30 minutes 5 2 hours 6 8 hours 7 24 hours
Auto-disable: Webhook endpoints are automatically disabled after 20 consecutive failures . You can re-enable them from the dashboard or via the API.
Parameter Type Required Description cursor string No Pagination cursor. limit integer No Items per page (default 20, max 100).
cURL
curl https://usebeckon.com/api/v1/webhooks \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : [
{
"id" : "wh_abc123" ,
"url" : "https://example.com/webhooks/gtg" ,
"events" : ["link.created", "link.clicked"],
"description" : "Production webhook" ,
"enabled" : true ,
"consecutive_failures" : 0 ,
"created_at" : "2026-03-01T10: 00 : 00 Z" ,
"updated_at" : "2026-03-10T15: 30 : 00 Z"
}
],
"meta" : {
"cursor_next" : null ,
"has_more" : false
}
}Parameter Type Required Description url string Yes The HTTPS URL to receive webhook events. events string[] Yes Array of event types to subscribe to. description string No A friendly label for this endpoint.
cURL
curl -X POST https://usebeckon.com/api/v1/webhooks \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/gtg",
"events": ["link.created", "link.clicked", "form.submission.created"],
"description": "Production webhook"
}'Response
{
"data" : {
"id" : "wh_new456" ,
"url" : "https://example.com/webhooks/gtg" ,
"events" : ["link.created", "link.clicked", "form.submission.created"],
"description" : "Production webhook" ,
"secret" : "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" ,
"enabled" : true ,
"created_at" : "2026-03-14T12: 00 : 00 Z"
}
}Important: The secret is only returned once at creation time. Store it securely for signature verification.
Parameter Type Required Description id string Yes Webhook ID (wh_...).
cURL
curl https://usebeckon.com/api/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Parameter Type Required Description id string Yes Webhook ID. url string No New endpoint URL. events string[] No Replace subscribed events. description string No Updated description. enabled boolean No Enable or disable the webhook.
cURL
curl -X PATCH https://usebeckon.com/api/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"events": ["link.created", "link.clicked", "link.deleted"],
"enabled": true
}'Parameter Type Required Description id string Yes Webhook ID.
cURL
curl -X DELETE https://usebeckon.com/api/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{ "data" : { "deleted" : true } }Sends a test event to the webhook endpoint so you can verify your integration is working correctly.
Parameter Type Required Description id string Yes Webhook ID.
cURL
curl -X POST https://usebeckon.com/api/v1/webhooks/wh_abc123/test \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"delivered" : true ,
"status_code" : 200 ,
"response_time_ms" : 142 ,
"event_type" : "webhook.test"
}
}Parameter Type Required Description id string Yes Webhook ID. cursor string No Pagination cursor. limit integer No Items per page (default 20, max 100).
cURL
curl "https://usebeckon.com/api/v1/webhooks/wh_abc123/deliveries?limit=5" \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : [
{
"id" : "dlv_001" ,
"event_type" : "link.clicked" ,
"status_code" : 200 ,
"success" : true ,
"response_time_ms" : 87 ,
"attempt" : 1 ,
"delivered_at" : "2026-03-14T11: 30 : 00 Z"
},
{
"id" : "dlv_002" ,
"event_type" : "form.submission.created" ,
"status_code" : 500 ,
"success" : false ,
"response_time_ms" : 3021 ,
"attempt" : 1 ,
"next_retry_at" : "2026-03-14T11: 31 : 00 Z" ,
"delivered_at" : "2026-03-14T11: 30 : 00 Z"
}
],
"meta" : {
"cursor_next" : "eyJpZCI6MTAwfQ" ,
"has_more" : true
}
} Account# Retrieve account information, check usage against plan limits, and manage API keys programmatically.
Returns the team and subscription details associated with the current API key.
cURL
curl https://usebeckon.com/api/v1/account \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"team_id" : "team_abc123" ,
"team_name" : "My Team" ,
"plan" : "pro" ,
"member_count" : 3 ,
"created_at" : "2025-08-15T10: 00 : 00 Z"
}
}Returns current resource usage compared to your plan limits.
cURL
curl https://usebeckon.com/api/v1/account/usage \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : {
"plan" : "pro" ,
"billing_period" : {
"start" : "2026-03-01T00: 00 : 00 Z" ,
"end" : "2026-03-31T23: 59 : 59 Z"
},
"links" : { "used" : 156 , "limit" : 1000 },
"clicks" : { "used" : 24893 , "limit" : 100000 },
"forms" : { "used" : 8 , "limit" : 25 },
"pages" : { "used" : 3 , "limit" : 10 },
"team_members" : { "used" : 3 , "limit" : 10 },
"custom_domains" : { "used" : 1 , "limit" : 5 },
"api_keys" : { "used" : 2 , "limit" : 5 }
}
}Lists all API keys for your team. Key values are masked for security and only show the last 4 characters.
cURL
curl https://usebeckon.com/api/v1/account/api-keys \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{
"data" : [
{
"id" : "key_abc123" ,
"name" : "Production" ,
"masked_key" : "gtg_sk_...a1b2" ,
"last_used_at" : "2026-03-14T11: 45 : 00 Z" ,
"created_at" : "2026-01-15T08: 00 : 00 Z"
},
{
"id" : "key_def456" ,
"name" : "Development" ,
"masked_key" : "gtg_sk_...c3d4" ,
"last_used_at" : "2026-03-10T09: 00 : 00 Z" ,
"created_at" : "2026-02-01T12: 00 : 00 Z"
}
]
}Parameter Type Required Description name string Yes A label for the API key (e.g., "Production", "CI/CD").
cURL
curl -X POST https://usebeckon.com/api/v1/account/api-keys \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "name": "CI/CD Pipeline" }'Response
{
"data" : {
"id" : "key_new789" ,
"name" : "CI/CD Pipeline" ,
"key" : "gtg_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" ,
"created_at" : "2026-03-14T12: 00 : 00 Z"
}
}Important: The full API key is only returned once at creation time. Store it securely — you will not be able to retrieve it again.
Permanently revokes an API key. Any requests using this key will immediately begin returning 401 Unauthenticated.
Parameter Type Required Description id string Yes API key ID (key_...).
cURL
curl -X DELETE https://usebeckon.com/api/v1/account/api-keys/key_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{ "data" : { "deleted" : true } } OAuth 2.0# Beckon supports OAuth 2.0 for third-party integrations. Users can authorize your application to access their Beckon account without sharing their API key.
Authorization Flow Beckon uses the Authorization Code + PKCE flow for maximum security.
Redirect the user to the authorization endpoint:Authorization URL
https://usebeckon.com/oauth/authorize?client_id=app_...&redirect_uri=https://yourapp.com/callback&response_type=code&scope=links:read links:write&state=random_state_value&code_challenge=...&code_challenge_method=S256 The user reviews the requested scopes and approves your application. Beckon redirects to your redirect_uri with ?code=...&state=.... Exchange the authorization code for tokens at POST /api/oauth/token. Token Endpoint Exchange an authorization code for an access token and refresh token.
POST /api/oauth/tokenExchange code for tokens Try it cURL
curl -X POST https://usebeckon.com/api/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "...",
"redirect_uri": "https://yourapp.com/callback",
"client_id": "app_...",
"client_secret": "secret_...",
"code_verifier": "..."
}'Response
{
"access_token" : "gtg_at_..." ,
"refresh_token" : "gtg_rt_..." ,
"token_type" : "Bearer" ,
"expires_in" : 3600 ,
"scope" : "links:read links:write"
}Refresh Tokens Access tokens expire after 1 hour. Use the refresh token to obtain a new access token without requiring the user to re-authorize.
cURL
curl -X POST https://usebeckon.com/api/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "gtg_rt_...",
"client_id": "app_...",
"client_secret": "secret_..."
}'Client Credentials For server-to-server integrations where no user interaction is needed, use the client credentials flow. This grants access scoped to your own account.
cURL
curl -X POST https://usebeckon.com/api/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "app_...",
"client_secret": "secret_..."
}'Available Scopes Request only the scopes your application needs. Scopes are space-delimited in the authorization URL.
Scope Description links:read Read links and their metadata links:write Create, update, and delete links links:analytics View click analytics for links forms:read Read form configurations forms:write Create, update, and delete forms forms.submissions:read Read form submissions forms.submissions:write Update and delete form submissions pages:read Read page configurations and blocks pages:write Create, update, and delete pages pages:analytics View page view analytics analytics:read Read aggregate analytics data webhooks:read Read webhook configurations webhooks:write Create, update, and delete webhooks account:read Read account and team information
OAuth App Management API Register and manage your OAuth applications programmatically.
cURL
curl https://usebeckon.com/api/v1/account/oauth-apps \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"cURL
curl -X POST https://usebeckon.com/api/v1/account/oauth-apps \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "My Integration",
"redirect_uris": ["https://yourapp.com/callback"],
"scopes": ["links:read", "links:write"]
}'cURL
curl -X PATCH https://usebeckon.com/api/v1/account/oauth-apps/app_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated App Name",
"redirect_uris": ["https://yourapp.com/callback", "https://yourapp.com/callback2"]
}'cURL
curl -X DELETE https://usebeckon.com/api/v1/account/oauth-apps/app_abc123 \
-H "Authorization: Bearer gtg_sk_xxxxxxxxxxxxxxxxxxxx"Response
{ "data" : { "deleted" : true } }Token Revocation Revoke an access token or refresh token when it is no longer needed.
POST /api/oauth/revokeRevoke a token Try it cURL
curl -X POST https://usebeckon.com/api/oauth/revoke \
-H "Content-Type: application/json" \
-d '{
"token": "gtg_at_..."
}'Response
{ "data" : { "revoked" : true } } SDKs# JavaScript / TypeScript Install
npm install @beckon/sdkTypeScript
import { BeckonClient } from '@beckon/sdk';
const beckon = new BeckonClient({ apiKey: process.env.BECKON_API_KEY });
// Create a short link
const link = await beckon.links.create({
url: 'https://example.com/long-url',
slug: 'summer-sale',
});
console.log(link.short_url);
// List form submissions
const submissions = await beckon.forms.submissions.list('form-id', {
status: 'unread',
limit: 50,
});
// Verify webhook signature
import { constructEvent } from '@beckon/sdk';
const event = constructEvent(
rawBody,
request.headers.get('Gtg-Signature')!,
process.env.BECKON_WEBHOOK_SECRET!
);OpenAPI Specification The full OpenAPI 3.1 specification is available at /api/openapi.json. Use it with Swagger UI, Postman, or any OpenAPI-compatible tool to explore the API interactively or generate client libraries in any language.
Fetch the spec
curl https://usebeckon.com/api/openapi.jsonReady to build? Create your free account, generate an API key, and start shipping in minutes. No credit card required.