Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
contact:
name: Linkbreakers Support
url: https://app.linkbreakers.com
description: 'This is a documentation of all the APIs of Linkbreakers
## Entry points
`GET https://api.linkbreakers.com/` and `GET https://api.linkbreakers.com/v1` answer without credentials with the API''s name, version and links. This document is served at `https://api.linkbreakers.com/openapi.json`.
## Rate limits
Every response describes where the caller stands in the IETF `RateLimit-Policy` and `RateLimit` header fields (draft-ietf-httpapi-ratelimit-headers), and in `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` and `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` (a Unix timestamp) for clients that read those. A request past the limit gets `429 Too Many Requests` with `Retry-After` in seconds.
- Workspace API token: 720 requests per 60 seconds, per token.
- Dashboard session or OAuth token: 600 requests per 60 seconds, per token.
- No credentials: 300 requests per 60 seconds, per client IP.
Each plan also includes a number of API calls per billing cycle. Past it, calls answer `429` with the code `MAX_PUBLIC_API_QUERIED_REACHED` until the cycle renews or the plan changes.
## Pagination
Every list pages with opaque cursors (AIP-158). Pass `pageSize`, then send the `nextPageToken` of each response back as `pageToken` (or its alias `cursor`) to get the next page. An empty or absent `nextPageToken` means the list is complete. Each list operation describes this in `x-pagination`.
## Batches and background jobs
`POST /v1/links/bulk` creates up to 250 links in one transactional request; `POST /v1/links/batch` takes the same links as a bare JSON array. `POST /v1/links/bulk/jobs` accepts the same batch and answers `202 Accepted` at once with a job and a `Location` header; poll `GET /v1/jobs/{id}` until `status` is `JOB_STATUS_SUCCEEDED` (the created link ids are in `linksBulkCreate.linkIds`) or `JOB_STATUS_FAILED` (`error` says why, and nothing was created). Jobs can be read for 24 hours after they finish.
## Versioning and deprecation
The version is in the path: every operation lives under `/v1`. Within a version, changes are additive only: new operations, new optional request fields, new response fields and new enum values. Clients should ignore fields and enum values they do not know. Anything that would break an existing client ships under a new path version instead.
An operation is retired in two steps. First it is deprecated: it keeps working, is flagged `deprecated: true` in this document, and every response carries a `Deprecation` header field (RFC 9745) with the time it was deprecated and a `Link` with `rel="deprecation"` to the policy. Then, at least 180 days later, it may be removed; that date is announced in advance in a `Sunset` header field (RFC 8594) and as `x-sunset` on the operation. The full policy: https://linkbreakers.com/help/article/api-versioning-and-deprecation-policy
## Idempotent retries
Every POST, PUT and PATCH accepts an optional `Idempotency-Key` header (draft-ietf-httpapi-idempotency-key-header). Send a new unique value, such as a UUID, with each logical request and reuse it only to retry that request. A retry with the same key and the same request returns the first response, marked `Idempotent-Replayed: true`, instead of running again. Keys are scoped to the token and kept for 24 hours. The same key with a different request is refused with `422`, and a retry while the first request is still running gets `409` with `Retry-After`. Server errors (5xx) and refusals such as 401, 403 and 429 are not stored, so retrying them runs the request again.'
title: Linkbreakers Pricing API
version: 1.185.0
x-api-versioning:
compatibility: additive changes only within a version
currentVersion: v1
deprecationHeaders:
- Deprecation
- Sunset
- Link
minimumNoticeDays: 180
policy: https://linkbreakers.com/help/article/api-versioning-and-deprecation-policy
strategy: url-path
servers:
- url: https://api.linkbreakers.com
security:
- bearerAuth: []
tags:
- description: 'Public pricing catalog: the plans, what each costs and what each allows. Prices come from the billing provider and limits from the code that enforces them.'
name: Pricing
paths:
/v1/pricing/plans:
get:
description: Retrieve every plan with its prices, limits and features. Public, no authentication required.
operationId: PricingService_ListPricingPlans
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ListPricingPlansResponse'
description: Everything worked as expected.
headers:
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
'429':
$ref: '#/components/responses/TooManyRequests'
default:
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
description: Unexpected error
headers:
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
security: []
summary: List pricing plans
tags:
- Pricing
components:
schemas:
CreditTopup:
properties:
amounts:
items:
$ref: '#/components/schemas/Money'
type: object
title: Price of one unit, one entry per currency
type: array
creditsPerUnit:
format: int32
title: Credits bought per unit
type: integer
title: CreditTopup is the price of buying platform credits outside a plan
type: object
PricingPlan:
description: 'One plan: what it costs and what it allows.'
properties:
contactUrl:
description: 'Where to ask for this plan''s price. Set only for a plan priced on request, such as Enterprise,
which is billed on the platform credits it uses at a rate agreed with sales.'
type: string
features:
items:
$ref: '#/components/schemas/PlanFeature'
title: Capabilities the plan includes
type: array
id:
description: "- PRICING_PLAN_ID_UNSPECIFIED: Not set\n - PRICING_PLAN_ID_FREE: Free plan, no payment\n - PRICING_PLAN_ID_LIGHT: Light plan\n - PRICING_PLAN_ID_PRO: Pro plan. Trials and sponsored workspaces are allowed what Pro allows unless a limit says otherwise.\n - PRICING_PLAN_ID_ENTERPRISE: Enterprise plan, billed on usage and priced on request through sales"
enum:
- PRICING_PLAN_ID_UNSPECIFIED
- PRICING_PLAN_ID_FREE
- PRICING_PLAN_ID_LIGHT
- PRICING_PLAN_ID_PRO
- PRICING_PLAN_ID_ENTERPRISE
title: Plan identifier
limits:
items:
$ref: '#/components/schemas/PlanLimit'
type: object
title: Every limit the plan enforces
type: array
name:
title: Display name
type: string
prices:
description: 'Recurring prices. Empty for the free plan and for Enterprise, which is priced on request.
Also empty for a paid plan whose prices could not be read: treat that as unknown, not free.'
items:
$ref: '#/components/schemas/PlanPrice'
type: object
type: array
trial:
$ref: '#/components/schemas/PlanTrial'
description: Self-serve free trial of this plan. Absent when the plan has none.
title: PricingPlan
type: object
PlanFeature:
default: PLAN_FEATURE_UNSPECIFIED
description: "- PLAN_FEATURE_UNSPECIFIED: Not set\n - PLAN_FEATURE_BRAND_FREE_PAGES: Visitor pages carry no Linkbreakers branding"
enum:
- PLAN_FEATURE_UNSPECIFIED
- PLAN_FEATURE_BRAND_FREE_PAGES
title: PlanFeature names a capability that depends on the plan
type: string
Money:
properties:
amountMinor:
format: int32
title: Amount in the currency's minor unit, e.g. 790 for 7.90 USD
type: integer
currency:
title: ISO 4217 currency code, upper case, e.g. "USD"
type: string
title: Money is an amount in one currency
type: object
ListPricingPlansResponse:
properties:
creditTopup:
$ref: '#/components/schemas/CreditTopup'
description: Price of buying more credits. Absent when prices could not be read.
linkCreatedCreditCost:
format: int32
title: Platform credits spent by creating one link
type: integer
plans:
items:
$ref: '#/components/schemas/PricingPlan'
type: object
title: Plans, cheapest first
type: array
pricesUpdatedAt:
description: When the prices were read from the billing provider. Absent when they never could be.
format: date-time
type: string
title: The pricing catalog
type: object
PlanPrice:
properties:
amounts:
items:
$ref: '#/components/schemas/Money'
type: object
title: The charge for the whole interval, one entry per currency the price is offered in
type: array
interval:
$ref: '#/components/schemas/BillingInterval'
title: How often the price is charged
monthlyEquivalents:
description: The charge spread over one month, one entry per currency. Equals amounts for a monthly price.
items:
$ref: '#/components/schemas/Money'
type: object
type: array
title: PlanPrice is what a plan costs for one billing interval
type: object
ErrorResponse:
properties:
code:
description: HTTP status code
format: int32
type: integer
codeType:
default: UNKNOWN
description: Custom error code type
type: string
details:
description: Additional error details
items:
type: object
type: array
message:
description: Error message
type: string
required:
- code
- codeType
- message
- details
type: object
BillingInterval:
default: BILLING_INTERVAL_UNSPECIFIED
description: "- BILLING_INTERVAL_UNSPECIFIED: Not set\n - BILLING_INTERVAL_MONTH: Charged every month\n - BILLING_INTERVAL_YEAR: Charged every year\n - BILLING_INTERVAL_ONE_TIME: Charged once"
enum:
- BILLING_INTERVAL_UNSPECIFIED
- BILLING_INTERVAL_MONTH
- BILLING_INTERVAL_YEAR
- BILLING_INTERVAL_ONE_TIME
title: BillingInterval is how often a price is charged
type: string
PlanTrial:
properties:
days:
format: int32
title: Length of the trial in days
type: integer
limits:
description: What a workspace on the trial is allowed. Mostly the plan's limits, with the exceptions enforcement makes.
items:
$ref: '#/components/schemas/PlanLimit'
type: object
type: array
signupOffer:
title: Value of the offer query parameter on the signup link that starts the trial
type: string
signupUrl:
title: Signup link that starts the trial
type: string
title: PlanTrial is a free, self-serve trial of a plan
type: object
PlanLimit:
properties:
key:
description: "- PLAN_LIMIT_KEY_UNSPECIFIED: Not set\n - PLAN_LIMIT_KEY_CUSTOM_DOMAINS: Custom domains connected to the workspace\n - PLAN_LIMIT_KEY_TEAM_MEMBERS: Members of the workspace\n - PLAN_LIMIT_KEY_PLATFORM_CREDITS: Platform credits, spent by creating links and by AI features\n - PLAN_LIMIT_KEY_TRACKED_VISITS: Tracked visits (scans and clicks)\n - PLAN_LIMIT_KEY_PUBLIC_API_CALLS: Public API calls\n - PLAN_LIMIT_KEY_WEBHOOKS: Webhooks configured in the workspace\n - PLAN_LIMIT_KEY_ASSISTANT_MESSAGES_PER_MINUTE: Assistant messages per minute\n - PLAN_LIMIT_KEY_LINKS_INCLUDED: Links the monthly platform credits pay for. Links are not capped on their own: each one spends credits.\n - PLAN_LIMIT_KEY_MEDIA_STORAGE_MB: Megabytes of uploaded media (media for Open media steps, QR code logos, page theme images) the workspace may hold at once. A standing total: deleting media frees it."
enum:
- PLAN_LIMIT_KEY_UNSPECIFIED
- PLAN_LIMIT_KEY_CUSTOM_DOMAINS
- PLAN_LIMIT_KEY_TEAM_MEMBERS
- PLAN_LIMIT_KEY_PLATFORM_CREDITS
- PLAN_LIMIT_KEY_TRACKED_VISITS
- PLAN_LIMIT_KEY_PUBLIC_API_CALLS
- PLAN_LIMIT_KEY_WEBHOOKS
- PLAN_LIMIT_KEY_ASSISTANT_MESSAGES_PER_MINUTE
- PLAN_LIMIT_KEY_LINKS_INCLUDED
- PLAN_LIMIT_KEY_MEDIA_STORAGE_MB
title: What the limit is on
kind:
description: "- PLAN_LIMIT_KIND_UNSPECIFIED: Not set\n - PLAN_LIMIT_KIND_TOTAL: A standing total that does not refill, such as connected domains\n - PLAN_LIMIT_KIND_MONTHLY: An allowance that refills every month\n - PLAN_LIMIT_KIND_PER_MINUTE: A rate that refills every minute\n - PLAN_LIMIT_KIND_UNLIMITED: No ceiling\n - PLAN_LIMIT_KIND_METERED: No ceiling; every unit is billed"
enum:
- PLAN_LIMIT_KIND_UNSPECIFIED
- PLAN_LIMIT_KIND_TOTAL
- PLAN_LIMIT_KIND_MONTHLY
- PLAN_LIMIT_KIND_PER_MINUTE
- PLAN_LIMIT_KIND_UNLIMITED
- PLAN_LIMIT_KIND_METERED
title: How the limit behaves
value:
description: The ceiling. Absent when kind is PLAN_LIMIT_KIND_UNLIMITED or PLAN_LIMIT_KIND_METERED.
format: int32
type: integer
title: PlanLimit is one number a plan puts on something
type: object
headers:
RateLimit-Remaining:
description: Requests left in the current window.
schema:
example: 598
type: integer
RateLimit:
description: 'What is left of the quota: `"<name>";r=<remaining requests>;t=<seconds until the window resets>` (draft-ietf-httpapi-ratelimit-headers).'
schema:
example: '"token";r=598;t=42'
type: string
Retry-After:
description: Seconds to wait before retrying a refused request.
schema:
example: 42
type: integer
X-RateLimit-Reset:
description: Unix time, in seconds, at which the current window resets.
schema:
example: 1791650400
type: integer
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
example: 600
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
example: 42
type: integer
RateLimit-Policy:
description: 'The quota that applies to this caller, as a structured field: `"<name>";q=<requests>;w=<window seconds>` (draft-ietf-httpapi-ratelimit-headers).'
schema:
example: '"token";q=600;w=60'
type: string
X-RateLimit-Limit:
description: Same as RateLimit-Limit, for clients that read the X- convention.
schema:
example: 600
type: integer
X-RateLimit-Remaining:
description: Same as RateLimit-Remaining, for clients that read the X- convention.
schema:
example: 598
type: integer
responses:
TooManyRequests:
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
description: Too many requests. Wait the number of seconds in Retry-After, or until the RateLimit window resets, then retry.
headers:
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit-Limit'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimit-Reset'
Retry-After:
$ref: '#/components/headers/Retry-After'
X-RateLimit-Limit:
$ref: '#/components/headers/X-RateLimit-Limit'
X-RateLimit-Remaining:
$ref: '#/components/headers/X-RateLimit-Remaining'
X-RateLimit-Reset:
$ref: '#/components/headers/X-RateLimit-Reset'
securitySchemes:
bearerAuth:
bearerFormat: JWT
description: JWT Bearer token authentication. Use a workspace API token obtained from the Linkbreakers dashboard. When using the SDK, pass this token to the `accessToken` field in the Configuration constructor (not `apiKey`). A token has full access or a list of scopes; each operation lists the one scope it requires, and a write scope also grants the read scope of the same resource. GET /v1/api-scopes lists every scope.
scheme: bearer
type: http
oauth2:
description: OAuth 2.0 authorization code flow with PKCE and dynamic client registration. Request only the scopes you need. The scope names are the same ones workspace API tokens hold.
flows:
authorizationCode:
authorizationUrl: https://mcp.linkbreakers.com/oauth/authorize
refreshUrl: https://mcp.linkbreakers.com/oauth/token
scopes:
analytics:read: Read events, metrics, time series, analytics data and dashboards.
analytics:write: Create, update and delete analytics dashboards and generate widget summaries.
assistant:read: Read the Assistant conversation.
assistant:write: Send files to the Assistant, clear the conversation and contact support.
billing:write: Open checkout, credit top-up and billing portal sessions.
domains:read: Read custom domains and their DNS instructions.
domains:write: Add, verify, update and delete custom domains.
integrations:read: Read the Slack and Google Forms integrations.
integrations:write: Connect, configure, test, sync and disconnect the Slack and Google Forms integrations.
links:read: Read links, their QR code images, tags, folders and link settings.
links:write: Create, update and delete links, tags, folders and link settings.
mcp:tools: Full access, including scopes added later.
media:read: Read uploaded media.
media:write: Upload and delete media.
members:read: Read workspace members.
members:write: Update, revoke, sign out and remove members. Inviting a member or changing a sign-in email or password needs full access.
page_themes:read: Read page themes and page theme templates.
page_themes:write: Change page themes and create, publish and delete page theme templates.
qrcodes:read: Read QR code designs and QR code templates.
qrcodes:write: Change QR code designs and create, publish and delete QR code templates.
tokens:read: Read API tokens and their scopes, never their secrets.
tokens:write: Create, update and delete API tokens, limited to the scopes the calling token holds.
visitors:read: Read and search visitors and their attributes.
visitors:write: Identify, update and delete visitors and their attributes.
webhooks:read: Read webhooks.
webhooks:write: Create, update and delete webhooks.
workflows:read: Read the workflow steps behind a link and validate them.
workflows:write: Create, connect, update, lay out and delete workflow steps.
workspace:read: Read the workspace and its settings.
workspace:write: Update the workspace, request enrollment and delete the workspace.
tokenUrl: https://mcp.linkbreakers.com/oauth/token
type: oauth2