Reference

The
API.

A typed tRPC layer over HTTP. Every dashboard feature is exposed at /trpc/<router>.<procedure>. 56 endpoints across 7 routers, all reachable with the same authentication header.

Chapter one

Authentication

Every request needs an API key. Generate one from the personal dashboard, then send it on every request.

1# Header on every request 2x-api-key: your_api_key_here 3 4# Or as an Authorization bearer token 5Authorization: Bearer your_api_key_here

Cookie-based session auth also works for browser flows. API keys are the right choice for scripts, automations, and MCP tool access.

Chapter two

Calling convention

tRPC over HTTP wraps every request body in { json: ... } and unwraps responses through .result.data.json. The wrapper looks unusual at first but it's mechanical.

Base URL

1https://a.i6t.co.za

Endpoint format

1# Mutations and queries both POST to the same shape 2POST https://a.i6t.co.za/trpc/<router>.<procedure> 3Content-Type: application/json 4x-api-key: your_api_key_here 5 6# Body 7{ "json": { ...input } } 8 9# Response 10{ "result": { "data": { "json": { ...output } } } }

Chapter three

Worked example

Creating a short link with cURL, JavaScript, Python, PHP, and C#. The same shape works for every other endpoint — just swap the URL and the body fields.

1curl -X POST "https://a.i6t.co.za/trpc/links.create" \ 2 -H "Content-Type: application/json" \ 3 -H "x-api-key: your_api_key_here" \ 4 -d '{ 5 "json": { 6 "destinationUrl": "https://example.com/very-long-url", 7 "title": "My Link", 8 "customCode": "mylink" 9 } 10 }'

Chapter four

Endpoint reference

Every procedure on every router. Mutations are POST-only writes. Queries are POST-but-idempotent reads.

links · 16 endpoints

Links

The core of the platform. Create new short links with custom slugs, expirations, and password protection. Read, update, archive, and delete existing links. Pull analytics and time-series data per link or per account.

mutationlinks.create
Create one short link with optional custom code, title, password, expiration, and workspace assignment.
querylinks.list
List links with filtering, sorting, and pagination. Filter by workspace, archive state, or scope.
querylinks.get
Fetch one link by UUID with click count.
querylinks.getByShortCode
Fetch one link by its human-facing short code.
mutationlinks.update
Update destination URL, title, description, archive flag, workspace, or expiration.
mutationlinks.delete
Delete one link by UUID. Cascade-deletes all click rows.
mutationlinks.bulkDelete
Delete up to 100 links at once. Silently skips links you don't have permission to delete.
mutationlinks.bulkCreate
Create up to 100 links in one request. Per-item errors are returned without aborting the batch.
querylinks.getAnalytics
Click totals, recent activity, and breakdowns by device, referrer, and country for one link.
querylinks.getTimeSeriesAnalytics
Per-day click counts over a 24h / 7d / 30d / 90d period with growth metrics.
querylinks.getOverallStats
Aggregate stats for the authenticated user's personal links: total links, total clicks, top performers.
querylinks.getUsageStats
Monthly usage against link creation limits, scoped to personal or a specific workspace.
querylinks.getUsageAnalytics
Rich monthly + daily breakdown of links created vs links engaged. Powers the /dashboard/usage page.
querylinks.exportCsv
Export every accessible link as an RFC-4180-compliant CSV string with click counts.
querylinks.generateQRCode
Generate a PNG data URL QR code for one link.
querylinks.verifyPassword
Validate a password for a password-protected link without performing the redirect.

collections · 8 endpoints

Collections

Group related links into a shared theme — a campaign, a launch, a newsletter issue. A link can belong to multiple collections. Each collection exposes aggregate stats so you can see how a whole bundle is performing.

querycollections.list
List collections in personal or workspace scope, with live link counts.
querycollections.get
Fetch one collection with aggregate stats and the full sorted member list.
mutationcollections.create
Create a new collection. Slug is auto-generated and de-duplicated within scope.
mutationcollections.update
Update name, description, color, or archived flag.
mutationcollections.delete
Delete a collection. The links inside are NOT deleted — only their membership.
mutationcollections.addLink
Add a link to a collection. Idempotent — duplicate adds are no-ops.
mutationcollections.removeLink
Remove a link from a collection (does not delete the link).
querycollections.getLinkMemberships
Get the array of collection IDs a link belongs to (for edit UIs).

insights · 1 endpoint

Insights

Surface what's interesting, not just what's there. The insights endpoint returns top performers, unexpected spikes, fresh hits, cold links, and weekly rhythm — all derived from existing clicks. No new schema, no caching.

queryinsights.get
Get five buckets of derived observations: top performer, spikes, fresh hits, cold links, weekly rhythm.

bio · 8 endpoints

Bio hub

A linktr.ee-style public profile page per user. Manage your slug, display name, tagline, and an ordered list of entries. Entries can point to your own short links or external URLs. The getBySlug endpoint is the only public procedure on the entire API.

querybio.getBySlug
Public — fetch a published bio page by its slug. Returns 404 if unpublished or missing.
querybio.getMine
Get the authenticated user's own bio page including all entries (enabled and disabled).
querybio.suggestSlug
Get a unique slug suggestion based on the user's name or email.
mutationbio.upsert
Create or update the user's bio page. Slug must be globally unique and match /^[a-z0-9-]+$/.
mutationbio.addEntry
Append a new entry. Provide exactly one of shortCode or externalUrl.
mutationbio.updateEntry
Update an entry's title, enabled flag, or icon. The link target itself can't be changed.
mutationbio.removeEntry
Permanently delete an entry by UUID.
mutationbio.reorderEntries
Reorder entries by passing all IDs in the desired order.

webhooks · 7 endpoints

Webhooks

Register URLs to receive HMAC-signed POST requests when link events happen. Subscribe to link.created, link.updated, link.deleted, or link.clicked. Inspect delivery history per webhook to debug receivers.

querywebhooks.list
List configured webhooks for the user or a specific workspace, with last status and failure count.
querywebhooks.get
Fetch one webhook with its 20 most recent delivery attempts.
mutationwebhooks.create
Register a new webhook. Returns the signing secret — only shown once, store it carefully.
mutationwebhooks.update
Update name, URL, subscribed events, or enabled flag. Doesn't change the signing secret.
mutationwebhooks.delete
Permanently delete a webhook and its full delivery log.
mutationwebhooks.rotateSecret
Generate a new signing secret. The old one stops working immediately.
mutationwebhooks.test
Send a canned test.ping payload to the receiver and report the result.

workspaces · 13 endpoints

Workspaces

Workspaces let multiple users collaborate on the same set of links. Owners, admins, members, and viewers each have different permissions. Pro tier billing is per-workspace, not per-seat.

queryworkspaces.list
List all workspaces the authenticated user is a member of.
queryworkspaces.get
Fetch one workspace with member count and the user's role within it.
mutationworkspaces.create
Create a new workspace. The creator becomes the owner automatically.
mutationworkspaces.update
Update workspace name. Requires admin or owner role.
mutationworkspaces.delete
Delete a workspace. Owner only. Cascade deletes members and clears link associations.
queryworkspaces.getMembers
List members with their roles and joined timestamps.
mutationworkspaces.addMember
Invite a user to a workspace by email with a role assignment.
mutationworkspaces.removeMember
Remove a member. Cannot remove the owner. Admins can only remove lower-permission members.
mutationworkspaces.updateMemberRole
Change a member's role. Cannot change the owner's role.
queryworkspaces.getAnalytics
Aggregate analytics across all workspace links: top performers, recent activity, member contributions.
queryworkspaces.getBilling
Get current billing tier, monthly link limit, subscription status, and Stripe customer details.
mutationworkspaces.createCheckoutSession
Create a Stripe checkout session to upgrade a workspace to Pro.
mutationworkspaces.createBillingPortalSession
Create a Stripe billing portal session for managing the workspace subscription.

apikeys · 3 endpoints

API keys

Most key management lives in Better-Auth's /api/auth/api-key endpoints (create, list, delete via authClient). These tRPC procedures handle the workspace-default-association layer that's specific to this app.

queryapikeys.listWithWorkspaces
List the user's API keys joined with their default workspace metadata.
mutationapikeys.setDefaultWorkspace
Set or clear the default workspace for an API key. Links created via that key will land in the default workspace unless overridden.
queryapikeys.getCurrentContext
Get the authenticated user/key context, including which API key (if any) made the request.

Chapter five

Errors

tRPC error codes are returned in the response body alongside an HTTP status. Map them to your own error handling.

BAD_REQUESTHTTP 400

Input failed Zod validation. Check the response body for the offending field.

UNAUTHORIZEDHTTP 401

Missing or invalid API key. Check your x-api-key header and that the key is enabled.

FORBIDDENHTTP 403

You're authenticated but not allowed to do this. Workspace permissions or admin checks failed.

NOT_FOUNDHTTP 404

The resource doesn't exist or has been deleted. Sometimes also returned to hide existence from unauthorized callers.

CONFLICTHTTP 409

Request conflicts with existing state — duplicate slug, member already exists, etc.

TOO_MANY_REQUESTSHTTP 429

Rate limited. The API key has its own per-minute limit (100 by default). Back off and retry.

INTERNAL_SERVER_ERRORHTTP 500

Something went wrong on our side. Safe to retry idempotent operations.

tRPC v11 · 56 endpoints · auth via x-api-key or session cookie