{"components":{"parameters":{"EventsCursor":{"in":"query","name":"cursor","schema":{"type":"string"}},"EventsFrom":{"description":"Default 24 hours before `to`.","in":"query","name":"from","schema":{"format":"date-time","type":"string"}},"EventsLimit":{"in":"query","name":"limit","schema":{"default":100,"maximum":1000,"minimum":1,"type":"integer"}},"EventsLinkId":{"in":"query","name":"link_id","schema":{"pattern":"^lnk_[0-9A-Z]{26}$","type":"string"}},"EventsRef":{"in":"query","name":"ref","schema":{"maxLength":256,"minLength":1,"type":"string"}},"EventsTo":{"description":"Default now. At most 31 days after `from`.","in":"query","name":"to","schema":{"format":"date-time","type":"string"}},"EventsType":{"in":"query","name":"type","schema":{"$ref":"#/components/schemas/EventType"}},"LinkID":{"in":"path","name":"id","required":true,"schema":{"pattern":"^lnk_[0-9A-Z]{26}$","type":"string"}},"MetricsCursor":{"in":"query","name":"cursor","schema":{"type":"string"}},"MetricsFrom":{"description":"Inclusive start date in tz. Default 7 days before to.","in":"query","name":"from","schema":{"format":"date","type":"string"}},"MetricsGranularity":{"in":"query","name":"granularity","schema":{"default":"day","enum":["day","hour"],"type":"string"}},"MetricsGroupBy":{"description":"link (default), day, or metadata.\u003ckey\u003e for a scalar key of the link's metadata.","in":"query","name":"group_by","schema":{"default":"link","pattern":"^(link|day|metadata\\.[A-Za-z0-9_]{1,64})$","type":"string"}},"MetricsLimit":{"in":"query","name":"limit","schema":{"default":1000,"maximum":5000,"minimum":1,"type":"integer"}},"MetricsTZ":{"description":"IANA timezone name. Default UTC.","in":"query","name":"tz","schema":{"default":"UTC","type":"string"}},"MetricsTo":{"description":"Inclusive end date in tz. Default today in tz. At most 93 days after from.","in":"query","name":"to","schema":{"format":"date","type":"string"}},"MetricsType":{"description":"Comma-separated subset of land, store_click, install, open, custom.","in":"query","name":"type","schema":{"type":"string"}}},"responses":{"BadRequest":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The request does not conform to this document or fails a validation rule"},"Forbidden":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"A client key was used where a server key is required"},"NotFound":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"No such resource in the caller's project"},"RateLimited":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Budget exceeded; Retry-After says when to try again","headers":{"Retry-After":{"schema":{"type":"integer"}}}},"Unauthorized":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Missing, malformed, unknown or revoked key"}},"schemas":{"ChangeRow":{"properties":{"count":{"description":"The day's current total, not a delta.","format":"int64","type":"integer"},"day":{"description":"YYYY-MM-DD in the requested tz.","type":"string"},"link_id":{"type":"string"},"metadata":{"$ref":"#/components/schemas/Metadata"},"name":{"description":"null unless type is custom.","nullable":true,"type":"string"},"partial":{"description":"True when the day contains the current time in tz.","type":"boolean"},"platform":{"$ref":"#/components/schemas/Platform"},"ref":{"type":"string"},"type":{"$ref":"#/components/schemas/EventType"},"value_sum":{"format":"double","type":"number"}},"required":["link_id","ref","metadata","day","type","name","platform","count","value_sum","partial"],"type":"object"},"ChangesResponse":{"properties":{"more":{"description":"True when the page was cut by limit; call again with next_since.","type":"boolean"},"next_since":{"description":"Pass back as since; equals the request's since when nothing changed.","type":"string"},"rows":{"items":{"$ref":"#/components/schemas/ChangeRow"},"type":"array"}},"required":["rows","next_since","more"],"type":"object"},"CheckStatus":{"enum":["ok","fail"],"type":"string"},"Checks":{"properties":{"postgres":{"$ref":"#/components/schemas/CheckStatus"},"redis":{"$ref":"#/components/schemas/CheckStatus"},"schema":{"$ref":"#/components/schemas/CheckStatus"}},"required":["postgres","redis","schema"],"type":"object"},"DeepLink":{"additionalProperties":true,"description":"Delivered verbatim to the app library; at most 4 KB. `url`, when present, is the\nrouting field: the app URL (http(s) or an app scheme such as kariyer://job/123) the\nlibrary hands to the app's own router. Other members are free-form extras. When an\nupsert carries no deep_link, the project's deep-link rules may derive one from\ndestination_url.\n","properties":{"url":{"description":"Absolute URL; scheme http, https or an app scheme ([a-z][a-z0-9+.-]*).","maxLength":2048,"type":"string"}},"type":"object"},"DeepLinkResponse":{"properties":{"deep_link":{"allOf":[{"$ref":"#/components/schemas/DeepLink"}],"nullable":true}},"required":["deep_link"],"type":"object"},"DeepLinkSource":{"description":"Where a link's deep_link came from — sent by the caller, or derived by a project rule.","enum":["explicit","rule"],"type":"string"},"Error":{"properties":{"error":{"properties":{"code":{"$ref":"#/components/schemas/ErrorCode"},"message":{"type":"string"}},"required":["code","message"],"type":"object"}},"required":["error"],"type":"object"},"ErrorCode":{"description":"Stable error identifiers.","enum":["unauthorized","server_key_required","rate_limited","invalid_request","not_found","method_not_allowed","internal","unhealthy","invalid_credentials","csrf_rejected","forbidden","conflict"],"type":"string"},"Event":{"properties":{"attributed":{"type":"boolean"},"attrs":{"additionalProperties":true,"type":"object"},"device_nonce":{"type":"string"},"event_id":{"description":"UUID, lower-cased.","type":"string"},"link_id":{"type":"string"},"name":{"description":"Empty when the type is not custom.","type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"received_at":{"format":"date-time","type":"string"},"source":{"$ref":"#/components/schemas/EventSource"},"time":{"description":"The stored event time (client_ts, clamped to receipt when in the future).","format":"date-time","type":"string"},"token_acquired_at":{"format":"date-time","nullable":true,"type":"string"},"type":{"$ref":"#/components/schemas/EventType"},"value":{"format":"double","nullable":true,"type":"number"}},"required":["event_id","link_id","type","name","value","platform","source","time","received_at","device_nonce","token_acquired_at","attributed","attrs"],"type":"object"},"EventBatchRequest":{"properties":{"events":{"items":{"$ref":"#/components/schemas/EventInput"},"maxItems":100,"minItems":1,"type":"array"}},"required":["events"],"type":"object"},"EventBatchResponse":{"properties":{"accepted":{"type":"integer"},"rejected":{"items":{"$ref":"#/components/schemas/RejectedEvent"},"type":"array"}},"required":["accepted","rejected"],"type":"object"},"EventInput":{"properties":{"attrs":{"additionalProperties":true,"description":"Flat object of scalars, at most 2 KB. Checked per event.","type":"object"},"client_ts":{"description":"RFC 3339. When the event happened on the device; drives the rollup bucket. Checked per event.","type":"string"},"device_nonce":{"description":"Random per-install id generated by the library. Never a device identifier.","maxLength":64,"minLength":1,"type":"string"},"event_id":{"description":"UUID generated by the library or snippet; the identity used for deduplication. Checked per event (invalid_event), not per batch.","type":"string"},"gol":{"description":"The 22-character link token from the URL, referrer or pasteboard. Checked per event.","type":"string"},"name":{"description":"Required for type custom, forbidden otherwise.","maxLength":64,"minLength":1,"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"source":{"$ref":"#/components/schemas/EventSource"},"token_acquired_at":{"description":"RFC 3339. When the library first stored this token; used for the custom-event attribution window. Checked per event.","type":"string"},"type":{"$ref":"#/components/schemas/EventType"},"value":{"format":"double","type":"number"}},"required":["event_id","gol","type","platform","source","client_ts","device_nonce"],"type":"object"},"EventListResponse":{"properties":{"events":{"items":{"$ref":"#/components/schemas/Event"},"type":"array"},"next_cursor":{"nullable":true,"type":"string"}},"required":["events","next_cursor"],"type":"object"},"EventSource":{"enum":["url","install_referrer","pasteboard","cookie"],"type":"string"},"EventType":{"enum":["land","store_click","install","open","custom"],"type":"string"},"Health":{"properties":{"checks":{"$ref":"#/components/schemas/Checks"},"commit":{"description":"Short commit the binary was built from (`none` for an unversioned build).","example":"3176efc","type":"string"},"status":{"enum":["ok"],"type":"string"},"version":{"description":"Release the binary was built as (`dev` for an unversioned build).","example":"v0.1.0","type":"string"}},"required":["status","checks","version","commit"],"type":"object"},"KeyInfo":{"properties":{"key":{"properties":{"created_at":{"description":"Server keys only.","format":"date-time","type":"string"},"id":{"description":"Server keys only.","type":"string"},"kind":{"enum":["server","client"],"type":"string"},"label":{"description":"Server keys only.","type":"string"}},"required":["kind"],"type":"object"},"limits":{"description":"Server keys only.","properties":{"links_per_call":{"type":"integer"},"server_rate":{"description":"The per-project server-key budget as configured, e.g. \"1200/m\".","type":"string"}},"required":["links_per_call","server_rate"],"type":"object"},"project":{"properties":{"attribution_window_days":{"description":"Server keys only.","type":"integer"},"id":{"type":"string"},"link_ttl_days":{"description":"Server keys only.","type":"integer"},"name":{"type":"string"},"post_close_window_days":{"description":"Server keys only.","type":"integer"},"timezone":{"type":"string"}},"required":["id","name","timezone"],"type":"object"}},"required":["project","key"],"type":"object"},"Link":{"properties":{"click_param":{"type":"string"},"closed_at":{"description":"When a close shortened the link's life; null otherwise, and null again after a later upsert.","format":"date-time","nullable":true,"type":"string"},"created_at":{"format":"date-time","type":"string"},"deep_link":{"allOf":[{"$ref":"#/components/schemas/DeepLink"}],"nullable":true},"deep_link_source":{"allOf":[{"$ref":"#/components/schemas/DeepLinkSource"}],"nullable":true},"destination_url":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"metadata":{"$ref":"#/components/schemas/Metadata"},"ref":{"type":"string"},"status":{"$ref":"#/components/schemas/LinkStatus"},"token":{"type":"string"},"tracked_deep_link":{"description":"deep_link.url with gol=\u003ctoken\u003e set by the same rule as tracked_url, any gol already\npresent removed first; null when there is no deep_link or it has no url.\n","nullable":true,"type":"string"},"tracked_url":{"description":"destination_url with gol=\u003ctoken\u003e set.","type":"string"},"updated_at":{"format":"date-time","type":"string"}},"required":["id","ref","token","click_param","tracked_url","destination_url","deep_link","tracked_deep_link","metadata","status","created_at","updated_at","expires_at"],"type":"object"},"LinkCloseRequest":{"properties":{"refs":{"items":{"type":"string"},"maxItems":500,"minItems":1,"type":"array"}},"required":["refs"],"type":"object"},"LinkCloseResponse":{"properties":{"links":{"items":{"$ref":"#/components/schemas/LinkCloseResult"},"type":"array"}},"required":["links"],"type":"object"},"LinkCloseResult":{"description":"Either a link the project holds (status, expires_at, closed_at) or an unknown ref (error).","properties":{"closed_at":{"format":"date-time","nullable":true,"type":"string"},"error":{"$ref":"#/components/schemas/LinkItemError"},"expires_at":{"format":"date-time","type":"string"},"ref":{"type":"string"},"status":{"$ref":"#/components/schemas/LinkStatus"}},"required":["ref"],"type":"object"},"LinkInput":{"description":"Item rules are checked per link and reported in its result rather than rejecting the\nbatch: `ref` 1–256 characters and required; `destination_url` required, an absolute\nhttp(s) URL of at most 2048 characters; `deep_link` a JSON object of at most 4 KB;\n`metadata` a flat object of scalars of at most 8 KB.\n","properties":{"deep_link":{"$ref":"#/components/schemas/DeepLink"},"destination_url":{"description":"The landing page; informational in v1 (no redirect). Absolute http(s), at most 2048 characters.","type":"string"},"metadata":{"$ref":"#/components/schemas/Metadata"},"ref":{"description":"The customer's own id for the ad unit; unique per project. 1–256 characters.","type":"string"}},"type":"object"},"LinkItemError":{"properties":{"code":{"$ref":"#/components/schemas/ErrorCode"},"field":{"description":"The offending field of the input link (ref, destination_url, deep_link, metadata).","type":"string"},"message":{"type":"string"}},"required":["code","field","message"],"type":"object"},"LinkStatus":{"enum":["active","expired","deleted"],"type":"string"},"LinkUpsertRequest":{"properties":{"links":{"items":{"$ref":"#/components/schemas/LinkInput"},"maxItems":500,"minItems":1,"type":"array"}},"required":["links"],"type":"object"},"LinkUpsertResponse":{"properties":{"failed":{"description":"Number of items carrying `error`.","type":"integer"},"links":{"items":{"$ref":"#/components/schemas/LinkUpsertResult"},"type":"array"}},"required":["links","failed"],"type":"object"},"LinkUpsertResult":{"description":"Either a written link (every field but `error`) or a rejected one (`ref` echoed as\nsent plus `error`, nothing else).\n","properties":{"click_param":{"description":"Append to a URL go never sees (the ad's deep-link field), e.g. \"gol=7Kq9mZ2pX4vL8nR3tW6yAb\".","type":"string"},"created":{"description":"true when this call created the link, false when it updated an existing ref.","type":"boolean"},"deep_link":{"allOf":[{"$ref":"#/components/schemas/DeepLink"}],"description":"The stored payload — sent by the caller or derived by a project rule — or null.","nullable":true},"deep_link_source":{"allOf":[{"$ref":"#/components/schemas/DeepLinkSource"}],"nullable":true},"error":{"$ref":"#/components/schemas/LinkItemError"},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"ref":{"type":"string"},"status":{"$ref":"#/components/schemas/LinkStatus"},"token":{"type":"string"},"tracked_deep_link":{"description":"deep_link.url with gol=\u003ctoken\u003e set by the same rule as tracked_url (query appended,\nfragment kept, nothing re-encoded, any gol already present removed first), whatever\nthe scheme; hand this to the ad platform as the deep-link field. null when the link\nhas no deep_link or its deep_link has no url.\n","nullable":true,"type":"string"},"tracked_url":{"description":"destination_url with gol=\u003ctoken\u003e set; hand this to the ad platform as the web destination.","type":"string"}},"required":["ref"],"type":"object"},"Metadata":{"additionalProperties":true,"description":"Flat object of scalar values (string, number, boolean, null); at most 8 KB. Nested values are rejected. Used by metrics group_by.","type":"object"},"MetricsResponse":{"properties":{"next_cursor":{"nullable":true,"type":"string"},"rows":{"items":{"$ref":"#/components/schemas/MetricsRow"},"type":"array"}},"required":["rows","next_cursor"],"type":"object"},"MetricsRow":{"properties":{"count":{"format":"int64","type":"integer"},"day":{"description":"Calendar date of the bucket in tz.","format":"date","type":"string"},"hour":{"description":"Bucket start with the tz offset. Only with granularity=hour.","format":"date-time","type":"string"},"link_id":{"description":"Only with group_by=link.","type":"string"},"metadata_value":{"description":"Only with group_by=metadata.\u003ckey\u003e; null for links without the key.","nullable":true,"type":"string"},"name":{"description":"The custom event name; null for other types.","nullable":true,"type":"string"},"partial":{"description":"true when the bucket contains the current time in tz.","type":"boolean"},"platform":{"$ref":"#/components/schemas/Platform"},"ref":{"description":"Only with group_by=link.","type":"string"},"type":{"$ref":"#/components/schemas/EventType"},"value_sum":{"format":"double","type":"number"}},"required":["day","type","name","platform","count","value_sum","partial"],"type":"object"},"Platform":{"enum":["android","ios","web"],"type":"string"},"RejectReason":{"enum":["invalid_event","too_old","unknown_token","link_expired","link_deleted"],"type":"string"},"RejectedEvent":{"properties":{"index":{"type":"integer"},"reason":{"$ref":"#/components/schemas/RejectReason"}},"required":["index","reason"],"type":"object"},"Unhealthy":{"allOf":[{"$ref":"#/components/schemas/Error"},{"properties":{"checks":{"$ref":"#/components/schemas/Checks"}},"required":["checks"],"type":"object"}]}},"securitySchemes":{"ClientKey":{"description":"Client key (pk_). Ships inside apps and pages; identifies the project only.","in":"header","name":"X-Go-Key","type":"apiKey"},"ServerKey":{"bearerFormat":"sk_","description":"Server key. Held by the customer's backend. Grants links, metrics, raw events.","scheme":"bearer","type":"http"}}},"info":{"description":"Scoped mobile attribution: links, events, metrics. This document is the source of truth\nfor the HTTP contract; every /v1/ request is validated against it.\n","title":"roiguru-go API","version":"1"},"openapi":"3.0.3","paths":{"/healthz":{"get":{"operationId":"GetHealth","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}},"description":"All dependencies reachable and schema current"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unhealthy"}}},"description":"At least one dependency failing"}},"security":[],"summary":"Liveness and dependency health"}},"/openapi.json":{"get":{"operationId":"GetOpenAPI","responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"The OpenAPI document as JSON"}},"security":[],"summary":"This document"}},"/s.js":{"get":{"operationId":"GetSnippet","responses":{"200":{"content":{"text/javascript":{"schema":{"type":"string"}}},"description":"The minified snippet"},"304":{"description":"Not modified"}},"security":[],"summary":"The web snippet (drop-in tag). Cached one hour; ETag revalidation."}},"/v1/events":{"get":{"operationId":"ListEvents","parameters":[{"$ref":"#/components/parameters/EventsLinkId"},{"$ref":"#/components/parameters/EventsRef"},{"$ref":"#/components/parameters/EventsFrom"},{"$ref":"#/components/parameters/EventsTo"},{"$ref":"#/components/parameters/EventsType"},{"$ref":"#/components/parameters/EventsLimit"},{"$ref":"#/components/parameters/EventsCursor"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventListResponse"}}},"description":"Events in the range, newest first"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ServerKey":[]}],"summary":"Raw events for one link, newest first (server key; for debugging, not analytics)"},"post":{"operationId":"IngestEvents","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventBatchRequest"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventBatchResponse"}}},"description":"Batch evaluated; see accepted and rejected"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ClientKey":[]}],"summary":"Report events (client key); each event is accepted or rejected on its own"}},"/v1/links":{"get":{"operationId":"GetLinkByRef","parameters":[{"in":"query","name":"ref","required":true,"schema":{"maxLength":256,"minLength":1,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Link"}}},"description":"The link"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ServerKey":[]}],"summary":"Fetch a link by the customer's ref"},"post":{"description":"One result per input link, in request order. A link that fails validation carries\n`error` (code `invalid_request`, the `field`, a message) and is not written; the others\nare written in one transaction. `400` is only for the envelope: not a JSON object,\n`links` missing or empty, more than 500 items, or a `ref` repeated within the batch.\nA `gol` parameter already present on a `destination_url` is stripped before storage.\n","operationId":"UpsertLinks","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkUpsertRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkUpsertResponse"}}},"description":"One result per input link, in request order; `failed` counts the items carrying `error`"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ServerKey":[]}],"summary":"Create or update links by ref (batch, idempotent); each link answers for itself"}},"/v1/links/by-token/{token}":{"get":{"description":"Returns only the deep_link payload. The token is public on ads, so nothing else about the link is disclosed.","operationId":"ResolveLink","parameters":[{"in":"path","name":"token","required":true,"schema":{"pattern":"^[0-9A-Za-z]{22}$","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeepLinkResponse"}}},"description":"The link's deep_link payload, or null if none was set"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ClientKey":[]}],"summary":"Deep-link payload for a token (client key)"}},"/v1/links/close":{"post":{"description":"For every active link named, expires_at becomes the earlier of its current value and\nnow plus the project's post-close window, and closed_at is recorded. The token keeps\nresolving until the expiry job runs, so clicks already made can still turn into\ninstalls. A later upsert of the same ref reopens the link with the same token.\nOne result per ref in request order; an expired or deleted link is reported with its\nstatus and left alone; an unknown ref carries error not_found.\n","operationId":"CloseLinks","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkCloseRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkCloseResponse"}}},"description":"One result per ref, in request order"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ServerKey":[]}],"summary":"Tell go these ads stopped; the links expire after the project's post-close window"}},"/v1/links/{id}":{"delete":{"operationId":"DeleteLink","parameters":[{"$ref":"#/components/parameters/LinkID"}],"responses":{"204":{"description":"Deleted (or already deleted)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ServerKey":[]}],"summary":"Mark a link deleted; its token stops resolving, rollups are kept"},"get":{"operationId":"GetLink","parameters":[{"$ref":"#/components/parameters/LinkID"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Link"}}},"description":"The link"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ServerKey":[]}],"summary":"Fetch a link by id"}},"/v1/me":{"get":{"description":"Writes nothing. With a server key the project's settings, the key's id, label and\ncreation time and the batch and rate limits are returned; with a client key only the\nproject's id, name and timezone and the key kind.\n","operationId":"WhoAmI","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyInfo"}}},"description":"The key's project and the key"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ServerKey":[]},{"ClientKey":[]}],"summary":"Describe the key and its project (server or client key)"}},"/v1/metrics":{"get":{"operationId":"GetMetrics","parameters":[{"$ref":"#/components/parameters/MetricsFrom"},{"$ref":"#/components/parameters/MetricsTo"},{"$ref":"#/components/parameters/MetricsTZ"},{"$ref":"#/components/parameters/MetricsGranularity"},{"$ref":"#/components/parameters/MetricsGroupBy"},{"$ref":"#/components/parameters/MetricsType"},{"$ref":"#/components/parameters/MetricsLimit"},{"$ref":"#/components/parameters/MetricsCursor"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsResponse"}}},"description":"Rows ordered by bucket, group, type, name, platform"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ServerKey":[]}],"summary":"Attributed activity per link and bucket, from hourly rollups, in the caller's timezone"}},"/v1/metrics/changes":{"get":{"description":"Every day-grain row whose underlying hourly rollup changed after the position `since`\nnames, with its current absolute values. Store `next_since` after processing a page and\npass it back next time; omit `since` for a full sync. At-least-once: a key may appear\nagain when it changes again or across a page boundary, so upsert by\n(link_id, day, type, name, platform). Rows become visible about 30 seconds after the\nevents that changed them were accepted.\n","operationId":"MetricsChanges","parameters":[{"$ref":"#/components/parameters/MetricsTZ"},{"description":"Opaque cursor from a previous response; absent means from the beginning.","in":"query","name":"since","schema":{"type":"string"}},{"description":"Upper bound on the hourly rollups scanned per page (1-5000, default 1000); the number of day rows returned is at most this.","in":"query","name":"limit","schema":{"default":1000,"maximum":5000,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangesResponse"}}},"description":"Changed day rows ordered by day, link, type, name, platform"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"ServerKey":[]}],"summary":"Change feed of day rows in the caller's timezone (server key); the integration path for collectors"}}},"servers":[{"url":"https://go.roiguru.net"}]}