Content owners and usage reports
Use Onward delivery to see where your edges’ usage goes, and Content owners, linked from it, to register publishers, download their usage reports and save destinations for them. The hub holds no content-owner accounts and opens no owner-facing view. Only members of your organisation use these screens.
Registering an owner
Section titled “Registering an owner”Under Register an owner, enter its name and optionally its first host and the basis for the registration, then choose Register owner. Open the owner to add or remove hosts. Adding or removing a host and deleting an owner need an organisation owner. A host another owner already holds is refused without changing its registration.
The basis is recorded, unverified, and included as typed in reports handed to the owner. Do not enter anything there you would not send them. Hosts have no scheme or path. An exact host registration takes precedence; otherwise a registration of its immediate parent can claim it, as described under Host resolution.
Delete owner requires the owner’s exact name. It deletes registrations, the destination and credential, and the records of deliveries to the saved destination. Records of deliveries to endpoints the sources declared are kept. Events stay and become unattributed.
The report
Section titled “The report”Open an owner and read Report. It shows retrieved and grounded counts, first and last event times, session count, enrolled edge key ids, licence references and per-URL counts. The resolution rule and URL limit appear above it. A dash for sessions means deletion has made that count unknown.
Download JSON saves the API’s report unchanged. It contains no wire session identifier, engagement or another owner’s URLs. Give this file to the content owner under your agreement. Enrolled edge key ids are pseudonymous identifiers the owner can match to signed requests; host tool names are omitted.
Unattributed hosts
Section titled “Unattributed hosts”Open Unattributed hosts from Content owners. The list contains the 50 hosts with the most unclaimed events, with counts and last event times. Choose an existing owner or name a new one, enter the basis and select Register. The registration claims existing matching events as well as future ones in reports. Onward delivery sends only events from the registration onward (see Onward delivery).
Onward delivery
Section titled “Onward delivery”Usage goes to each publisher’s declared endpoint whether or not you register an owner for it.
Onward delivery, in the Network group, shows every destination:
- Where usage goes: each endpoint a licence or a host manifest declared, with the declarations that named it, its host and event counts (and how many of those events had no registered owner), queued, delivered and dead counts, what was held (suppressed, or withheld because a licence named it from another site), the last delivery, the next attempt and the latest error; then each destination saved for an owner. The count of events still awaiting their declarations is at the top. The page reads the saved destinations of the first 20 owners by name; the others are on each owner’s delivery page, and an owner whose status could not be read shows on its own row.
- Hosts read: each host manifest read, with its outcome, the status the
host answered, the reason and when the read expires, and each licence
resolution. A publisher whose CDN challenged the hub’s reader shows here as
refusedwith the reasonchallenge. - Suppressed endpoints: each stopped origin, who stopped it and why. Owners can suppress an endpoint and lift a suppression here.
- Dead letters: up to 50 declared-endpoint deliveries that failed ten times. Owners can requeue them all.
Each list shows up to 50 entries and says so when it is full. URLs, hosts,
reasons and errors come from licences, manifests and receivers and are shown
as text. A manifest or licence reason or a delivery error the hub records is
cut to 512 bytes; an owner’s suppression reason is not, and nor are entries
recorded before the hub applied the cut. A declared endpoint longer than
2,048 bytes is not used: its manifest read or licence is listed invalid with
that reason. A licence whose telemetry reporting profile is longer than 512
bytes is listed not_rsl with that reason and routes no events. Any member
can read the page; the actions are an owner’s. Support acting as an owner
can suppress an endpoint; lifting a suppression and requeueing are refused,
and the page shows the refusal.
Open a content owner, then Onward delivery. The destination lists its URL, set time and whether a credential was provided. The credential is never returned. Any signed-in member can read status; only an organisation owner can save a destination or requeue dead letters.
Enter the public HTTPS endpoint designated by the content owner and, if
required, its consumer credential. Save destination stores the credential
encrypted, sends it as X-API-Key, queues the raw events the owner is owed
(below) and requeues all dead letters. Enter the credential again whenever saving; a blank field
removes the stored credential. The hub refuses private addresses. An unresolved
hostname can be saved, but must pass the address check before delivery.
Onward batches include wire session and agent identifiers, event URLs and
the event data the edge sent. This differs from the downloadable report’s
omissions. Citations (content_cited: an agent’s answer named the page)
are delivered with their output_id, which groups the citations of one
answer. Turn boundaries and session refused counts are not delivered onward.
The hub forwards terms_ref separately from license_ref without interpreting
the terms reference. An HTTPS license_ref can supply the reporting endpoint
below. Duplicate events keep the first accepted values.
Every event goes to every route that applies to it, not to one of them:
- Each endpoint the event’s source declared: the public HTTPS endpoint in
its RSL licence
<reporting type="telemetry" profile="…" endpoint="…">binding, and the endpoint its host declares in its Content Telemetry manifest. Two declarations naming one endpoint deliver once. - The destination you saved on the owner’s registration.
A declared endpoint is delivered to whether or not you registered an owner for
the host, and a destination you save adds to it rather than replacing it. A
declared endpoint is sent no credential: it is the source’s own designation,
and only the saved destination uses the credential you stored. terms_ref
never chooses a route.
A licence’s endpoint takes only the events of hosts under the licence
document’s own registrable domain: a licence many publishers cite would
otherwise send every publisher’s URLs to the endpoint its author declared.
The registrable domain is read from the Public Suffix List, compiled into the
hub: a licence at
licences.example.com takes the events of www.example.com, one at
www.example.com those of example.com, and one at example.com those of
a.b.example.com, but one at attacker.co.uk never takes the events of
bbc.co.uk, since the two share only the public suffix co.uk. A host the
list does not cover (an IP address, a name under an unlisted top-level label)
is compared exactly. An event routed away from its registrable domain this way
is recorded at that endpoint as withheld, with the reason
endpoint_off_origin, and is not sent, unless the host’s own manifest names
the same URL. A later declaration of that URL from the event’s own origin
releases it. A manifest carries no such test: it is the host’s own
declaration for its own events. This guard uses the suffix list;
Host resolution, which attributes events to owners you
registered, does not.
The hub reads a licence once per distinct reference in your organisation, and a host’s manifest once per host, caching a usable endpoint for 24 hours and an unsuccessful result for one hour. It records the profile, endpoint, outcome and reason. Missing endpoints, failed reads, private addresses and ambiguous reporting bindings supply no route. The hub does not interpret profile-specific configuration or obtain a consumer credential from a licence or a manifest. Where nothing is declared and no destination is saved, the event remains stored and undelivered.
An event’s declared endpoints are fixed once, from the declarations in force
when it arrived: as it is ingested where the licence and the manifest are
already read, otherwise once the hub has read them. Each route settles on its
own read, so an unreachable manifest does not hold back the licence’s
endpoint. A licence read that could not connect or complete, or whose
endpoint did not resolve, and a manifest read that was unreachable or
answered 401, 403, a redirect, 429 or 5xx, are retried about hourly for 24
hours after the event arrived; any other answer is final. A 401 or 403 from a
bot-protection service is recorded as refused with the reason challenge,
and a redirect as redirect to its origin; the hub does not follow
redirects, because a manifest must be served from the URL it names. The event is then fixed with what was read. A licence or manifest that names
a new endpoint later takes the events that arrive after it, never earlier
ones, so a host that changes hands does not pass the previous holder’s record
to the new one.
Saving a destination changes future claims of the saved route only. A batch already being sent can finish at the previous endpoint. Completed deliveries keep their original route and are not sent again to the new one.
Delivery status covers every route owed on this owner’s events, declared endpoints included: complete queued, delivered and dead counts, the last delivery, next attempt and latest error. Refresh status loads current values. Routes gives counts by route and endpoint; one event can appear under several, since the routes add to each other. Attempted events show their last route; events awaiting their first attempt show their current route. Recent batches lists up to 50 batches, with their route, destination, status, event count, the count the receiver created (unknown when its answer did not state one) and attempt time. Retried events move to the new batch. Licence resolutions lists up to 50 recent outcomes and their cache expiry.
Dead letters lists up to 50 events with their URLs, attempt counts and last errors. After fixing the cause, Requeue all dead letters gives every dead letter a fresh attempt budget, including those outside the displayed list. Saving a destination does the same. Failed attempts retry after 1, 2, 4, 8, 16 and 32 minutes, then hourly; the tenth failure becomes a dead letter.
Back-fill lists the owner’s back-fills. An owner can back-fill a range of events there, with times in UTC (Onward delivery API explains what a back-fill sends); support acting as an owner is refused.
Clearing the destination is available through the API. Clearing it records the person making the change in the audit log, pauses the saved route and drops its queued and dead records, except batches already in flight. Those can finish; their records and completed delivery records stay. Saving a destination resumes the saved route. Endpoints the sources declared are not paused by clearing: they are the sources’ own designations, not yours to withdraw. What reaches the hub at all is what your edges’ policy and reporting approvals clear. Raw events deleted under retention cannot be delivered onward.
API reference
Section titled “API reference”Requests use the organisation resolved from the signed-in session or an appropriately scoped API key. Destination changes and retry require an owner session; API keys cannot perform them.
Host resolution
Section titled “Host resolution”Hosts are spelled the way events carry them: lower-case, no scheme or
path, port kept. An event resolves to the owner of its exact host first;
where no owner registered that host, to the owner of its parent, the
host with its first label removed (www.example.com resolves to a
registration of example.com, news.example.co.uk to one of
example.co.uk). One level only, never for a two-label host, and with no
list of public suffixes: the parent of bbc.co.uk is co.uk, which
nobody registers, so a three-label host under such a suffix is registered
exactly and its own subdomains resolve to it. An exact registration by
one owner beats a parent registration by another, so example.com cannot
claim a subdomain someone else registered. Registering the apex covers
the www. and section hosts an ownership map usually omits; register a
host exactly where the parent rule would give it to the wrong owner.
Within your organisation one host is registered to at most one owner.
Owner registration API
Section titled “Owner registration API”curl -X POST https://hub.example/api/v1/owners \ -H 'content-type: application/json' \ -d '{"name": "Example Press"}'
curl -X POST https://hub.example/api/v1/owners/{id}/hosts \ -H 'content-type: application/json' \ -d '{"host": "news.example.com", "basis": "licence agreement ref EP-1"}'GET /api/v1/owners is the listing the screen shows.
DELETE /api/v1/owners/{id}/hosts/{host} removes a registration.
DELETE /api/v1/owners/{id} removes the owner with the same cascade and
asks for no confirmation. Registering a host another owner holds answers
409.
Removing an owner records who removed it, the destination origin and the counts of delivered and undelivered rows deleted with it. If that audit record cannot be saved, the removal fails and the owner stays.
Owner report API
Section titled “Owner report API”GET /api/v1/owners/{id}/report answers with owner, resolution, hosts
with each basis, content_retrieved, content_grounded, sessions,
agent_ids, first_event_at, last_event_at, license_refs, url_limit
and urls. sessions is null once deletion has removed a session from any
of the owner’s events. Counts include retained aggregates.
Unattributed hosts API
Section titled “Unattributed hosts API”GET /api/v1/telemetry/unattributed lists content_host, events and
last_seen_at for the 50 hosts with the most unclaimed events.
Onward delivery API
Section titled “Onward delivery API”An owner that runs or designates a telemetry consumer can receive its events directly, as they arrive, instead of a report. The routes follow the per-event rule above: each endpoint the source declared, and the destination you save. Set a destination yourself, or leave the hub to deliver to what the licence and the host’s manifest declare.
Each delivered event keeps its optional terms_ref, the reference to its
governing terms, separately from license_ref, the reference to its grant.
The hub forwards terms_ref as supplied and does not interpret it or use
it to select a destination. It can resolve license_ref for routing. Events
received without a reference carry none onward. A duplicate event keeps the
first accepted value.
Setting the destination yourself
Section titled “Setting the destination yourself”Set the destination directly when the owner names a consumer outside
its manifest or when the consumer issued you a credential. A saved
destination adds a route beside the endpoints a licence or manifest
declares; it replaces neither. Only an owner of your
organisation can set it, with PUT /api/v1/owners/{id}/destination
and a JSON body:
{ "url": "https://consumer.example/api/v1/telemetry/events", "credential": "…" }The URL must be https, with no userinfo or fragment, at most 2,048 bytes
once percent-encoded, and its host must resolve to public addresses.
A host that resolves to an address that is not public is refused with a
400 naming the address: resolves to 10.0.0.8, which is not a public address. Not public means private, loopback, link-local, shared
(100.64.0.0/10), multicast, reserved, unspecified or documentation
ranges, and the IPv6 forms that carry such an IPv4 address (mapped,
compatible, NAT64 and 6to4); in IPv6, only global unicast outside Teredo
and the documentation prefixes counts. A name that does not resolve yet
is accepted. The credential is stored encrypted, sent as
X-API-Key, and never shown again. The destination stands until you
change or clear it.
An owner is sent only the events that occurred while it held their host: from its registration of that host until the registration is removed. An event’s time is the one the edge recorded, or the time the hub received it if that is earlier. Setting a destination queues the events the owner is owed and has not been sent; every later event is queued as it is ingested. Events from before the owner registered a host are not sent, including events of an owner that held the host before it, so a host that changes hands does not pass the previous holder’s record to the new one. Removing a host stops new events for it; events that occurred while the owner held it are still delivered, unless you clear the destination or delete the owner.
To send an owner earlier events, back-fill a range with
POST /api/v1/owners/{id}/delivery/backfill and a JSON body:
{ "from": "2026-09-01T00:00:00Z", "until": "2026-09-15T00:00:00Z" }A back-fill queues, once, the events in that range, from from up to but
not including until, whose hosts the owner holds at that moment, whoever
held them when the events occurred. It is an act, not a standing rule: a
host you register for the owner later brings none of its earlier events
unless you back-fill again. Events already owed to the owner are left as
they are. The rows are queued on the owner’s saved destination whether or
not it has one yet, and are sent once it has one. A back-fill does not send
anything to the endpoints a licence or manifest declares: those are fixed
from each event’s own declarations when it arrived. Clearing the
destination drops back-filled rows not yet sent, and the back-fill’s record
counts them as dropped; saving a destination again does not bring them
back, so back-fill again if you want them. until must be later than
from and not in the future. The answer
gives the back-fill’s id, the hosts it covered, the number of events
queued, and under held_by_others how many of those were owed, when
they occurred, to another owner (through the exact host or its parent) and
which owners those were: a back-fill
across a hand-over sends the previous holder’s events to this owner’s
receiver, so check that count before you rely on it. Only an organisation
owner can back-fill, not while a super admin acts as someone, and each
back-fill is recorded in the audit log with the same detail.
The worker checks for delivery every fifteen seconds; licence reads and a
backlog can delay an attempt. It sends Content Telemetry event_batch
documents of up to 500 events: for the saved destination, grouped by
session; for a declared endpoint, by session and content host, so one
host’s endpoint never receives another host’s events. Deliveries are not
signed, so an endpoint that requires a signature refuses them and they
become dead letters. The hub builds each document from what it stored of the
edge’s delivery: the session’s identifier, agent id and start time, and
each event’s id, type, time, source role, URL, licence, its data
object as the edge sent it (which carries the supplier field and can
name the tool the agent ran in), and the content_telemetry_id of the
fetch’s Content-Telemetry-ID header where the edge sent one, so the
consumer can match the event to the request the owner’s servers logged.
On a retrieval sent under a positive Crawl-delay, the edge includes
data.commonmeasure-crawl-delay.delay_ms: the delay it kept, in integer
milliseconds, at most 60,000. The Hub forwards it unchanged to that content
owner. It is absent for a zero delay or a crossing sent without a delay.
The session’s refused count is not sent. Any 2xx answer is an
acceptance, with or without a body. When the answer is JSON with
events_created, the hub records that count against the batch;
otherwise the count is unknown, never 0. Any other status is a failure.
A URL that answers 2xx to any request, such as a web page, is taken as
accepting, so check a destination’s URL before relying on its delivered
count. A failed attempt is
retried after 1, 2, 4, 8, 16 and 32 minutes, then hourly; the tenth
failure dead-letters the delivery, which stops retrying and keeps its
last error.
Each delivery resolves the destination’s host again and connects only
to the addresses it resolved. If any of them is not public, however the
destination was set, the hub sends nothing and records a failed attempt
whose error begins destination refused: and names the address. A
name that takes longer than 30 seconds to resolve is a failed attempt
too. The hub is never a route into a private network.
GET /api/v1/owners/{id}/delivery shows the destination and its
source, paused, backfills with each range,
its hosts, the counts it queued and when it was made, licences with their resolution
outcomes and cache expiry, routes with counts by route and endpoint, and
batches with the latest attempted batches, each delivered batch with the
events_created its receiver stated or null when it stated none. batch_limit and licence_limit
state the list bounds. It also shows the complete counts
of queued, delivered and dead deliveries, the last delivery time, the
next attempt time, the most recent error, and the dead letters
themselves, each with its URL, attempt count and last error (bounded;
dead_letter_limit states the bound). POST /api/v1/owners/{id}/delivery/retry requeues the dead letters with a
fresh attempt budget; setting the destination again does the same.
DELETE /api/v1/owners/{id}/destination stops the saved route and drops what
it still owed; what was delivered stays recorded, and declared endpoints go on
receiving events.
Deliveries to declared endpoints, whether or not an owner is registered for
their hosts, are read with GET /api/v1/onward/declared (a signed-in member
or a telemetry:read key):
curl https://hub.example/api/v1/onward/declaredIt answers each endpoint with the declarations that named it (routes), the
number of hosts and events it serves, how many of those events had no
registered owner, complete queued, delivered, dead, suppressed and withheld
counts with the reasons anything was held (withheld_reasons), the last
delivery, the next attempt and the latest error; then the dead letters, the
recent batches (with events_created as on the owner’s answer), the suppressed endpoints, the latest host manifest reads and
licence resolutions, each bounded by limit; and awaiting_declarations, the
number of events whose licence or host manifest the hub has not read yet.
POST /api/v1/onward/declared/retry gives every declared dead letter a fresh
attempt budget (a signed-in owner). Requeueing an owner’s dead letters does
the same for the declared endpoints of the events that owner held. Neither
requeues a dead letter at a suppressed endpoint.
Stopping a declared endpoint. A source’s declaration is the source’s, and
the hub cannot edit it; what you can do is refuse to deliver to it. POST /api/v1/onward/declared/suppressions with {"url": "…", "reason": "…"} (a
signed-in owner) stops every declared route to that URL’s origin, whatever
declares it — the stop for a hostile endpoint, or for one a compromised
licence document or manifest names. Nothing is dropped in silence: what was
queued there becomes suppressed, is counted on the endpoint and against the
owner’s routes, and returns to the queue with a fresh attempt budget when
DELETE /api/v1/onward/declared/suppressions with {"url": "…"} (any URL at
that origin) lifts the stop. Suppressing is allowed under impersonation, since
it stops data leaving; lifting one is not.
- A stop covers the endpoint’s origin: its scheme, host and port, read as
delivery reads them (case, a default port and a trailing dot on the host
ignored). The party that declares an endpoint controls its paths and
queries; a stop on one exact URL would last only until its licence document
or manifest named
/events/,/events?v=2or/v2. The answer names the origin indestination_origin. Another host, a subdomain included, is another origin: stop each one. - Any http or https URL may be given, so an origin can be stopped before
anything names it. A URL with no host is refused with
400. - A batch already on its way when the stop lands is not recalled. The answer
counts it as
in_flightbesideheld; if the endpoint accepts it, those rows readdelivered. - An origin already stopped keeps the URL, reason and name of the stop that
made it. A second request holds whatever has been queued there since and
answers
"already_suppressed": truewith the reason in force, not the one it offered; both requests are in the audit log. To change the reason, lift the stop and make it again. - The stop list (
suppressionsin the status answer) names who made each stop insuppressed_by. Where support made it while acting as one of your people,acted_asnames that person: the stop is support’s act, made in their name, and only you can lift it. - It stops declared routes only. A destination you saved for an owner at the
same URL is your own route and keeps delivering until you clear it
(
DELETE /api/v1/owners/{id}/destination) or delete the owner.
curl -X POST https://hub.example/api/v1/onward/declared/suppressions \ -H 'content-type: application/json' \ -d '{"url": "https://receiver.example/events", "reason": "endpoint not the publisher's"}'GET /api/v1/onward/events/{event_id} answers every route one event is owed
— each saved route (kind saved) and each declared endpoint (kind
declared) — with its destination, state, attempts, last error and batch,
and whether the event is still awaiting its declarations.
A batch the receiver recorded but whose answer the hub did not receive is sent again with the same event ids. A receiver that deduplicates on event id, as this hub’s own receiver does, counts it once.
The Onward delivery screens render this status and post suppressions, lifts, retries and back-fills through these endpoints.
Access
Section titled “Access”The Onward delivery, Content owners, owner and unattributed hosts screens are open to every signed-in member of your organisation.
Registering an owner needs a signed-in member or an identity:write key;
adding or removing a host and deleting an owner need a signed-in owner.
Reports, the unattributed listing, the delivery status,
the declared-endpoint status and an event’s routes need a signed-in member or
a telemetry:read key. Setting or
clearing a destination and back-filling need a signed-in owner. Requeueing dead letters requires a signed-in owner. An ingest key can deliver
events and nothing else.
Measuring access to sites you own
Section titled “Measuring access to sites you own”Registering an owner here groups matching events delivered by your organisation’s Common Measure edges. To receive reports from other agents that use a public site you own, declare where they should report:
- Publish a Content Telemetry manifest at
https://<host>/.well-known/content-telemetry.json, or a telemetry reporting binding in the site’s RSL licence, naming the endpoint of the consumer you choose. Any consumer that conforms to Content Telemetry v1.0 can receive the reports. Participating agents deliver their own evidence there; this hub delivers there every event about your site that its organisations’ edges release (§Onward delivery). - Your organisation can be that consumer: a receiver gives a URL to declare, and Received reports shows what other parties’ agents report to it, unverified and apart from your fleet evidence.
- A site-side collector, at your server or CDN, observes requests that do not
report themselves. It sends
content_retrievedevents withsource_role: edgeto your consumer under the credential that consumer issues. A hub key does not work for it; a receiver takes its events only in batches the hub’s ingest accepts (Received reports).
The manifest and a collector serve separate purposes: publishing the manifest installs no collection, and a collector’s observations do not establish grounding or citation. Detection depends on the signals an agent exposes and does not identify every automated request. Inspect collected events with your consumer. The hub’s owner report counts only the events your fleet delivered. Neither route reports intranet or private-source activity.