{"openapi":"3.0.3","info":{"title":"COKIQ API","version":"1.0.0","description":"Public REST API for COKIQ consent-management workspaces: sites, consent logs, scans, cookie rules and webhooks. Authenticate with a workspace API key (Dashboard → Security → API keys). Required scopes per endpoint are listed in the docs. Free plan: 100 calls/day and 50 webhook deliveries/day; paid plans are higher. Over the cap the API returns 429 with an upgrade_url. Consent data is privacy-sensitive: responses and webhooks never include raw IP addresses, user agents or other visitor PII; visitor_hash is a salted, truncated hash that cannot be reversed.","contact":{"name":"COKIQ support","email":"support@cokiq.com","url":"https://cokiq.com/contact"},"termsOfService":"https://cokiq.com/legal/terms"},"servers":[{"url":"https://cokiq.com/api/v1"}],"security":[{"bearerAuth":[]},{"apiKeyAuth":[]}],"tags":[{"name":"Account"},{"name":"Sites"},{"name":"Consent"},{"name":"Scans"},{"name":"Cookies"},{"name":"Webhooks"}],"paths":{"/me":{"get":{"tags":["Account"],"operationId":"getMe","summary":"Current workspace and key (connection test)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sites":{"get":{"tags":["Sites"],"operationId":"listSites","summary":"List sites (newest first)","description":"Scope: sites:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"description":"Page size (max 100)."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from next_cursor."},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only items created after this time (polling)."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Site"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Sites"],"operationId":"createSite","summary":"Add a site (domain)","description":"Scope: sites:write. Subject to the plan site limit (403 plan_limit_reached with upgrade_url).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Domain exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sites/{id}":{"get":{"tags":["Sites"],"operationId":"getSite","summary":"Get a site","description":"Scope: sites:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sites/{id}/scans":{"post":{"tags":["Scans"],"operationId":"startScan","summary":"Start a cookie scan for a site and return the result","description":"Scope: scans:write. Free plan: 5 scans/day.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Scan completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Scan"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/scans":{"get":{"tags":["Scans"],"operationId":"listScans","summary":"List scans (newest first)","description":"Scope: sites:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"description":"Page size (max 100)."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from next_cursor."},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only items created after this time (polling)."},{"name":"site_id","in":"query","schema":{"type":"string"},"description":"Filter by site id."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Scan"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/consent-logs":{"get":{"tags":["Consent"],"operationId":"listConsentLogs","summary":"List consent logs (newest first)","description":"Scope: consent:read. No raw IP or user agent is returned.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"description":"Page size (max 100)."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from next_cursor."},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only items created after this time (polling)."},{"name":"site_id","in":"query","schema":{"type":"string"},"description":"Filter by site id."},{"name":"until","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ConsentLog"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/consent-logs/export":{"post":{"tags":["Consent"],"operationId":"exportConsentLogs","summary":"Export consent logs (JSON rows or CSV text, max 5000 rows)","description":"Scope: consent:read","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentExport"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentExportResult"}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Site not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/cookie-rules":{"post":{"tags":["Cookies"],"operationId":"createCookieRule","summary":"Create a cookie rule (classify a cookie) for a site","description":"Scope: cookies:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CookieRuleCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CookieRule"}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Site not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/hooks":{"get":{"tags":["Webhooks"],"operationId":"listHooks","summary":"List webhook subscriptions","description":"Scope: hooks:manage","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Hook"}},"events":{"type":"array","items":{"type":"string"}}}}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Webhooks"],"operationId":"subscribeHook","summary":"Subscribe a REST hook (Zapier / Make / Pabbly)","description":"Scope: hooks:manage. https only; private and internal hosts are refused. Returns the signing secret once. Deliveries are signed: Cokiq-Signature: t=<unix>,v1=HMAC_SHA256(secret, \"<t>.<body>\"). Failed deliveries retry 3 times; HTTP 410 unsubscribes automatically.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["event","target_url"],"properties":{"event":{"type":"string","enum":["consent.logged","scan.completed","banner.published","site.created"]},"target_url":{"type":"string","format":"uri"}}}}}},"responses":{"201":{"description":"Subscribed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Hook"}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/hooks/{id}":{"delete":{"tags":["Webhooks"],"operationId":"unsubscribeHook","summary":"Unsubscribe a REST hook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/hooks/sample":{"get":{"tags":["Webhooks"],"operationId":"hookSample","summary":"Sample payload for an event (used by Zapier/Make for field mapping)","parameters":[{"name":"event","in":"query","required":true,"schema":{"type":"string","enum":["consent.logged","scan.completed","banner.published","site.created"]}}],"responses":{"200":{"description":"Array with one sample object","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}},"400":{"description":"Invalid event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit or freemium quota reached (includes upgrade_url on the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Authorization: Bearer <key>"},"apiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"upgrade_url":{"type":"string","format":"uri"},"retry_after":{"type":"integer"}}}}},"Me":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"Workspace name (connection label)"},"email":{"type":"string","nullable":true},"workspace":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"plan":{"type":"object","properties":{"id":{"type":"string"},"free":{"type":"boolean"}}},"scopes":{"type":"array","items":{"type":"string"}},"limits":{"type":"object"}}},"Site":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"site_key":{"type":"string"},"status":{"type":"string"},"compliance_score":{"type":"number"},"total_consents":{"type":"integer"},"region":{"type":"string"},"banner_version":{"type":"string","nullable":true},"banner_published_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"SiteCreate":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","example":"example.com"},"region":{"type":"string","default":"global"}}},"ConsentLog":{"type":"object","properties":{"id":{"type":"string"},"site_id":{"type":"string"},"domain":{"type":"string"},"consent_type":{"type":"string","enum":["accept_all","reject_all","custom"]},"categories":{"type":"array","items":{"type":"string"}},"country":{"type":"string"},"visitor_hash":{"type":"string","description":"Salted, truncated hash. Not reversible; never an IP."},"created_at":{"type":"string","format":"date-time"}}},"ConsentExport":{"type":"object","properties":{"site_id":{"type":"string"},"since":{"type":"string","format":"date-time"},"until":{"type":"string","format":"date-time"},"format":{"type":"string","enum":["json","csv"],"default":"json"}}},"ConsentExportResult":{"type":"object","properties":{"count":{"type":"integer"},"truncated":{"type":"boolean"},"format":{"type":"string"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/ConsentLog"}},"csv":{"type":"string"}}},"Scan":{"type":"object","properties":{"id":{"type":"string"},"site_id":{"type":"string"},"domain":{"type":"string"},"health_score":{"type":"number"},"risk_score":{"type":"number"},"risk_level":{"type":"string"},"summary":{"type":"string"},"scan_type":{"type":"string"},"scanned_at":{"type":"string","format":"date-time"}}},"CookieRuleCreate":{"type":"object","required":["site_id","name"],"properties":{"site_id":{"type":"string"},"name":{"type":"string"},"category":{"type":"string","enum":["Necessary","Analytics","Marketing","Preferences"],"default":"Necessary"},"domain":{"type":"string"},"duration":{"type":"string"},"description":{"type":"string"}}},"CookieRule":{"type":"object","properties":{"id":{"type":"string"},"site_id":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"domain":{"type":"string"},"duration":{"type":"string"},"description":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}},"Hook":{"type":"object","properties":{"id":{"type":"string"},"event":{"type":"string","enum":["consent.logged","scan.completed","banner.published","site.created"]},"target_url":{"type":"string"},"active":{"type":"boolean"},"secret":{"type":"string","description":"Only on creation."},"created_at":{"type":"string","format":"date-time"}}}}}}