Skip to main content
/api/v2/storefront/esa/{esaId}/signals The ad-server signal-component endpoints let a storefront operator build and manage the targeting components exposed by an ad server source. The /esa/ path segment and esaId field are stable API identifiers; the operator-facing object is an ad server source. Keep these two layers distinct:
TermMeaning
Ad-server targetingSource-native audience segments, custom targeting keys, and custom targeting values already present in the connected ad server
Signal componentA named targeting definition the seller creates from one or more source-native targeting primitives; carried as a signal on the API wire
Browsing ad-server targeting does not create or import a signal component. It shows the raw material available for authoring. Start every authoring workflow by reading source capabilities. Capabilities describe which mapping kinds, API candidate types, value types, composition models, and parent-filtered types the source supports. Do not assume every ad server source supports GAM fields.

Endpoints

MethodEndpointDescription
GET/api/v2/storefront/esa/{esaId}/signalsList signal components created on the source
GET/api/v2/storefront/esa/{esaId}/signals/{signalId}Read one signal component
POST/api/v2/storefront/esa/{esaId}/signalsCreate a signal component. Add ?dry_run=true to validate and preview without persisting
GET/api/v2/storefront/esa/{esaId}/signals/adapter-capabilitiesDescribe source support for signal-component authoring
GET/api/v2/storefront/esa/{esaId}/signals/candidatesBrowse source-native ad-server targeting; candidates is the API response name

Bulk signal-component creation with Murph

When you need to create many signal components, ask Murph to create them as a batch instead of one by one. Murph still validates and previews the proposed components before any durable write, and the confirmation gate still fires before creation. The batch is approved once, then Murph creates the set together.
  • Paste a list or upload rows. Murph maps each row to the source’s supported signal-component shape after reading source capabilities.
  • One approval for the batch. You review the full set and approve once rather than approving every component individually.
  • Continues on error. If one component fails, the rest continue. Murph reports a per-component result so you can retry only the failures.
Use this for requests such as “create signal components from these 49 GAM values,” “set up my first audience components,” or “build components from these key-values.”

Source capabilities

curl https://api.interchange.io/api/v2/storefront/esa/123/signals/adapter-capabilities \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
{
  "data": {
    "adapter": "google_ad_manager",
    "supportsSignalMappingAuthoring": true,
    "mappingKinds": [
      {
        "mappingKind": "audience_segment",
        "label": "Audience segment",
        "candidateType": "audience_segment",
        "supportsSearch": true
      },
      {
        "mappingKind": "gam_targeting_groups",
        "label": "GAM targeting groups",
        "candidateType": null,
        "supportsSearch": false
      }
    ],
    "supportedCandidateTypes": [
      "audience_segment",
      "custom_targeting_key",
      "custom_targeting_value"
    ],
    "candidateTypes": [
      {
        "candidateType": "custom_targeting_key",
        "label": "Custom targeting key",
        "browseOnly": true,
        "childCandidateTypes": ["custom_targeting_value"],
        "supportsSearch": true
      },
      {
        "candidateType": "custom_targeting_value",
        "label": "Custom targeting value",
        "mappingKind": "custom_key_value",
        "directlyMappable": true,
        "parentCandidateType": "custom_targeting_key",
        "supportsParentFilter": true,
        "supportsSearch": true
      }
    ],
    "targetingSemantics": {
      "supportsComposed": true,
      "compositionModels": ["groups"],
      "supportedModes": ["include", "exclude"],
      "mappingKinds": [
        {
          "mappingKind": "gam_targeting_groups",
          "supportsComposed": true,
          "compositionModels": ["groups"],
          "exclusiveWithOtherSignals": true,
          "notes": "Grouped GAM targeting must be used alone for buyer targeting that consumes this field."
        }
      ]
    },
    "valueTypes": ["audience", "binary"]
  }
}

Capability fields

FieldNotes
adapterAdapter implementation behind the ad server source, for example google_ad_manager
supportsSignalMappingAuthoringfalse means the source can list signal components but cannot create drafts from this API
mappingKindsSignal mapping kinds the adapter can create, such as audience_segment, custom_key_value, or gam_targeting_groups
candidateTypesAPI types for browseable ad-server targeting. Types listed under childCandidateTypes can require parent_id when supportsParentFilter is true
targetingSemanticsComposition behavior, include/exclude modes, buyer targeting fields, and warnings such as exclusivity
valueTypesAllowed valueType values for signal-component drafts

Browse ad-server targeting

Ad-server targeting records are source-native values that can be used to build a signal-component draft. The endpoint returns them in a candidates array; that is the wire name, not a separate operator-facing object. For hierarchical API types, first browse the parent type and then pass its externalId as parent_id when browsing the nested type.
curl "https://api.interchange.io/api/v2/storefront/esa/123/signals/candidates?candidate_type=custom_targeting_key&q=DAYOFWEEK&limit=10" \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
curl "https://api.interchange.io/api/v2/storefront/esa/123/signals/candidates?candidate_type=custom_targeting_value&parent_id=17467172&q=FRIDAY&limit=10" \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
{
  "data": {
    "candidates": [
      {
        "candidateType": "custom_targeting_value",
        "externalId": "451422266753",
        "name": "FRIDAY",
        "parentId": "17467172",
        "path": ["DAY OF WEEK", "FRIDAY"],
        "mappingKind": "custom_key_value",
        "defaultSignal": {
          "signalId": "dayofweek_friday",
          "name": "DAY OF WEEK: FRIDAY",
          "valueType": "binary",
          "adapterConfig": {
            "type": "passthrough",
            "kind": "custom_key_value",
            "keyId": "17467172",
            "valueId": "451422266753"
          }
        }
      }
    ],
    "count": 1,
    "nextCursor": null
  }
}

Ad-server targeting query parameters

ParameterRequiredNotes
candidate_typeYesAPI type from candidateTypes[].candidateType
q or queryNoAdapter search string
parent_idNoParent candidate externalId, required by candidate types with supportsParentFilter: true
limitNoPage size
cursorNoCursor returned as nextCursor

Signal-component draft shape

Creation and validation use the same request body:
FieldTypeRequiredNotes
signalIdstringYesStable caller-supplied signal identifier
namestringYesHuman-readable signal name
descriptionstring or nullNoOperator-facing description
valueTypestringYesOne of the adapter capability valueTypes
tagsstring[]NoOptional labels
adapterConfigobjectYesAdapter mapping configuration

How signal components relate to products

Products describe the sellable inventory package. Signal components describe targetable attributes that can be exposed to buyers or used in targeting workflows. For GAM key-values, do not treat “not in the product selector fields” as “not supported.” Key-value signal targeting is supported when the source capabilities advertise the relevant signal mapping kind. Use custom_key_value for a direct key/value mapping and gam_targeting_groups for composite GAM key-value logic. Then validate the signal and use it according to the adapter’s targetingSemantics. If targetingSemantics.mappingKinds[].exclusiveWithOtherSignals is true for gam_targeting_groups, use that grouped signal by itself for the buyer targeting field it consumes. Some large networks use GAM key-values to identify site lists or other seller-defined groups inside their network. Those keys and values are browseable as ad-server targeting and can be used to create signal components. Publisher coverage still comes from adagents.json. Buyer property-list references are forwarded and resolved today; the seller’s agent decides whether and how to map the requested subset to products or ad-server controls. See Custom targeting and properties.

Audience segment

{
  "signalId": "auto_intenders",
  "name": "Auto intenders",
  "valueType": "audience",
  "adapterConfig": {
    "type": "passthrough",
    "kind": "audience_segment",
    "segmentId": "987654321"
  }
}

Direct GAM key-value signal

Use a direct custom_key_value signal when the adapter exposes a specific custom targeting value as directly mappable. Browse values with parent_id so the value remains tied to the correct key.
{
  "signalId": "dayofweek_friday",
  "name": "DAY OF WEEK: FRIDAY",
  "valueType": "binary",
  "adapterConfig": {
    "type": "passthrough",
    "kind": "custom_key_value",
    "keyId": "17467172",
    "valueId": "451422266753"
  }
}

Grouped GAM targeting

Use gam_targeting_groups for composite GAM logic. Groups are OR’d together; criteria inside a group are AND’d together; multiple values inside one criterion are OR’d by GAM for that key. A criterion with exclude: true excludes matching values. Grouped GAM targeting can be exclusive depending on the adapter semantics. If targetingSemantics.mappingKinds[].exclusiveWithOtherSignals is true, do not combine the grouped signal with another signal targeting the same buyer field.
{
  "signalId": "weekday_or_sports",
  "name": "Weekday or sports package",
  "valueType": "binary",
  "adapterConfig": {
    "type": "passthrough",
    "kind": "gam_targeting_groups",
    "groups": [
      {
        "criteria": [
          {
            "keyId": "17467172",
            "values": ["451422266753", "451420638792"]
          },
          {
            "keyId": "98765",
            "values": ["12345"],
            "exclude": true
          }
        ]
      },
      {
        "criteria": [
          {
            "keyId": "24680",
            "values": ["13579"]
          }
        ]
      }
    ]
  }
}

Validate a component draft with dry_run=true

Use POST /api/v2/storefront/esa/{esaId}/signals?dry_run=true to validate and preview a signal-component draft without persisting it. The request body is the same as POST /signals, but the response is a validation result rather than a saved signal object. Read the valid flag, not the HTTP status — a dry run returns 200 even when the draft is invalid, and the issues[] array explains why. A malformed request body still returns 422.
curl -X POST "https://api.interchange.io/api/v2/storefront/esa/123/signals?dry_run=true" \
  -H "Authorization: Bearer $SCOPE3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "signalId": "weekday_or_sports",
    "name": "Weekday or sports package",
    "valueType": "binary",
    "adapterConfig": {
      "type": "passthrough",
      "kind": "gam_targeting_groups",
      "groups": [
        {
          "criteria": [
            {
              "keyId": "17467172",
              "values": ["451422266753"]
            }
          ]
        }
      ]
    }
  }'
{
  "data": {
    "valid": true,
    "issues": []
  }
}
A dry run does not persist the signal component. When the draft is valid the response also includes a preview with the rendered wire signal and source projections. Use a dry run before create when a client is assembling adapterConfig manually, or before update to preview a change.

Create a signal component

curl -X POST https://api.interchange.io/api/v2/storefront/esa/123/signals \
  -H "Authorization: Bearer $SCOPE3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "signalId": "dayofweek_friday",
    "name": "DAY OF WEEK: FRIDAY",
    "valueType": "binary",
    "adapterConfig": {
      "type": "passthrough",
      "kind": "custom_key_value",
      "keyId": "17467172",
      "valueId": "451422266753"
    }
  }'
{
  "data": {
    "signalId": "dayofweek_friday",
    "name": "DAY OF WEEK: FRIDAY",
    "valueType": "binary",
    "adapterConfig": {
      "type": "passthrough",
      "kind": "custom_key_value",
      "keyId": "17467172",
      "valueId": "451422266753"
    }
  }
}

List and get signal components

curl https://api.interchange.io/api/v2/storefront/esa/123/signals \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
curl https://api.interchange.io/api/v2/storefront/esa/123/signals/dayofweek_friday \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
Signal-component response objects include at least signalId and name; sources can return additional fields such as description, status, valueType, adapterConfig, coverageForecast, createdAt, and updatedAt.

Errors

  • 400 VALIDATION_ERROR — invalid ad server source id, malformed draft, missing required fields, or a source validation issue.
  • 401 UNAUTHORIZED — missing or invalid bearer token.
  • 404 NOT_FOUND — ad server source or signal component does not exist for the caller.
  • 502 or 503 — the ad server source or its upstream service could not complete the request.
See Errors for the full error contract.

Storefront signal-component tasks

Create and manage storefront signal components

Custom targeting and properties

How GAM key-values relate to site lists and publisher coverage

Signal overview

Signal model and lifecycle

Storefront API reference

OpenAPI reference for storefront routes