{"openapi":"3.1.0","info":{"title":"KeptLink API","version":"1.0.0","description":"Create and manage dynamic QR codes and short links. Authenticate with `Authorization: Bearer <API key>` (create keys in Workspace settings). Every call counts toward the plan's rolling 24-hour API quota. Destination changes reach visitors within about a minute or two."},"servers":[{"url":"https://app.keptlink.com/api/v1"}],"security":[{"apiKey":[]}],"paths":{"/links":{"post":{"summary":"Create a link","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLinkRequest"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Link"}}}},"400":{"description":"Invalid request (error.code says why, e.g. invalid_destination)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid or revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed: plan, read-only workspace, or blocked link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Version conflict or code taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the plan's rolling 24-hour API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds"}}}}},"get":{"summary":"List links","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["active","archived"],"default":"active"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of links","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkList"}}}},"401":{"description":"The API key is missing, invalid or revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed: plan, read-only workspace, or blocked link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the plan's rolling 24-hour API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds"}}}}}},"/links/{id}":{"get":{"summary":"Get a link","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Link"}}}},"401":{"description":"The API key is missing, invalid or revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed: plan, read-only workspace, or blocked link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the plan's rolling 24-hour API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds"}}}}},"patch":{"summary":"Update a link","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLinkRequest"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Link"}}}},"400":{"description":"Invalid request (error.code says why, e.g. invalid_destination)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid or revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed: plan, read-only workspace, or blocked link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Version conflict or code taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the plan's rolling 24-hour API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds"}}}}}},"/links/{id}/archive":{"post":{"summary":"Archive a link","description":"An archived link stops redirecting (visitors see a 'link no longer active' page).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArchiveLinkRequest"}}}},"responses":{"200":{"description":"Archived","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Link"}}}},"401":{"description":"The API key is missing, invalid or revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed: plan, read-only workspace, or blocked link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Version conflict or code taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the plan's rolling 24-hour API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds"}}}}}},"/links/{id}/analytics/summary":{"get":{"summary":"Visit totals for a link","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"default":30}},{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Totals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsSummary"}}}},"400":{"description":"Invalid request (error.code says why, e.g. invalid_destination)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The API key is missing, invalid or revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed: plan, read-only workspace, or blocked link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in this workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Over the plan's rolling 24-hour API quota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds"}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"kl_live_…"}},"schemas":{"CreateLinkRequest":{"type":"object","properties":{"destination":{"type":"string","maxLength":4096,"description":"The http(s) URL visitors are sent to.","example":"https://example.com/menu"},"code":{"description":"A custom back-half (plans with custom back-halves). Random if omitted.","type":"string","maxLength":64},"domain_id":{"description":"An active custom domain of the workspace. Default: keptlink.app.","type":"string","maxLength":64},"title":{"description":"A label for you.","anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"tags":{"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":32}},"utm":{"type":"object","properties":{"source":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"medium":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"campaign":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"term":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"content":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]}},"additionalProperties":false,"description":"UTM parameters added to the destination when a visitor is redirected."},"forward_query":{"description":"Pass the short link's query string on to the destination.","type":"boolean"}},"required":["destination"],"additionalProperties":false},"UpdateLinkRequest":{"type":"object","properties":{"expected_version":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"The link's current version. A different version gets a 409."},"destination":{"type":"string","maxLength":4096},"title":{"description":"A label for you.","anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"tags":{"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":32}},"utm":{"type":"object","properties":{"source":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"medium":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"campaign":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"term":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"content":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]}},"additionalProperties":false,"description":"UTM parameters added to the destination when a visitor is redirected."},"forward_query":{"description":"Pass the short link's query string on to the destination.","type":"boolean"}},"required":["expected_version"],"additionalProperties":false},"ArchiveLinkRequest":{"type":"object","properties":{"expected_version":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"additionalProperties":false},"Link":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"hostname":{"type":"string"},"short_url":{"type":"string"},"qr_url":{"type":"string","description":"The URL encoded in the link's QR code."},"destination_url":{"type":"string"},"pending_destination_url":{"description":"A new destination still being safety-checked.","type":["string","null"]},"title":{"type":["string","null"]},"tags":{"type":"array","items":{"type":"string"}},"utm":{"type":"object","properties":{"source":{"type":["string","null"]},"medium":{"type":["string","null"]},"campaign":{"type":["string","null"]},"term":{"type":["string","null"]},"content":{"type":["string","null"]}},"required":["source","medium","campaign","term","content"],"additionalProperties":false},"forward_query":{"type":"boolean"},"status":{"type":"string","enum":["active","archived"]},"serve":{"type":"object","properties":{"state":{"type":"string","enum":["REDIRECT","PENDING","PAUSED","BLOCKED","GONE"]},"reason":{"type":["string","null"]}},"required":["state","reason"],"additionalProperties":false,"description":"What a visitor gets right now: a redirect, a safety check in progress, a paused, blocked or gone page."},"safety_status":{"type":"string"},"permanent":{"type":"boolean","description":"Keeps redirecting after a cancellation."},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"created_at":{"type":"string","description":"ISO 8601"},"updated_at":{"type":"string"},"archived_at":{"type":["string","null"]}},"required":["id","code","hostname","short_url","qr_url","destination_url","pending_destination_url","title","tags","utm","forward_query","status","serve","safety_status","permanent","version","created_at","updated_at","archived_at"],"additionalProperties":false},"LinkList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Link"}},"next_cursor":{"description":"Pass it as the cursor parameter for the next page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"AnalyticsSummary":{"type":"object","properties":{"link_id":{"type":"string"},"range":{"type":"object","properties":{"from":{"type":"string","description":"YYYY-MM-DD, the workspace's time zone"},"to":{"type":"string"},"timezone":{"type":"string"}},"required":["from","to","timezone"],"additionalProperties":false},"totals":{"type":"object","properties":{"visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"qr_visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"link_visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"visitor_days":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Distinct visitors per day, summed."}},"required":["visits","qr_visits","link_visits","visitor_days"],"additionalProperties":false},"all_time_visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["link_id","range","totals","all_time_visits"],"additionalProperties":false},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}