BUILD SOMETHING CONNECTED

A small API.
All the right context.

Look up all matching clicks in your account.

Authenticate

Create an API key in your dashboard. Treat it as a password and send it only from a trusted server. The full key is shown once; the service stores only its hash.

Authorization: Bearer <api_key>
GET https://iink.click/api/v1/check?ip_address=203.0.113.42
Authorization: Bearer <api_key>

The response is a JSON array with all matching clicks for your account’s links, including repeated visits to the same link. Supply at least one criterion: link IDs, IP, tags, short/destination/referrer URL text, device type/brand/model, operating system, browser, language, missing data, screen resolution, or a UTC time bound. IP is optional. Fields combine with AND, selected links with OR, and tags support Any/All matching. A valid search with no matches returns [] and consumes one API check. Use URL encoding for query values. cursor and tags_match alone do not count as criteria.

Both IPv4 and IPv6 are supported through ip_address. An explicitly supplied empty or invalid IP returns 400. The legacy ip parameter remains supported. If both parameters are supplied, they must normalize to the same address; conflicting addresses return 400.

[
  {
    "id": "dbd8d015-68a7-46cd-bcb2-f0acaa24a86a",
    "source_url": "https://iink.click/wakeo.rey",
    "target_url": "https://example.com/wakeo",
    "tags": ["promo", "wakeo"],
    "ip_address": "203.0.113.42",
    "clicked_at": "2026-10-10 14:30:12.123 UTC",
    "device_type": "smartphone",
    "device_brand": "Samsung",
    "device_model": "Galaxy S23",
    "os_name": "Android",
    "browser_name": "Chrome",
    "language": "en-GB",
    "referrer_url": "https://example.com/articles/wakeo?campaign=launch",
    "screen_width_css": 390,
    "screen_height_css": 844,
    "device_pixel_ratio": 3,
    "screen_width_px": 1170,
    "screen_height_px": 2532
  }
]
FieldMeaning
idThe click’s stable UUID version 4 identifier. It identifies this individual visit, stays the same across searches, and differs for repeated visits to the same link. The link ID is separate.
source_urlThe complete short URL as it appeared at the time of the click.
target_urlThe destination URL at the time of the click.
tagsThe link’s current tags as an array of strings. Returns [] when the link has no tags.
ip_addressThe recorded IPv4 or IPv6 address.
clicked_atClick timestamp in UTC, including milliseconds.
device_typeThe recognized device type, including detailed categories supplied by the parser. Returns "unknown" when unavailable.
device_brandThe recognized device brand, or null.
device_modelThe recognized device model, or null. Generic iPhone, iPad and iPod labels and the Android placeholder K are unavailable models.
os_nameThe recognized operating system name, or null.
browser_nameThe recognized browser name, or null.
languageThe preferred valid language tag from Accept-Language, respecting quality weights, or null.
referrer_urlThe full supplied HTTP(S) Referer, including its path and query, or null.
screen_width_css, screen_height_cssBrowser-reported screen width and height in CSS pixels, or null.
device_pixel_ratioThe browser-reported device pixel ratio (DPR), or null.
screen_width_px, screen_height_pxEstimated physical screen dimensions, calculated as floor(CSS size × DPR + 0.5), or null. These are estimates, not verified hardware specifications.

Device and visit metadata

These fields describe supplied request information from User-Agent, Accept-Language, UA Client Hints and HTTP Referer. They do not verify a physical device or a human visitor. A browser, app, proxy or automated client can omit, reduce or change this information. Parsing failures preserve the click and any independently available fields.

Older history can have no device information. Missing device types are "unknown"; other unavailable fields are explicitly null. Screen dimensions are collected only when the link owner enables collectScreen. They are reported by the browser and do not verify hardware. IP classification is not collected. Raw request headers and dictionary identifiers are not exposed by the API.

The dashboard history API includes these same device, visit and nullable screen fields. Open Device & visit details beneath a historical link to view them. Search results contain each visit snapshot that satisfies your criteria; unavailable fields stay unavailable rather than inheriting values from other visits.

The website lives under /ui/ and public backend endpoints stay under /api/. Customer links stay at the domain root, for example /wakeo.rey or /campaign/login, on both the primary domain and your custom domains.

Link endings contain 1–128 ASCII characters. Start every segment with a letter or number; dots, hyphens, underscores and tildes are allowed within a segment, with one slash between segments. Empty segments, traversal, backslashes, percent-encoded input and non-ASCII characters are rejected.

The following first-segment names are reserved, along with every descendant. Matching ignores case and treats underscores as hyphens. It checks the full first segment and the portion before its first dot, so sign_in, reset_password, login.php, admin.json and ui.anything/nested are blocked. Numbered sitemap names such as sitemap-1.xml are also reserved.

Reservations apply only to the first segment: campaign/login, wakeo/api and login-tips remain valid. Creating or editing a reserved path returns HTTP 400 with invalid_slug. A blocked short-link request returns 404 and records no click.

Optional screen collection

Screen collection is off by default for existing and new links. Enable Collect screen dimensions when creating or editing a dashboard link, or send the boolean collectScreen in the authenticated link API:

POST /api/dashboard/links
{
  "slug": "screen-demo",
  "targetUrl": "https://example.com/",
  "collectScreen": true
}

With PATCH /api/dashboard/links/:id, omit collectScreen to preserve the saved setting or send false to disable it. Nonboolean values return 400. Creation, editing and listing responses include collectScreen.

An enabled link serves a small intermediate page only for GET requests whose Accept header explicitly permits text/html. Its script reads screen.width, screen.height and devicePixelRatio, sends the measurements in the background and immediately opens the destination without waiting for a collector response. A separate refresh redirects after one second when JavaScript is unavailable, and a manual destination link is provided. Other GET requests and all HEAD requests keep the usual 302 response; HEAD does not record a click.

Measurements are browser-reported data. Physical screen resolution is an estimate, and collection and delivery are not guaranteed. Missing or invalid measurements leave all five screen fields null. No measurement delivery increments clicks or API checks. Screen measurements follow the original click’s 365-day retention and account history erasure; unmatched measurements are removed after 24 hours.

Manage and search tags

Create or edit a link in the dashboard using the comma-separated Tags field, for example wakeo, promo. The authenticated link API accepts tags as a JSON array:

POST /api/dashboard/links
{
  "slug": "wakeo.rey",
  "targetUrl": "https://example.com/wakeo",
  "tags": ["wakeo", "promo"]
}

New links default to []. With PATCH /api/dashboard/links/:id, omit tags to keep existing values, supply an array to replace them, or use {"tags": []} to clear them. Listing, creation and editing responses include saved tags. Link writes require an array; a comma-separated string is only accepted for search.

Tags trim surrounding whitespace, normalize Unicode to NFC, convert to lowercase, remove duplicates and sort. Use Unicode letters and digits, colons, hyphens and underscores (for example, app:wakeo). Internal whitespace, commas within a tag, empty entries, other characters and non-string values are invalid. Use at most 20 distinct normalized tags, with at most 64 Unicode characters per normalized tag.

GET https://iink.click/api/v1/check?tags=wakeo
GET https://iink.click/api/v1/check?tags=wakeo,promo&tags_match=or
GET https://iink.click/api/v1/check?ip_address=203.0.113.42&tags=wakeo&os_name=Android
Authorization: Bearer <api_key>

The default tags_match=and requires all requested tags; tags_match=or requires at least one. Other criteria still combine with AND. Unsupported matching modes, tags_match without tags, tags= and empty comma-separated entries return 400 without consuming a check.

Tag search uses each link’s current tags for all of its retained clicks. Editing tags immediately changes which past clicks are discoverable. Deleting a link preserves its tags and unexpired click history, so it can still appear in tag searches. Click URLs, destinations and visit metadata remain the values recorded at the time of each click.

Filter the dashboard history

Keep link selection, exact IPv4/IPv6, inclusive UTC date/time bounds and tags visible. Select multiple links; choose Any or All for tags. Open More filters for short URL, destination URL and referrer text searches, device type/brand/model, OS, browser, language and physical screen resolution. Search the recorded choices in each picker. Deleted links with retained history are marked, and active links remain selectable before their first click. Unknown/No data finds unavailable metadata, referrers or screen measurements.

Draft changes take effect when you choose Apply. Remove an active-filter chip to apply that removal, or use Clear to return to all retained history. Applied filters are saved in the page URL and restored on refresh and Back/Forward. Load more uses the applied criteria, and any filter change starts a new page. The last 24 hours, 7 days and 30 days presets resolve to absolute UTC timestamps when applied; all retained history leaves the bounds open. Dashboard history reads and picker requests do not consume API checks.

Search links, URLs and missing data

link_ids accepts comma-separated stable link IDs. Any selected link can match, including deleted links with retained clicks. IDs follow the link across renames. Use source_url_contains, target_url_contains and referrer_url_contains for case-insensitive literal substring searches against recorded click-time URL snapshots. SQL wildcard characters such as %, _ and backslash are literal text. URL searches must contain 1–4096 characters after trimming and no null byte.

GET https://iink.click/api/v1/check?link_ids=first-link-id,second-link-id&browser_name=Chrome
GET https://iink.click/api/v1/check?target_url_contains=campaign&language=en-GB
GET https://iink.click/api/v1/check?missing_fields=referrer_url,screen_resolution

missing_fields accepts a comma-separated list of device_type, device_brand, device_model, os_name, browser_name, language, referrer_url and screen_resolution. Every listed field must be unavailable. Missing device type includes recorded unknown and legacy null values. A value filter and a missing criterion for the same field return 400 without consuming a check.

Find matching clicks

Add any of these optional query parameters: device_brand, device_type, device_model, os_name, browser_name or language. All supplied filters must match. Matches are exact and case-sensitive after surrounding whitespace is trimmed; for example, Samsung and samsung are different values.

GET https://iink.click/api/v1/check?ip_address=203.0.113.42&device_brand=Samsung&device_type=smartphone&device_model=Galaxy%20S23&os_name=Android
Authorization: Bearer <api_key>

The API returns every retained click that satisfies your filters, including repeated clicks on the same link. For example, os_name=Android returns all matching Android visits. Your client decides whether to use the newest click or another subset. With no IP criterion, events can match across different IPs. Equal timestamps use event ID as a deterministic tie-breaker. device_type=unknown includes legacy visits without device type information. Unavailable metadata cannot match name filters; use missing_fields to find it.

Each supplied filter must contain 1–256 characters after trimming and must not contain a null byte. Blank or invalid filter values return 400 without consuming an API check. A valid lookup with no matches returns [] and consumes the usual check.

Use clicked_from_utc and clicked_to_utc to filter matching events by time. Both bounds are inclusive, and either can be supplied alone. Send a UTC timestamp in YYYY-MM-DDTHH:mm:ssZ format, with optional 1–3 fractional second digits. Surrounding whitespace is trimmed. Invalid timestamps, non-UTC offsets or a start later than the end return 400 without consuming an API check. All visits inside the range that satisfy every criterion are returned.

GET https://iink.click/api/v1/check?ip_address=203.0.113.42&clicked_from_utc=2026-10-11T11:00:00Z&clicked_to_utc=2026-10-11T12:00:00Z
Authorization: Bearer <api_key>

Search by estimated screen resolution

GET https://iink.click/api/v1/check?screen_resolution=1170x2532
GET https://iink.click/api/v1/check?tags=wakeo&screen_resolution=1170x2532&os_name=Android
Authorization: Bearer <api_key>

screen_resolution is sufficient as the only criterion, and combines with all other criteria using AND. Use positive integer sides from 1 to 524288, separated by x, X or ×. Surrounding whitespace is ignored. Side order is normalized, so 2532x1170 matches the same resolution as 1170x2532, including a rotated screen. URL-encode spaces and the multiplication sign when needed.

Matching uses the estimated physical pixel dimensions exactly, without a range or tolerance. Events without measurements do not match. Every click with matching measurements is returned, including older and repeated visits. Invalid resolutions return 400 without consuming an API check.

Continue through results

A page contains up to 100 records. If another page is available, the response includes an X-Next-Cursor header. Results are ordered by click time descending, with descending event ID for equal timestamps. Continuation tracks individual events, including repeated clicks on one link. Pass the opaque cursor value in the next request with every original criterion and the same effective tag matching mode. Cursors bind your account, history generation, search-contract version, canonical IP and every normalized filter. Filter scopes are hashed to keep cursors bounded. Reordered or duplicate link IDs and missing-field names, and URL searches differing only by case, are equivalent. Reordered tags, duplicate tags and equivalent casing are accepted; omitted tags_match and explicit and are equivalent. Swapping screen-resolution sides is equivalent; adding, removing or changing the normalized resolution invalidates the cursor before a check is charged. Preserve every time bound; equivalent fractional second precision is accepted. Adding, removing or changing criteria or matching mode invalidates the cursor before charging.

GET /api/v1/check?ip_address=203.0.113.42&device_brand=Samsung&device_type=smartphone&device_model=Galaxy%20S23&os_name=Android&cursor=<url_encoded_cursor>

Do not derive meaning from or modify cursor values. Cursors expire after 15 minutes. History erasure also invalidates continuation. This release advances the search contract to version 5; all existing version 4 or earlier cursors must restart from the first page. Each valid page is a separate API check, including an empty result. No continuation header means you have reached the end.

Pages read current data, so new clicks and tag edits between requests can change results or which links match. Pagination does not provide a frozen snapshot.

Handle status codes

StatusWhat to do
200Read the array and check the continuation header.
400Supply at least one criterion and check the supplied links, IP, URL text, tags, matching mode, metadata, missing fields, screen/time values and cursor. Preserve the same normalized criteria and effective tag mode on continuation. Invalid requests do not consume a check.
401Provide a valid, active Bearer key.
429The monthly API allowance is exhausted. Wait for the next UTC month or upgrade.

Know what the result represents

Allowances

Free includes 500 checks per calendar month. Pro includes 10,000. Months start at 00:00 UTC on the first day. The click threshold is separate from your API allowance and does not stop redirects or recording.

Create an API key