{"info":{"_postman_id":"6f0c1c1e-0c1c-4c1c-8c1c-0c1c1c1c1c1c","name":"C1K REST API","description":"Every path is relative to one organization: `https://c1k.me/api/v1/orgs/{org_id}`.\nA key binds to exactly one organization; a request for another organization,\nobject, cursor or bulk item answers 404 without details (API-02).\n\n**Authentication.** Send a REST key from the organization's Integrations page as\n`Authorization: Bearer c1k_rest_...`. Keys in a URL, query parameter or cookie are\nnever accepted, and browser sessions do not authenticate API calls (API-01,\nAUTH-03). Each key carries explicit scopes; an operation outside them answers 403.\n\n**Format.** Requests and responses are UTF-8 JSON. Bodies are limited to 65,536\nbytes and 16 levels of nesting (API-03). Successful responses carry `data` and\n`meta` (with `request_id`); errors carry `error` with a stable `code` (API-04).\nTimes are RFC 3339 in UTC with Z. Integers above 2^53-1 are sent as decimal strings.\n\n**Safe retries.** Creating links, bulk changes and import apply accept an\n`Idempotency-Key`; an identical retry returns the first result, or a compact form of it with the same identifiers when the full result did not fit the stored budget (API-06). Edits and\ndeletions need `If-Match` with the current version (API-07).\n\n**Rate limits** (API-08): 60 requests per minute per key, 300 per minute per\norganization and 10 mutations per minute per key. A 429 carries Retry-After.\n\n**AI assistants** use the MCP endpoint `https://c1k.me/mcp/{org_id}` with an MCP\ntoken or OAuth instead of this API; see https://c1k.me/developers/mcp.\n\nSet the collection variables orgId (from the Integrations page) and apiKey (a c1k_rest_ key). Every request authenticates with Bearer {{apiKey}}. Idempotency-Key headers use a fresh {{$guid}} per send.","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"},"auth":{"type":"bearer","bearer":[{"key":"token","value":"{{apiKey}}","type":"string"}]},"variable":[{"key":"orgId","value":"org_REPLACEWITHYOURID0","type":"string"},{"key":"apiKey","value":"","type":"string"},{"key":"baseUrl","value":"https://c1k.me/api/v1/orgs/{{orgId}}","type":"string"}],"item":[{"name":"Account","description":"The calling key, its organization, capabilities and quotas.","item":[{"name":"Identity, organization, capabilities and quotas of the calling key","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/me","host":["{{baseUrl}}"],"path":["me"]},"description":"Answers for any valid key, whatever its scopes. A good first call to check a new key.\n\nOperation getMe."},"response":[]}]},{"name":"Links","description":"Create, read, edit, pause, archive and delete short links, one at a time or up to 25 per request.","item":[{"name":"List links with filters and a cursor","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/links","host":["{{baseUrl}}"],"path":["links"],"query":[{"key":"q","value":"launch","description":"Search in slug, title and destination.","disabled":true},{"key":"state","value":"active","description":"","disabled":true},{"key":"tag","value":"launch","description":"","disabled":true},{"key":"campaign","value":"","description":"","disabled":true},{"key":"created_from","value":"","description":"RFC 3339 time or YYYY-MM-DD, inclusive.","disabled":true},{"key":"created_to","value":"","description":"RFC 3339 time or YYYY-MM-DD, exclusive.","disabled":true},{"key":"sort","value":"-created_at","description":"","disabled":true},{"key":"limit","value":"25","description":"","disabled":true},{"key":"cursor","value":"","description":"Opaque next_cursor from the previous page. Bound to the organization and filters, valid for 24 hours.","disabled":true}]},"description":"Requires links:read. Stable order by creation time and ID unless another supported sort is chosen (API-05). Pass `meta.next_cursor` back as `cursor` for the next page.\n\nOperation listLinks."},"response":[]},{"name":"Create one link","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Idempotency-Key","value":"{{$guid}}","description":"16 to 128 visible ASCII characters, unique per intended change. An identical retry within 24 hours returns the original result, or a compact form of it with the same identifiers when the full result did not fit the stored budget; a changed payload answers 409 (API-06). At most 20 unexpired keys per organization.","disabled":false}],"url":{"raw":"{{baseUrl}}/links","host":["{{baseUrl}}"],"path":["links"]},"description":"Requires links:write. Only destination_url is required. Omitted fields take their defaults, which are a random seven-character slug, no metadata, no schedule, no password, the primary domain and no query forwarding (API-10).\n\nOperation createLink.","body":{"mode":"raw","raw":"{\n  \"destination_url\": \"https://venture.example/launch\",\n  \"slug\": \"launch26\",\n  \"title\": \"Launch page\",\n  \"tags\": [\n    \"launch\"\n  ],\n  \"utm\": {\n    \"source\": \"newsletter\",\n    \"medium\": \"email\",\n    \"campaign\": \"launch26\"\n  }\n}","options":{"raw":{"language":"json"}}}},"response":[]},{"name":"Create or change up to 25 links with a result per item","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Idempotency-Key","value":"{{$guid}}","description":"16 to 128 visible ASCII characters, unique per intended change. An identical retry within 24 hours returns the original result, or a compact form of it with the same identifiers when the full result did not fit the stored budget; a changed payload answers 409 (API-06). At most 20 unexpired keys per organization.","disabled":false}],"url":{"raw":"{{baseUrl}}/links/bulk","host":["{{baseUrl}}"],"path":["links","bulk"]},"description":"Each item is applied on its own and never partially (LNK-11). Requires the scope of the operation. `create` items take the fields of Create one link; `pause`, `activate` and `archive` items take `id` and `expected_version`; `tag` items also take `tags` and `mode` (add, remove or replace).\n\nOperation bulkLinks.","body":{"mode":"raw","raw":"{\n  \"operation\": \"pause\",\n  \"items\": [\n    {\n      \"id\": \"lnk_4fQ2mVxT9kLpR7sA1b\",\n      \"expected_version\": 3\n    },\n    {\n      \"id\": \"lnk_9Hn3cZq8Wb2Ld5Rk7T\",\n      \"expected_version\": 1\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[]},{"name":"Read one link","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/links/:id","host":["{{baseUrl}}"],"path":["links",":id"],"variable":[{"key":"id","value":"lnk_4fQ2mVxT9kLpR7sA1b","description":""}]},"description":"Requires links:read. Never includes the password or its hash; `password_protected` says whether one is set.\n\nOperation getLink."},"response":[]},{"name":"Edit mutable fields or the lifecycle state","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"},{"key":"If-Match","value":"\"1\"","description":"The current integer version, for example \"3\", as returned in ETag. Missing answers 428, stale answers 412 (API-07).","disabled":false}],"url":{"raw":"{{baseUrl}}/links/:id","host":["{{baseUrl}}"],"path":["links",":id"],"variable":[{"key":"id","value":"lnk_4fQ2mVxT9kLpR7sA1b","description":""}]},"description":"Requires links:write and If-Match with the current version (API-07). Omitted fields are kept, null clears a nullable field and arrays replace the whole array. The slug and short URL never change.\n\nOperation updateLink.","body":{"mode":"raw","raw":"{\n  \"destination_url\": \"https://venture.example/launch-v2\",\n  \"title\": \"Launch page (v2)\"\n}","options":{"raw":{"language":"json"}}}},"response":[]},{"name":"Erase the link and keep its short key reserved","request":{"method":"DELETE","header":[{"key":"If-Match","value":"\"1\"","description":"The current integer version, for example \"3\", as returned in ETag. Missing answers 428, stale answers 412 (API-07).","disabled":false}],"url":{"raw":"{{baseUrl}}/links/:id","host":["{{baseUrl}}"],"path":["links",":id"],"variable":[{"key":"id","value":"lnk_4fQ2mVxT9kLpR7sA1b","description":""}]},"description":"Requires links:delete and If-Match. The link and its analytics are erased; the slug can never be reused (LNK-05).\n\nOperation deleteLink."},"response":[]},{"name":"SVG QR code of the short URL","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/links/:id/qr","host":["{{baseUrl}}"],"path":["links",":id","qr"],"variable":[{"key":"id","value":"lnk_4fQ2mVxT9kLpR7sA1b","description":""}]},"description":"Requires links:read. Error correction level M with a four-module quiet zone (LNK-10). The SVG contains only the code.\n\nOperation getLinkQr."},"response":[]}]},{"name":"Analytics","description":"Recorded requests per day and dimension, with coverage and estimate labels. Counts are served redirects, not people.","item":[{"name":"Daily and lifetime recorded requests of one link","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/links/:id/analytics","host":["{{baseUrl}}"],"path":["links",":id","analytics"],"query":[{"key":"from","value":"2026-09-01","description":"ISO 8601 UTC date, inclusive. With `to` at most 30 days apart; both omitted select the last seven days.","disabled":true},{"key":"to","value":"2026-09-08","description":"ISO 8601 UTC date, exclusive.","disabled":true}],"variable":[{"key":"id","value":"lnk_4fQ2mVxT9kLpR7sA1b","description":""}]},"description":"Requires analytics:read. Link daily figures are kept for seven UTC days; lifetime totals until the analytics are purged or the link is deleted.\n\nOperation getLinkAnalytics."},"response":[]},{"name":"Organization daily totals and dimensions","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/analytics","host":["{{baseUrl}}"],"path":["analytics"],"query":[{"key":"from","value":"2026-09-01","description":"ISO 8601 UTC date, inclusive. With `to` at most 30 days apart; both omitted select the last seven days.","disabled":true},{"key":"to","value":"2026-09-08","description":"ISO 8601 UTC date, exclusive.","disabled":true}]},"description":"Requires analytics:read. The same figures as the Analytics page for equal filters (ANA-09). Without from and to it covers the last seven UTC days.\n\nOperation getAnalytics."},"response":[]},{"name":"Purge all or selected-link analytics","request":{"method":"DELETE","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/analytics","host":["{{baseUrl}}"],"path":["analytics"]},"description":"Requires analytics:delete. Cannot be undone (ANA-10). Removes counters, sketches and dimensions in bounded batches. When the answer has done false, send the same request with the returned started_at until done is true. Link IDs outside the organization answer 404.\n\nOperation purgeAnalytics.","body":{"mode":"raw","raw":"{\n  \"confirm\": true,\n  \"link_ids\": [\n    \"lnk_4fQ2mVxT9kLpR7sA1b\"\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[]}]},{"name":"Events","description":"A bounded change feed for keeping another system in sync.","item":[{"name":"Poll the change feed after a cursor","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/events","host":["{{baseUrl}}"],"path":["events"],"query":[{"key":"limit","value":"100","description":"","disabled":true},{"key":"cursor","value":"","description":"Opaque next_cursor from the previous page. Bound to the organization and filters, valid for 24 hours.","disabled":true}]},"description":"Requires events:read. Events come in increasing ID order, at most 100 per page.\nThe feed keeps at most 100 events per organization and seven days. A cursor\nolder than the retained history answers 410 cursor_expired; take a fresh\nsnapshot and poll again without a cursor. Deduplicate by event ID (EVT-02).\n\n\nOperation listEvents."},"response":[]}]},{"name":"Import and export","description":"Chunked link import with validation receipts, and streamed exports of links and analytics.","item":[{"name":"Check one import chunk without writing anything","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/imports/validate","host":["{{baseUrl}}"],"path":["imports","validate"]},"description":"Requires links:write. At most 25 rows and 65,536 bytes (IO-02). Returns every row as ok or with its error, and a receipt valid for ten minutes that is bound to the organization, the caller and the SHA-256 of the rows. Fields other than the listed ones, including password, fail their row.\n\nOperation validateImport.","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"row\": 1,\n      \"destination_url\": \"https://venture.example/spring\",\n      \"slug\": \"spring26\",\n      \"tags\": [\n        \"campaign\"\n      ]\n    },\n    {\n      \"row\": 2,\n      \"destination_url\": \"https://venture.example/summer\",\n      \"title\": \"Summer offer\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}}},"response":[]},{"name":"Create the rows of a validated chunk","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Idempotency-Key","value":"{{$guid}}","description":"16 to 128 visible ASCII characters, unique per intended change. An identical retry within 24 hours returns the original result, or a compact form of it with the same identifiers when the full result did not fit the stored budget; a changed payload answers 409 (API-06). At most 20 unexpired keys per organization.","disabled":false}],"url":{"raw":"{{baseUrl}}/imports/apply","host":["{{baseUrl}}"],"path":["imports","apply"]},"description":"Requires links:write and an Idempotency-Key. Send the validated rows unchanged with their receipt (IO-03). Each row is created in its own transaction with authorization, quota, capacity and slug checked again; existing links are never changed. A retry with the same key returns the first result. An expired or mismatched receipt answers 409; validate the chunk again.\n\nOperation applyImport.","body":{"mode":"raw","raw":"{\n  \"rows\": [\n    {\n      \"row\": 1,\n      \"destination_url\": \"https://venture.example/spring\",\n      \"slug\": \"spring26\",\n      \"tags\": [\n        \"campaign\"\n      ]\n    }\n  ],\n  \"receipt\": \"eyJ2IjoxLCJvcmciOiJvcmdfLi4uIn0.SIGNATURE\"\n}","options":{"raw":{"language":"json"}}}},"response":[]},{"name":"Stream the link configuration as CSV or versioned JSON","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/exports/links","host":["{{baseUrl}}"],"path":["exports","links"],"query":[{"key":"format","value":"csv","description":"csv (the default) or json.","disabled":true}]},"description":"Requires exports:read. Read in batches and streamed; no copy stays on the server and no password material is included (IO-01). CSV cells that begin with =, +, -, @, a tab or a carriage return get one leading apostrophe, removed again on import. The last CSV record is \"#end\" with the record count.\n\nOperation exportLinks."},"response":[]},{"name":"Stream retained analytics as CSV or versioned JSON","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/exports/analytics","host":["{{baseUrl}}"],"path":["exports","analytics"],"query":[{"key":"format","value":"csv","description":"csv (the default) or json.","disabled":true}]},"description":"Requires exports:read and analytics:read. Daily totals, per-link days, dimension buckets, lifetime totals, collection gaps and coverage notes, streamed (IO-01).\n\nOperation exportAnalytics."},"response":[]}]},{"name":"Members","description":"Invitation links, roles and removal of organization members.","item":[{"name":"Active members, owners first, with pending invitations in meta","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/members","host":["{{baseUrl}}"],"path":["members"]},"description":"Requires members:manage. Invitation links are never listed again.\n\nOperation listMembers."},"response":[]},{"name":"Create a single-use invitation link for a new member","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/members","host":["{{baseUrl}}"],"path":["members"]},"description":"Requires members:manage. People join only by opening an invitation link (TEN-04); C1K sends no mail. The link is returned once and works for 72 hours. A key acts as an administrator, so it cannot invite an owner. An optional email binds the invitation to that account.\n\nOperation inviteMember.","body":{"mode":"raw","raw":"{\n  \"role\": \"editor\",\n  \"email\": \"new.colleague@venture.example\"\n}","options":{"raw":{"language":"json"}}}},"response":[]},{"name":"Change a member's role within the caller's authority","request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/members/:user_id","host":["{{baseUrl}}"],"path":["members",":user_id"],"variable":[{"key":"user_id","value":"usr_REPLACEWITHUSERID0","description":""}]},"description":"Requires members:manage. Administrators and keys cannot change owners or assign the owner role.\n\nOperation changeMemberRole.","body":{"mode":"raw","raw":"{\n  \"role\": \"admin\"\n}","options":{"raw":{"language":"json"}}}},"response":[]},{"name":"End a membership","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/members/:user_id","host":["{{baseUrl}}"],"path":["members",":user_id"],"variable":[{"key":"user_id","value":"usr_REPLACEWITHUSERID0","description":""}]},"description":"Requires members:manage. The member's sessions and delegated access end on their next request. The last owner cannot be removed (409), and keys cannot remove owners.\n\nOperation removeMember."},"response":[]}]},{"name":"Integrations","description":"Service accounts and their REST and MCP keys.","item":[{"name":"Service accounts of the organization","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/service-accounts","host":["{{baseUrl}}"],"path":["service-accounts"]},"description":"Requires integrations:manage.\n\nOperation listServiceAccounts."},"response":[]},{"name":"Create a service account","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/service-accounts","host":["{{baseUrl}}"],"path":["service-accounts"]},"description":"Requires integrations:manage. At most two active service accounts per organization.\n\nOperation createServiceAccount.","body":{"mode":"raw","raw":"{\n  \"name\": \"website backend\"\n}","options":{"raw":{"language":"json"}}}},"response":[]},{"name":"Revoke a service account and every key it holds","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/service-accounts/:id","host":["{{baseUrl}}"],"path":["service-accounts",":id"],"variable":[{"key":"id","value":"sva_REPLACEWITHACCTID0","description":""}]},"description":"Requires integrations:manage. Its keys stop working on their next request.\n\nOperation revokeServiceAccount."},"response":[]},{"name":"Keys of the organization without their secrets","request":{"method":"GET","header":[],"url":{"raw":"{{baseUrl}}/credentials","host":["{{baseUrl}}"],"path":["credentials"]},"description":"Requires integrations:manage.\n\nOperation listCredentials."},"response":[]},{"name":"Create a key; the secret is returned once","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{baseUrl}}/credentials","host":["{{baseUrl}}"],"path":["credentials"]},"description":"Requires integrations:manage. A key may create keys only with a subset of its own scopes; an owner can grant more on the Integrations page. At most four live keys per organization. Audience rest makes a REST key, audience mcp an MCP token.\n\nOperation createCredential.","body":{"mode":"raw","raw":"{\n  \"service_account_id\": \"sva_REPLACEWITHACCTID0\",\n  \"name\": \"reporting job\",\n  \"audience\": \"rest\",\n  \"scopes\": [\n    \"links:read\",\n    \"analytics:read\"\n  ],\n  \"expires_in_days\": 90\n}","options":{"raw":{"language":"json"}}}},"response":[]},{"name":"Revoke a key immediately","request":{"method":"DELETE","header":[],"url":{"raw":"{{baseUrl}}/credentials/:id","host":["{{baseUrl}}"],"path":["credentials",":id"],"variable":[{"key":"id","value":"crd_REPLACEWITHKEYID00","description":""}]},"description":"Requires integrations:manage. The key stops working on its next request.\n\nOperation revokeCredential."},"response":[]}]}]}