Documentation
Publisher integration reference
Pixel (script tag)
One tag on every page where the user is identified. The tag loads from a hostname on your own domain (we give you the DNS record at approval), so it is not blocked as a third-party tracker. You render the SHA-256 of the user's email into the tag; raw addresses never leave your site.
<script async src="https://cc.<your-domain>.com/v1/cc.js" data-property-id="<your property id>" data-hashed-email="<server-rendered: sha256 of the lowercased+trimmed user email>" data-endpoint="https://cc.<your-domain>.com/p/v1/collect" data-job-title="<job title on this page>" <!-- optional: feeds interest data --> data-company="<employer on this page>" <!-- optional --> data-policy-version="v1" <!-- optional --> data-disclosure-tier="standard" <!-- optional --> ></script>
- The hash rule is
sha256_hex(email.strip().lower()), 64 lowercase hex characters, no other transformation. - Pages without a known user can carry the tag with the hashed-email attribute empty; they are not counted.
- Add
data-job-titleanddata-companyon job pages and search results to qualify for interest data (occupations and employers per user).
Google Tag Manager
The pixel works in Tag Manager as-is. Three things matter:
- Add it as a Custom HTML tag (not a sandboxed custom template), fired on All Pages.
- Push the hashed email into the data layer on logged-in page loads, for example
dataLayer.push({ cc_hashed_email: "<sha256>" }), and read it in the tag through a Data Layer Variable. - Hash on your server before the push. The pixel never hashes and never sees a raw address.
Server-to-server events
For events you only know about server-side, or sites that prefer not to run a tag: one HTTPS POST per event. Your key is issued per property at approval and shown once.
POST https://ingest.coverclicks.com/s2s/v1/events
Authorization: Bearer <your property API key>
Content-Type: application/json
{
"property_id": "<your property id>",
"hashed_email": "<sha256 hex of lowercased+trimmed email>",
"url": "https://your-site/jobs/12345",
"event_type": "page_view",
"external_id": "your_user_42",
"user_ip": "203.0.113.9",
"partner_extras": { "job_title": "Registered Nurse", "company": "Acme Health" }
}- property_id
- Required. Your property id, assigned at approval.
- hashed_email
- Required. SHA-256 hex (64 chars) of the lowercased, trimmed email. Hash on your server.
- url
- Required. Page URL the event happened on. Known personal-data query parameters are stripped on our side.
- event_type
- page_view (default), form_submit, click, auth or transaction.
- external_id
- Your own user id, stored as-is.
- event_id
- Your unique id for this event, so retries can be de-duplicated.
- hashed_phone
- SHA-256 hex of the E.164-normalized phone.
- user_ip
- The end user's IP. Used only to derive a US zip code at ingest, then discarded; never stored.
- partner_extras
- Any extra JSON (64 KB max). Two keys feed interest data: job_title (the job viewed or searched) and company (the employer).
- consent_metadata
- Object with optional policy_version and disclosure_tier.
- page_title, meta_description, referrer
- Optional page context, sanitized the same way as url.
- privacy_policy_url
- Your privacy policy URL, kept verbatim.
- sdk_version
- Your integration's version label, for our analytics.
200accepted, body{"status":"ok","message_id":"..."}.400malformed property id.401key missing or not registered to that property.413partner_extras over 64 KB.422missing required field, wrong type, or an unknown field.- Retry other failures with backoff. Duplicates are accepted; send
event_idso they can be collapsed.
Runnable samples in Python, Node and PHP (standard library only, about 40 lines each) are on each property page of your dashboard.
Profile lookup API
Ask, for any hashed email, which occupations and employers the rest of the network has seen that person interested in. Your own contributions are removed before ranking, so you only ever learn something new. Available to publishers who contribute job-title or company data; email support to have it switched on.
curl https://portal.coverclicks.com/api/publisher/v1/profile/lookup \
-H "X-Property-Id: <your property id>" \
-H "Authorization: Bearer <your property API key>" \
-H "Content-Type: application/json" \
-d '{"hashed_email": "5d41402abc4b2a76b9719d911017c592a3b7e1f0c9d8e7f6a5b4c3d2e1f00a1b"}'
{
"results": [
{
"hashed_email": "5d41402a...0a1b",
"found": true,
"status": "match",
"occupations": [
{ "title": "Registered Nurse", "soc": "29-1141" },
{ "title": "Licensed Practical Nurse", "soc": "29-2061" }
],
"employers": [ { "name": "HCA Healthcare" } ]
}
],
"credits": { "used": 41, "allotted": 1200, "remaining": 1159 }
}- Up to 100 hashes per request, 3,000 requests per minute. Results in the order asked.
- Each match uses 1 credit from your monthly credits; a lookup that finds nothing is free.
- Data covers the last 90 days and refreshes once a day around 11:00 UTC. We never return raw emails, hit counts or source names.
Opt-outs
Anyone can opt out of the whole network at portal.coverclicks.com/opt-out. Opt-outs apply across every publisher and buyer at once. Your dashboard also lets you block specific buyers. How consent is described to users and recorded on every signal is on the Trust page.
