|

Measurement partners

Affiliate networks, dashboard tools, and analytics platforms can read OA telemetry data on behalf of content owners who grant them access. No proprietary integration - you query the same API content owners use.

If you also need to write events on behalf of content owners (for example, reporting retrievals from a content marketplace, or reporting link_click engagements from a landing page), see the marketplaces and networks guide.

Building a dashboard with AI?

Drop this URL into Claude, ChatGPT, Cursor, or any other LLM:

https://openattribution.org/docs/api.md

That is the full API reference as a single self-contained Markdown file - everything the model needs to scaffold a starter dashboard against your delegated telemetry. Or jump straight in:


How it works

text
Content owner                    Measurement partner
     |                                  |
     |  1. Grants delegation            |
     |  (dashboard or API)              |
     |                                  |
     |                                  |  2. Queries content-owner endpoints
     |                                  |     ?delegated_from={owner_org_id}
     |                                  |
     |           OA gateway             |
     |      checks delegation table     |
     |      returns owner's data        |
     |                                  |

The content owner grants you telemetry:read access via the OA dashboard or API. You authenticate with your own API key and pass delegated_from on content-owner endpoints to access their data.


Getting started

First, set up your platform org
Measurement partners register as platforms - that's the role that holds delegated read access. The platform setup guide covers sign-up, approval, finding your organisation ID, and minting an API key (scope it to telemetry:read here). Then come back for the delegation flow below.

1. A content owner grants you access

The content owner goes to Measurement partners in their OA dashboard and enters your organisation ID (the one from /partners). This creates a delegation - immediately active, revocable at any time.

Alternatively, they can use the API:

json
POST /api/v1/identity/delegations
{
  "grantee_org_id": "your-org-id",
  "scopes": ["telemetry:read"]
}

2. Query their telemetry

Use the same content-owner endpoints, adding your authentication and the delegated_from parameter:

text
GET https://api.openattribution.org/content-owners/summary?delegated_from={grantor_org_id}&since=2026-03-01
X-API-Key: oat_pk_yourkey...

You get the same response a content owner would see - total events, agent breakdown, top URLs. All three content-owner endpoints support delegation: /content-owners/summary, /content-owners/events, and /content-owners/urls. Full request/response shapes are in the API reference.


What you can build

AI traffic dashboards

Show content owners which AI agents are fetching their content, how often, and which URLs. Net-new data that doesn't exist in any affiliate dashboard today.

Attribution models

When citation and outcome data flows, build multi-touch attribution across the content influence chain. Which content was retrieved, cited, and led to a purchase.

Aggregated reporting

Query across all content owners who have granted you access. Build network-wide views of AI agent activity.

Data isolation
Each delegation is a separate grant. You can only access data for content owners who have explicitly granted you access. No cross-content-owner aggregation happens on the OA side - you aggregate across your own delegations.

Managing delegations

List your delegations

text
GET /api/v1/identity/delegations?role=grantee
X-API-Key: oat_pk_yourkey...
json
[
  {
    "id": "...",
    "grantor_org_id": "...",
    "grantee_org_id": "your-org-id",
    "grantor_name": "Wirecutter",
    "grantee_name": "Your Network",
    "scopes": ["telemetry:read"],
    "created_at": "2026-03-24T...",
    "revoked_at": null
  }
]

Use the grantor_org_id from each delegation as the delegated_from parameter when querying content-owner endpoints.


Onboarding content owners at scale

Partners with an existing content-owner base can provision organisations directly, rather than waiting for each owner to sign up and grant access. Provisioning creates the organisation, registers its domains as unverified, creates a delegation back to you (immediately active), and returns an invite URL for the owner to claim their account. Requires an API key with the partner:provision scope and identity:write. Platform admission and trusted-partner provisioning approval are separate decisions.

Partner access and credentials

  1. Request trusted-partner enablement, providing your platform organisation ID and intended onboarding use. Ordinary platform approval does not grant this capability.
  2. After an operator administrator enables your organisation, open API keys, choose custom scopes, and select identity:write and partner:provision. Add identity:read to list delegations and telemetry:read for delegated telemetry reads if this credential needs them.
  3. Copy the newly issued key once and store it securely. Check its returned scope list before provisioning. Default keys and existing keys do not gain new scopes when partner access is enabled.
Partner capability rollout
The gated selector requires the partner-enablement backend update. It appears only when the service confirms the capability through GET /api/v1/identity/api-keys/scopes. If it is absent, contact the operator to confirm both deployment and enablement. On updated services the organisation grant is checked at key creation and on every provisioning call; disabling it blocks provisioning even for previously issued keys.

A 403 naming identity:write means the key lacks identity write permission. A partner:provision scope required response means that scope is absent. An administrator-enablement error means the organisation grant is missing or disabled. Delegated reads separately require an active delegation and a key with telemetry:read.

json
POST /api/v1/identity/organizations/provision
{
  "name": "Wirecutter",
  "admin_email": "[email protected]",
  "domains": ["wirecutter.com"],
  "delegation": { "scopes": ["telemetry:read"] }
}

For bulk onboarding, POST /api/v1/identity/organizations/provision/bulk accepts an array of up to 100 of the same items. Each is processed independently, so one conflict doesn't fail the batch - the response reports per-item status (created, existing, conflict, error) alongside a summary. Provisioning is idempotent: re-submitting an organisation you already provisioned returns it as existing rather than duplicating it. A domain already registered to another organisation returns conflict - that owner is already on OpenAttribution, so file a delegation request instead.

Domain verification and trusted-partner attestation

Explicit evidence required
Approved partners can explicitly attest ownership already established through their own process, with the owner's consent. Existing registrations remain unverified until OA accepts an attestation or ordinary verification succeeds. There is no automatic verification or backfill.

Ordinary verification checks a served .well-known manifest, DNS TXT record, or HTML meta tag. An approved trusted partner that has already established domain ownership through its own process can instead explicitly attest to that ownership and the owner's consent. OA records this as partner_attested, separately from OA's own DNS or website checks. Registering a domain, submitting a host to a Hub, or receiving telemetry does not establish ownership or constitute an attestation.

Use the same administrator-controlled partner approval and a platform key with both identity:write and partner:provision. A telemetry-read delegation alone gives no authority to verify or change identity records. Attestation is limited to content-owner organisations originally provisioned by your platform, with an active delegation back to it. After owner claim, the owner must revoke the old delegation and create a new one with identity:write (and any read scopes they want to retain). A delegation created before claim cannot supply that reauthorisation. Another partner's owner or another owner's registered domain, including overlapping parent domains, subdomains and www aliases, cannot be taken over.

For a new owner, add domain_attestation to the provisioning body (or each bulk item). It applies to every domain listed in that item, so the evidence must cover each one. Omit it to register domains without verifying them. Supply real, non-empty descriptions of the ownership check and owner consent, plus a reference to retained evidence; do not include credentials or private evidence documents in the request. Each field is trimmed and must be between 1 and 2,000 UTF-8 bytes. Domains must be valid DNS hostnames; use Punycode for international names.

json
POST /api/v1/identity/organizations/provision
X-API-Key: oat_pk_your_scoped_partner_key
{
  "name": "Example Publisher",
  "admin_email": "[email protected]",
  "domains": ["example.com", "www.example.com"],
  "domain_attestation": {
    "ownership_basis": "Domain control established through our publisher onboarding check",
    "consent_basis": "Owner authorised OA registration, domain attestation and delegated telemetry access",
    "evidence_reference": "publisher-onboarding/record-123"
  }
}

For an owner you already provisioned, attest its existing domain by ID. This upgrades the existing record without creating another organisation or domain. Use the organisation and domain IDs from your stored provisioning response or an authorised identity domain listing; make a separate request for each domain. The body is the evidence object itself:

json
POST /api/v1/identity/organizations/provision/{organization_id}/domains/{domain_id}/attest
X-API-Key: oat_pk_your_scoped_partner_key
{
  "ownership_basis": "Domain control established through our publisher onboarding check",
  "consent_basis": "Owner authorised OA registration, domain attestation and delegated telemetry access",
  "evidence_reference": "publisher-onboarding/record-123"
}

Once OA accepts the attestation, the verified domain becomes eligible for public resolution and content-owner telemetry queries, subject to the usual visibility settings and read permissions. Attestation creates no telemetry events. See the API reference for response, retry and lifecycle semantics.

Requesting access from owners already on OpenAttribution

The delegation flow in Getting started is owner-initiated - the content owner has to act. For owners who already have an OpenAttribution account, you can initiate instead: file a delegation request keyed by one of their verified domains. The owner sees it in their dashboard and approves or denies it; approval creates the delegation and you're notified (see webhooks below). Requests expire after 30 days, after which you can file a fresh one.

json
POST /api/v1/identity/delegation-requests
{
  "domain": "wirecutter.com",
  "scopes": ["telemetry:read"]
}

The domain must be verified by its owner - an unverified registration is an unproven claim and returns 404. If an active delegation or another pending request already exists for the pair, you get 409. POST /api/v1/identity/delegation-requests/bulk takes an array of up to 100, with per-item statuses (created, not_found, conflict, error) like bulk provisioning. List what you've filed with GET /api/v1/identity/delegation-requests?role=grantee.

Which onboarding path?
Owner not on OpenAttribution yet - provision them; the delegation is created for you. Owner already here - file a delegation request; they approve. Either way, once the delegation exists you query with delegated_from exactly as above.

Webhooks

Rather than polling GET /delegations, register an HTTPS endpoint and OpenAttribution will push identity events to it as they happen. Managing endpoints needs an API key with identity:write; up to 10 active endpoints per organisation.

EventFired whenDelivered to
delegation.createdA delegation is created - directly, at provision time, or via an approved requestBoth orgs
delegation.revokedA delegation is revokedBoth orgs
invite.claimedA content owner you provisioned claims their accountYou
delegation_request.createdA delegation request is filedThe content owner
json
POST /api/v1/identity/webhooks
{
  "url": "https://hooks.yournetwork.example/openattribution",
  "event_types": ["delegation.created", "invite.claimed"]
}

The response includes a signing secret (whsec_...) - it's shown once, in this response only, so store it. Every delivery is a POST with a JSON envelope (id, type, created_at, data) and an X-OA-Signature header: hex HMAC-SHA256 over "{timestamp}.{body}" keyed with your secret, where the timestamp is the X-OA-Timestamp header. Verify it against the raw body with a constant-time comparison before trusting the payload.

Delivery is at-least-once: any 2xx within 10 seconds counts as delivered; failures retry with backoff (1m, 5m, 30m, 2h, then 12h) and give up after 8 attempts. Dedupe on the X-OA-Delivery-Id header. Endpoints must be HTTPS with a hostname (no IP literals or embedded credentials); addresses resolving to private, loopback, or cloud-metadata ranges are refused, and redirects aren't followed. Full header list, envelope shape, and the receiver-side verification steps are in the API reference.

On the roadmap
Telemetry events pushed as they arrive (a webhook firehose for the data itself, not just identity changes) is next. Today's webhooks cover identity events only; telemetry is read via the content-owner endpoints.