{"openapi":"3.1.0","info":{"title":"Trimly API","version":"1.0.0","description":"Trimly is the link management platform for modern teams — short links, custom domains, QR codes and click analytics in one place.\n\n### Authentication\n\nMachine clients authenticate with an API key created in **Settings → API**:\n\n```\nX-API-Key: trm_live_xxxxxxxxxxxx\n```\n\nThe first-party dashboard uses a short-lived bearer token plus an httpOnly refresh cookie.\n\n### Workspaces\n\nEvery resource belongs to a workspace. API keys are workspace-scoped. Bearer tokens select a workspace with the `X-Workspace-Id` header, defaulting to the caller's first membership.\n\n### Rate limits\n\nResponses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`. Exceeding a limit returns `429`.","contact":{"name":"Trimly docs","url":"https://zerogov.lol/docs"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://trimly-api.fly.dev/api/v1","description":"Current environment"}],"tags":[{"name":"Authentication","description":"Sign-in, registration and session management"},{"name":"Links","description":"Create, search and manage short links"},{"name":"Analytics","description":"Click analytics and exports"},{"name":"QR codes","description":"Generate and download QR codes"},{"name":"Domains","description":"Connect and verify custom domains"},{"name":"Organization","description":"Collections, tags and retargeting pixels"},{"name":"Workspace","description":"Members, invitations and activity"},{"name":"Developer","description":"API keys and webhooks"},{"name":"Billing","description":"Plans, subscription and usage"}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"parameters":{"WorkspaceId":{"name":"X-Workspace-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Target workspace. Defaults to the caller’s first membership."},"Page":{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},"PageSize":{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}},"schemas":{"ApiError":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string"},"details":{},"requestId":{"type":"string"}}}}},"PaginationMeta":{"type":"object","properties":{"page":{"type":"integer"},"pageSize":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}}},"Link":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string","example":"spring24"},"shortUrl":{"type":"string","format":"uri","example":"https://example.com/spring24"},"destinationUrl":{"type":"string","format":"uri"},"title":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"status":{"type":"string","enum":["ACTIVE","PAUSED","EXPIRED","ARCHIVED"]},"isFavorite":{"type":"boolean"},"hasPassword":{"type":"boolean"},"clickCount":{"type":"integer"},"uniqueClickCount":{"type":"integer"},"clickLimit":{"type":"integer","nullable":true},"expiresAt":{"type":"string","format":"date-time","nullable":true},"lastClickedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"tags":{"type":"array","items":{"$ref":"#/components/schemas/Tag"}}}},"CreateLink":{"type":"object","required":["destinationUrl"],"properties":{"destinationUrl":{"type":"string","format":"uri"},"slug":{"type":"string","description":"Custom alias. A random one is generated when omitted."},"domainId":{"type":"string","nullable":true},"title":{"type":"string"},"notes":{"type":"string"},"collectionId":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"string"}},"expiresAt":{"type":"string","format":"date-time","nullable":true},"password":{"type":"string","nullable":true},"clickLimit":{"type":"integer","nullable":true},"utm":{"type":"object","properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"generateQr":{"type":"boolean","default":false}}},"Tag":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"color":{"type":"string","nullable":true}}},"Collection":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"color":{"type":"string","nullable":true},"linkCount":{"type":"integer"}}},"Domain":{"type":"object","properties":{"id":{"type":"string"},"hostname":{"type":"string"},"status":{"type":"string","enum":["PENDING","VERIFYING","ACTIVE","FAILED"]},"verifiedAt":{"type":"string","format":"date-time","nullable":true},"linkCount":{"type":"integer"},"dnsRecords":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"},"ttl":{"type":"integer"}}}}}},"AnalyticsOverview":{"type":"object","properties":{"summary":{"type":"object","properties":{"totalClicks":{"type":"integer"},"uniqueVisitors":{"type":"integer"},"activeLinks":{"type":"integer"},"conversionRate":{"type":"number"}}},"timeseries":{"type":"array","items":{"type":"object","properties":{"bucket":{"type":"string","format":"date-time"},"clicks":{"type":"integer"},"uniques":{"type":"integer"}}}},"countries":{"type":"array","items":{"$ref":"#/components/schemas/Breakdown"}},"devices":{"type":"array","items":{"$ref":"#/components/schemas/Breakdown"}},"browsers":{"type":"array","items":{"$ref":"#/components/schemas/Breakdown"}},"referrers":{"type":"array","items":{"$ref":"#/components/schemas/Breakdown"}}}},"Breakdown":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"clicks":{"type":"integer"},"uniques":{"type":"integer"},"percentage":{"type":"number"}}}}},"paths":{"/links":{"get":{"tags":["Links"],"summary":"List links","parameters":[{"$ref":"#/components/parameters/WorkspaceId"},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PageSize"},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["ACTIVE","PAUSED","EXPIRED","ARCHIVED"]}},{"name":"tag","in":"query","schema":{"type":"string"}},{"name":"collectionId","in":"query","schema":{"type":"string"}},{"name":"sortBy","in":"query","schema":{"type":"string","enum":["createdAt","updatedAt","clickCount","uniqueClickCount","title","slug"],"default":"createdAt"}},{"name":"sortOrder","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"responses":{"200":{"description":"A page of links","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Link"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"tags":["Links"],"summary":"Create a link","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLink"}}}},"responses":{"201":{"description":"The created link","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Link"}}}}}},"402":{"description":"Plan limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Alias already in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/links/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/WorkspaceId"}],"get":{"tags":["Links"],"summary":"Retrieve a link","responses":{"200":{"description":"The link","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Link"}}}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"tags":["Links"],"summary":"Update a link","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLink"}}}},"responses":{"200":{"description":"The updated link","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/Link"}}}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"tags":["Links"],"summary":"Delete a link","responses":{"204":{"description":"Deleted"},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/links/bulk/delete":{"post":{"tags":["Links"],"summary":"Delete up to 500 links","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ids"],"properties":{"ids":{"type":"array","items":{"type":"string"},"maxItems":500}}}}}},"responses":{"200":{"description":"Count of deleted links"}}}},"/links/export":{"get":{"tags":["Links"],"summary":"Export every link as CSV","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"responses":{"200":{"description":"CSV file","content":{"text/csv":{}}}}}},"/links/import":{"post":{"tags":["Links"],"summary":"Bulk-import links from a CSV file","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Import summary with per-row errors"}}}},"/analytics/overview":{"get":{"tags":["Analytics"],"summary":"Aggregated click analytics","parameters":[{"$ref":"#/components/parameters/WorkspaceId"},{"name":"range","in":"query","schema":{"type":"string","enum":["24h","7d","30d","90d","12m","all"],"default":"7d"}},{"name":"linkId","in":"query","schema":{"type":"string"}},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"excludeBots","in":"query","schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Analytics overview","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/AnalyticsOverview"}}}}}}}}},"/analytics/top-links":{"get":{"tags":["Analytics"],"summary":"Best-performing links for a period","parameters":[{"$ref":"#/components/parameters/WorkspaceId"},{"name":"range","in":"query","schema":{"type":"string","default":"7d"}},{"name":"limit","in":"query","schema":{"type":"integer","default":10,"maximum":50}}],"responses":{"200":{"description":"Ranked links"}}}},"/analytics/export":{"get":{"tags":["Analytics"],"summary":"Export analytics as CSV, PDF or JSON","parameters":[{"$ref":"#/components/parameters/WorkspaceId"},{"name":"format","in":"query","schema":{"type":"string","enum":["csv","pdf","json"],"default":"csv"}},{"name":"range","in":"query","schema":{"type":"string","default":"7d"}}],"responses":{"200":{"description":"The exported report"}}}},"/qr-codes":{"get":{"tags":["QR codes"],"summary":"List QR codes","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"responses":{"200":{"description":"QR codes"}}},"post":{"tags":["QR codes"],"summary":"Create or restyle a link’s QR code","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["linkId"],"properties":{"linkId":{"type":"string"},"name":{"type":"string"},"style":{"type":"object","properties":{"foreground":{"type":"string","example":"#000000"},"background":{"type":"string","example":"#FFFFFF"},"dotStyle":{"type":"string","enum":["square","rounded","dots","classy"]},"errorCorrection":{"type":"string","enum":["L","M","Q","H"]}}}}}}}},"responses":{"201":{"description":"The QR code"}}}},"/qr-codes/{id}/download":{"get":{"tags":["QR codes"],"summary":"Download a QR code","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","schema":{"type":"string","enum":["png","svg","pdf"],"default":"png"}},{"name":"size","in":"query","schema":{"type":"integer","default":512,"maximum":2048}}],"responses":{"200":{"description":"The rendered QR code"}}}},"/domains":{"get":{"tags":["Domains"],"summary":"List custom domains","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"responses":{"200":{"description":"Domains","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}}}},"post":{"tags":["Domains"],"summary":"Connect a custom domain","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hostname"],"properties":{"hostname":{"type":"string","example":"go.example.com"},"rootRedirectUrl":{"type":"string","format":"uri","nullable":true},"notFoundRedirectUrl":{"type":"string","format":"uri","nullable":true}}}}}},"responses":{"201":{"description":"The domain, with DNS records to add"}}}},"/domains/{id}/verify":{"post":{"tags":["Domains"],"summary":"Check DNS and verify ownership","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The domain with its updated status"}}}},"/collections":{"get":{"tags":["Organization"],"summary":"List collections","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"responses":{"200":{"description":"Collections","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}}}},"post":{"tags":["Organization"],"summary":"Create a collection","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"color":{"type":"string","example":"#4F46E5"}}}}}},"responses":{"201":{"description":"The collection"}}}},"/tags":{"get":{"tags":["Organization"],"summary":"List tags","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"responses":{"200":{"description":"Tags"}}}},"/workspaces/members":{"get":{"tags":["Workspace"],"summary":"List workspace members","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"responses":{"200":{"description":"Members"}}}},"/workspaces/activity":{"get":{"tags":["Workspace"],"summary":"Audit trail for the workspace","parameters":[{"$ref":"#/components/parameters/WorkspaceId"},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PageSize"}],"responses":{"200":{"description":"Activity entries"}}}},"/developer/api-keys":{"get":{"tags":["Developer"],"summary":"List API keys","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"responses":{"200":{"description":"API keys (never the secret)"}}},"post":{"tags":["Developer"],"summary":"Create an API key","description":"The plaintext key is returned exactly once and cannot be retrieved again.","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","scopes"],"properties":{"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["links:read","links:write","analytics:read","domains:read","qr:write"]}}}}}}},"responses":{"201":{"description":"The key, including `plaintextKey`"}}}},"/developer/webhooks":{"get":{"tags":["Developer"],"summary":"List webhooks","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"responses":{"200":{"description":"Webhooks"}}},"post":{"tags":["Developer"],"summary":"Register a webhook","description":"Payloads are signed `X-Trimly-Signature: t=<unix>,v1=<hmac-sha256(t + \".\" + body)>`.","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["link.created","link.updated","link.deleted","link.clicked","link.expired","link.limit_reached","member.invited","member.joined","domain.verified"]}}}}}}},"responses":{"201":{"description":"The webhook, including its signing secret"}}}},"/billing/plans":{"get":{"tags":["Billing"],"summary":"List available plans","security":[],"responses":{"200":{"description":"Plans with their limits and pricing"}}}},"/billing/usage":{"get":{"tags":["Billing"],"summary":"Current usage against plan limits","parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"responses":{"200":{"description":"Usage snapshot"}}}},"/auth/login":{"post":{"tags":["Authentication"],"summary":"Sign in with email and password","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","format":"password"},"rememberMe":{"type":"boolean"}}}}}},"responses":{"200":{"description":"A session, or `{ twoFactorRequired: true, challengeToken }` when 2FA is enabled."},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many attempts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/auth/refresh":{"post":{"tags":["Authentication"],"summary":"Exchange a refresh token for a new session","security":[],"responses":{"200":{"description":"A rotated session"},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/auth/me":{"get":{"tags":["Authentication"],"summary":"The current user and their workspaces","responses":{"200":{"description":"Session"},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}}}