Skip to content
Developers

Build with toa.ee

A REST API, an MCP server for Claude and other AI assistants, and ready-made apps for Zapier, Make and your browser. On every plan, including Free.

Quick start

  1. Sign up or log in, and open Settings → Integrations.
  2. Create an API key.
  3. Make your first short link:
curl https://toa.ee/api/v1/links \
  -H "Authorization: Bearer $TOA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"destination":"https://example.com/spring-sale","slug":"spring"}'

Response:

{
  "id": "019a3f2c-8b1e-7d40-9c2a-1f6e4b8d0a11",
  "slug": "spring",
  "short_url": "https://toa.ee/spring",
  "destination": "https://example.com/spring-sale",
  "final_url": "https://example.com/spring-sale",
  "title": null,
  "utm": null,
  "redirect_type": 301,
  "status": "active",
  "hold_ends_at": null,
  "clicks": 0,
  "dashboard_url": "https://toa.ee/app/links/019a3f2c-8b1e-7d40-9c2a-1f6e4b8d0a11",
  "created_at": "2026-10-29T12:00:00.000Z",
  "updated_at": "2026-10-29T12:00:00.000Z"
}

Authentication

API keys use Authorization: Bearer toa_sk_…. Each key is read only, or read and write. Free allows 1 key; Ultra allows up to 50.

Apps sign in with OAuth 2.1 (authorization code + PKCE). Scopes are read and write. Discovery lives at /.well-known/oauth-authorization-server. Clients register with a Client ID Metadata Document or Dynamic Client Registration.

Use toa.ee in Claude and other AI assistants

Server URL

https://toa.ee/mcp

Claude (web, desktop, mobile): Settings → Connectors → Add custom connector, paste the URL, then sign in with your toa.ee account.

Claude Code: claude mcp add --transport http toa https://toa.ee/mcp, then /mcp → Authenticate.

Other MCP clients (Cursor, VS Code): Add a remote (Streamable HTTP) server with the URL above. Clients without OAuth can send an API key: Authorization: Bearer toa_sk_….

Get account and plan usage

Returns the signed-in toa.ee account's email, plan, and how many short links, digital business cards, API keys and API requests this month it has used against the plan's limits.

List short links

Lists the account's short links, newest first or by clicks. Search matches title, slug or destination. Returns up to 50 per page with a cursor for the next page.

Get a short link

Returns one short link by id or by its exact slug (slugs are case-sensitive), with its destination, UTM tags, status and total clicks.

Create a short link

Creates a short link at toa.ee/{slug} that redirects to the destination URL. Without a slug, toa.ee picks a random one. Slugs use letters, numbers, hyphens and underscores; accented letters are converted (ä → a). UTM tags are added to the destination.

Update a short link

Changes a short link's destination, slug, title, UTM tags or redirect type. Printed QR codes and shared links follow the new destination right away. Changing the slug breaks the old toa.ee address.

Delete a short link

Deletes a short link and its click stats. The toa.ee address stops working. Pass the link's current slug in confirm_slug. Links younger than 24 hours can't be deleted.

Get click stats for a short link

Returns click stats for one short link over a time range: totals, unique visitors, bot clicks, a time series, and top referrers, countries, devices and browsers. Stats are cookie-free and exclude bots from totals.

Compare short links and digital business cards

Compares two to five short links or digital business cards over the same time range: totals and a time series for each.

List digital business cards

Lists the account's digital business cards with their toa.ee address and status. Contact details are not included.

Get stats for a digital business card

Returns views, unique visitors, contact saves, taps per field, countries and devices for one digital business card over a time range.

Get a QR code

Returns a PNG QR code for a short link or digital business card, in the account's saved colours and logo. PNG, SVG and PDF downloads are on the item's page in the toa.ee dashboard.

List UTM templates

Lists the account's saved UTM templates, to use with create_short_link's utm_template_id.

Example prompts

  • Shorten https://example.com/spring-sale as toa.ee/spring with utm_source=newsletter.
  • Which of my short links got the most clicks last week, and from which countries?
  • Compare toa.ee/spring and toa.ee/summer for the last 30 days.
  • Make a QR code for toa.ee/menu.

Limits by plan

PlanRequests a monthRequests a minuteAPI keysNew links an hour
Free1,00030160
Pro10,00060360
Max100,00030010300
Ultra1,000,000600501,000

Every counted API and MCP call shares one monthly quota and one per-minute limit for the account, across every key and connected app.

Not counted toward the monthly quota (still counted per minute): GET /api/v1/me, the MCP get_account tool, Zapier and Make list polls, MCP discovery messages, GET /api/v1/openapi.json, and every OAuth endpoint.

The monthly quota resets on the 1st of each month, UTC.

Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-Quota-Limit, X-Quota-Remaining and X-Quota-Reset. A 429 also sends Retry-After.

See pricing

Errors

Every error uses the same shape: { "error": { "code", "message", "field?", "docs" } }. field is set only when one input is at fault.

HTTPCodeWhenMessage
400bad_requestBody isn't valid JSONThe request body isn't valid JSON.
401unauthorizedMissing, unknown, expired or revoked credential; account deleted or blockedUse a valid API key or sign in again.
403key_over_limitAPI key beyond the plan's key limit after a downgradeThis API key is over your plan's limit of keys. Revoke a key in Settings → Integrations or upgrade.
403insufficient_scopeWrite with read-only accessThis key or app has read-only access.
403limit_reachedLive-link limit reachedYou've hit this plan's link limit. Upgrade or delete a link.
404not_foundUnknown id, not owned, or wrong kindWe couldn't find that short link. / We couldn't find that digital business card.
409slug_takenSlug already in useThat slug isn't available. Try a different one.
409delete_too_soonLink younger than 24 hoursYou can delete a link only after 24 hours.
409in_plan_graceEdit of a held link after a downgradeThis link is in a plan grace period and can't be edited yet.
409idempotency_conflictSame Idempotency-Key, different requestThat Idempotency-Key was already used for a different request.
409idempotency_in_progressSame key while the first request is still runningA request with this Idempotency-Key is still running. Try again in a moment.
409qr_unavailableQR for a disabled, flagged or expired link, or a paused digital business cardA QR code isn't available for this item right now.
422validation_errorA field failed validationThe first field error, with field set.
422unsafe_destinationPrivate IP, SSRF or shortener nestingThat destination isn't allowed.
429rate_limitedPer-minute limitToo many requests. Try again in {seconds} seconds.
429quota_exceededMonthly request quota usedYou've used this month's API and MCP requests. See /pricing.
500internalUnexpected server errorSomething went wrong on our side. Try again.

Pagination and idempotency

List endpoints return { data, next_cursor }. Pass limit (1–100, default 25) and the opaque cursor from the previous page. Timestamps are ISO 8601 UTC with Z; field names are snake_case.

POST routes marked idempotent accept an Idempotency-Key header (1–255 characters). A repeat with the same key and body replays the first response; a different body with the same key returns 409 idempotency_conflict. Keys are per account and kept for 24 hours.

Versioning and changelog

Changes to /api/v1 are additive only. A breaking change means /api/v2, with at least six months' notice on this page.

  • On launch — API v1, MCP server (Claude and ChatGPT), Zapier, Make and browser extension.