Sources

Manage data collection sources. Create, list, update, and delete sources in your Ours Privacy account, including pixel tokens and install scripts.

Manage data collection sources. Create, list, update, and delete sources in your account.

Where this fits in the dispatch flow

Sources are the entry point:

Configuration changes at any stage take effect once you publish a new version.

Events leave a source and are evaluated against Allowed Events (does the event name match an allow-list entry?), then Data Governance (do any consent rules stop dispatch?), then per-destination Mappings (which fields go where?), before reaching the configured destinations.

Listing sources

GET /rest/v1/sources returns a cursor-paginated list. Use limit (default 25, max 100) and cursor for pagination. Filter the list with:

  • type — filter to a specific source type (e.g. Webhook, WebSource, Formstack)
  • status — filter by status (Enabled or Disabled)
  • nameContains — case-insensitive substring match on the source name

Results are sorted by creation date descending (newest first).

New response fields

Every source response now includes operational fields that are useful for debugging:

  • isPublished — whether this source is included in the currently published version. An unpublished source does not accept inbound events.
  • lastTriggeredAt — ISO-8601 timestamp of the most recent inbound request. Use this to confirm that your webhook or pixel is reaching the platform.
  • lastDispatchedAt — ISO-8601 timestamp of the most recent successful event dispatch from this source.
  • accountId — the organization id that owns this source.

PATCH semantics

PATCH /rest/v1/sources/{id} is a partial update. Fields you omit are left unchanged. Send explicit null to clear a nullable field (e.g. "redirectUrl": null). No field is required — a rename-only PATCH ({ "name": "New name" }) is valid. The response returns the full source entity after the update.

Source tokens (/tokens)

GET /rest/v1/sources/{id}/tokens returns different shapes depending on the source type:

Pixel sources (WebSource, PixelImage, HTTPApiSource, and similar) return:

{
  "sourceType": "pixel",
  "token": "...",
  "testToken": "...",
  "installScript": "<script>...</script>",
  "testInstallScript": "<script>...</script>"
}

Webhook sources (Webhook, CallRail, Formstack, Healthie, TypeformWebhooks, JotFormWebhooks, CalendlyWebhook, WhatConverts, HubspotAppActions, and all other *Webhook types) return:

{
  "sourceType": "webhook",
  "token": "...",
  "testToken": "...",
  "ingestUrl": "https://api.oursprivacy.com/source/...",
  "testIngestUrl": "https://api.oursprivacy.com/source/...",
  "sampleCurl": "curl -X POST 'https://api.oursprivacy.com/source/...' ..."
}

Use the sourceType field to discriminate between the two response shapes. Webhook sources do not have an installScript; pixel sources do not have an ingestUrl.

Building webhook mappers

Webhook sources accept arbitrary JSON payloads. You can map those inbound fields to the canonical event schema using the Mappings API with entityId set to the source id and templateId set to "webhook" (or the relevant per-vendor template such as "typeform", "jotform", "calendly", etc.).

To discover the exact JSON structure your webhook is sending, use the lastTriggeredAt field to confirm events are arriving, then inspect recent payloads at your destination or via the platform dashboard.

GET
/rest/v1/sources
AuthorizationBearer <token>

Ours Privacy API key

In: header

Query Parameters

limit?|

Maximum number of items to return. Defaults to 25; values below 1 are clamped to 1 and values above 100 are clamped to 100.

cursor?string

Opaque pagination cursor from pagination.nextCursor in the previous response. Do not decode or modify it. Malformed cursors return 400 Bad Request.

type?string

Filter by source type.

Value in"AlchemerWebhook" | "AndroidNativeApi" | "CSharpApi" | "CalComWebhooks" | "CalendlyWebhook" | "CallRail" | "CallTrackingMetrics" | "DotNetApi" | "FacebookLeadAds" | "FormsortWebhooks" | "Formstack" | "GoLangApi" | "HTTPApiSource" | "Healthie" | "HubspotAppActions" | "HubspotFormWebhook" | "JotFormWebhooks" | "KotlinApi" | "NodejsApi" | "PHPApi" | "PixelImage" | "PythonApi" | "ReactNativeApi" | "RedirectSource" | "RubyApi" | "SegmentWebPlugin" | "TypeformWebhooks" | "WebSource" | "Webhook" | "WhatConverts" | "iOSNativeApi"
status?string

Filter by source status.

Value in"Disabled" | "Enabled"
nameContains?string

Case-insensitive substring filter on the source name.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://app.oursprivacy.com/rest/v1/sources"
{
  "entities": [
    {
      "id": "string",
      "name": "string",
      "type": "AlchemerWebhook",
      "status": "Disabled",
      "createdAt": "string",
      "accountId": "string",
      "isPublished": true,
      "lastTriggeredAt": "string",
      "lastDispatchedAt": "string",
      "selectedAccountId": "string",
      "whitelistDomains": [
        "string"
      ],
      "whitelistIps": [
        "string"
      ],
      "botControlMode": "string",
      "botScoreThreshold": 0,
      "excludeRequestContext": true,
      "redirectUrl": "string",
      "projectAPIKey": "string",
      "probabilisticIdentity": {}
    }
  ],
  "pagination": {
    "nextCursor": "string",
    "hasMore": true
  }
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
POST
/rest/v1/sources
*object
AuthorizationBearer <token>

Ours Privacy API key

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://app.oursprivacy.com/rest/v1/sources" \  -H "Content-Type: application/json" \  -d '{    "type": "AlchemerWebhook"  }'
{
  "id": "string",
  "name": "string",
  "type": "AlchemerWebhook",
  "status": "Disabled",
  "createdAt": "string",
  "accountId": "string",
  "isPublished": true,
  "lastTriggeredAt": "string",
  "lastDispatchedAt": "string",
  "selectedAccountId": "string",
  "whitelistDomains": [
    "string"
  ],
  "whitelistIps": [
    "string"
  ],
  "botControlMode": "string",
  "botScoreThreshold": 0,
  "excludeRequestContext": true,
  "redirectUrl": "string",
  "projectAPIKey": "string",
  "probabilisticIdentity": {}
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
GET
/rest/v1/sources/{id}
AuthorizationBearer <token>

Ours Privacy API key

In: header

Path Parameters

id*string

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://app.oursprivacy.com/rest/v1/sources/string"
{
  "id": "string",
  "name": "string",
  "type": "AlchemerWebhook",
  "status": "Disabled",
  "createdAt": "string",
  "accountId": "string",
  "isPublished": true,
  "lastTriggeredAt": "string",
  "lastDispatchedAt": "string",
  "selectedAccountId": "string",
  "whitelistDomains": [
    "string"
  ],
  "whitelistIps": [
    "string"
  ],
  "botControlMode": "string",
  "botScoreThreshold": 0,
  "excludeRequestContext": true,
  "redirectUrl": "string",
  "projectAPIKey": "string",
  "probabilisticIdentity": {}
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
PATCH
/rest/v1/sources/{id}
*object
AuthorizationBearer <token>

Ours Privacy API key

In: header

Path Parameters

id*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X PATCH "https://app.oursprivacy.com/rest/v1/sources/string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "string",
  "name": "string",
  "type": "AlchemerWebhook",
  "status": "Disabled",
  "createdAt": "string",
  "accountId": "string",
  "isPublished": true,
  "lastTriggeredAt": "string",
  "lastDispatchedAt": "string",
  "selectedAccountId": "string",
  "whitelistDomains": [
    "string"
  ],
  "whitelistIps": [
    "string"
  ],
  "botControlMode": "string",
  "botScoreThreshold": 0,
  "excludeRequestContext": true,
  "redirectUrl": "string",
  "projectAPIKey": "string",
  "probabilisticIdentity": {}
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
DELETE
/rest/v1/sources/{id}
AuthorizationBearer <token>

Ours Privacy API key

In: header

Path Parameters

id*string

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X DELETE "https://app.oursprivacy.com/rest/v1/sources/string"
{
  "deleted": true
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
GET
/rest/v1/sources/{id}/tokens
AuthorizationBearer <token>

Ours Privacy API key

In: header

Path Parameters

id*string

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://app.oursprivacy.com/rest/v1/sources/string/tokens"
{
  "sourceType": "pixel",
  "token": "string",
  "testToken": "string",
  "installScript": "string",
  "testInstallScript": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}
{
  "error": "string",
  "details": "string"
}

How is this guide?