> ## Documentation Index
> Fetch the complete documentation index at: https://agenticadvertisingorg-snap-format-preview-links.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# get_creative_features

> get_creative_features evaluates a creative manifest against a governance agent and returns feature values for brand safety and compliance in AdCP.

# get\_creative\_features

Evaluates a creative manifest and returns feature values from a creative governance agent.

## Use cases

* **Security scanning**: Detect malware, auto-redirects, credential harvesting, cloaking
* **Creative quality**: Evaluate brand consistency, platform optimization, guideline adherence
* **Content categorization**: Classify creative content against IAB Content Taxonomy or other standards
* **Accessibility**: Check WCAG compliance, screen reader compatibility

## Request

```json theme={null}
{
  "$schema": "/schemas/creative/get-creative-features-request.json",
  "creative_manifest": {
    "format_id": {
      "agent_url": "https://creative.adcontextprotocol.org",
      "id": "html5-display-300x250"
    },
    "assets": {
      "creative_html": {
        "asset_type": "url",
        "url": "https://cdn.agency.com/creative/abc123.html"
      }
    }
  },
  "feature_ids": ["auto_redirect", "credential_harvest", "cloaking"]
}
```

### Parameters

| Parameter           | Type      | Required | Description                                                                         |
| ------------------- | --------- | -------- | ----------------------------------------------------------------------------------- |
| `creative_manifest` | object    | Yes      | Creative manifest with `format_id` and `assets`                                     |
| `feature_ids`       | string\[] | No       | Filter to specific features. If omitted, evaluates all features the agent supports. |

### Authentication when used as a build evaluator

`get_creative_features` is also the evaluator contract used when `build_creative.evaluator.agent_url` or `build_creative.evaluator.feature_agent.agent_url` points at an external evaluator. In that flow, the creative/seller agent is the caller and the evaluator authenticates it on the transport: RFC 9421 request signing with JWKS discovery is preferred, and mTLS or a pre-provisioned Bearer/API-key credential are acceptable when both parties have arranged them.

The request payload is not an authentication channel. Evaluators MUST NOT treat `agent_url`, `account`, `context`, `ext`, or fields inside `creative_manifest` as proof of caller identity, and callers MUST NOT put evaluator credentials or caller-supplied trust material in those fields. Credential- or trust-material payload keys such as `api_key`, `client_secret`, `bearer`, `authorization`, `jwk`, `jwks`, or `jwks_uri` are non-conforming and should be rejected with [`CREDENTIAL_IN_ARGS`](/docs/building/by-layer/L3/error-handling#authentication-and-access).

After authenticating the transport, the evaluator maps the caller to its allowed creative agent/account configuration. A request signed by, or carrying credentials for, an unrecognized creative agent should fail authentication or authorization; it should not be accepted because the payload names an expected account.

When this call was initiated by `build_creative` and the evaluator is unreachable or rejects the producing agent's transport authentication, the buyer-visible build should fall back to seller-default ranking with an advisory `errors[]` note rather than failing solely because evaluation was unavailable.

## Response

<CodeGroup>
  ```json Security scanner (clean) theme={null}
  {
    "$schema": "/schemas/creative/get-creative-features-response.json",
    "status": "completed",
    "results": [
      { "feature_id": "auto_redirect", "value": false },
      { "feature_id": "credential_harvest", "value": false },
      { "feature_id": "cloaking", "value": false }
    ],
    "detail_url": "https://scanner.example.com/reports/ctx_abc123"
  }
  ```

  ```json Security scanner (threat detected) theme={null}
  {
    "$schema": "/schemas/creative/get-creative-features-response.json",
    "status": "completed",
    "results": [
      { "feature_id": "auto_redirect", "value": true, "confidence": 0.97 },
      { "feature_id": "credential_harvest", "value": true, "confidence": 0.91 },
      { "feature_id": "cloaking", "value": false }
    ],
    "detail_url": "https://scanner.example.com/reports/ctx_def456"
  }
  ```

  ```json Creative quality platform theme={null}
  {
    "$schema": "/schemas/creative/get-creative-features-response.json",
    "status": "completed",
    "results": [
      { "feature_id": "brand_consistency", "value": 87, "unit": "percentage" },
      { "feature_id": "platform_optimized", "value": true },
      { "feature_id": "creative_quality_score", "value": 92, "unit": "score" }
    ],
    "detail_url": "https://quality.example.com/reports/ctx_ghi789"
  }
  ```

  ```json Content categorizer theme={null}
  {
    "$schema": "/schemas/creative/get-creative-features-response.json",
    "status": "completed",
    "results": [
      { "feature_id": "iab_casinos_gambling", "value": true, "confidence": 0.95 },
      { "feature_id": "iab_automotive", "value": false, "confidence": 0.12 }
    ],
    "detail_url": "https://categorizer.example.com/reports/ctx_jkl012"
  }
  ```

  ```json Provenance audit observation theme={null}
  {
    "$schema": "/schemas/creative/get-creative-features-response.json",
    "status": "completed",
    "results": [
      { "feature_id": "ai_generated", "value": true, "confidence": 0.94 }
    ],
    "audit_observations": [
      {
        "code": "OVERSIGHT_DISCLOSURE_CARVEOUT_CLAIMED",
        "severity": "audit-worthy",
        "recovery": "informational",
        "field": "creative_manifest.provenance.disclosure.required",
        "message": "Creative claims human-directed AI output does not require disclosure; retain for audit review.",
        "details": {
          "agent_url": "https://governance.encypher.seller.example",
          "feature_id": "ai_generated",
          "claimed_value": {
            "human_oversight": "directed",
            "disclosure_required": false
          },
          "observed_value": true,
          "confidence": 0.94
        }
      }
    ]
  }
  ```
</CodeGroup>

### Response fields

| Field                                        | Description                                                                                                                                                                                                    |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `results`                                    | Array of feature evaluation results                                                                                                                                                                            |
| `results[].feature_id`                       | Which feature was evaluated                                                                                                                                                                                    |
| `results[].value`                            | Feature value: boolean (binary), number (quantitative), or string (categorical)                                                                                                                                |
| `results[].confidence`                       | Confidence score (0-1), when applicable                                                                                                                                                                        |
| `results[].unit`                             | Unit for quantitative values (e.g., `percentage`, `score`)                                                                                                                                                     |
| `results[].expires_at`                       | When this evaluation expires and should be refreshed                                                                                                                                                           |
| `results[].measured_at`                      | When this feature was evaluated                                                                                                                                                                                |
| `results[].methodology_version`              | Version of methodology used                                                                                                                                                                                    |
| `results[].details`                          | Vendor-specific details                                                                                                                                                                                        |
| `detail_url`                                 | URL to vendor's full assessment. Access-controlled by the vendor.                                                                                                                                              |
| `audit_observations[]`                       | Non-blocking observations for audit routing. These are not rejection signals by themselves.                                                                                                                    |
| `audit_observations[].code`                  | Machine-readable observation code, such as `OVERSIGHT_DISCLOSURE_CARVEOUT_CLAIMED`                                                                                                                             |
| `audit_observations[].severity`              | Routing severity; currently `audit-worthy`                                                                                                                                                                     |
| `audit_observations[].recovery`              | Caller recovery category; currently `informational`                                                                                                                                                            |
| `audit_observations[].field`                 | Resolved creative manifest path for the risky claim side of the observation. Multi-field observations anchor the primary claim path, not necessarily every trigger field.                                      |
| `audit_observations[].message`               | Human-readable audit queue summary; do not include PII, cross-tenant data, or vendor-only report details                                                                                                       |
| `audit_observations[].details`               | Audit-safe details limited to `{ agent_url, feature_id, claimed_value, observed_value, confidence, substituted_for }`                                                                                          |
| `audit_observations[].details.claimed_value` | For `OVERSIGHT_DISCLOSURE_CARVEOUT_CLAIMED`, a compact object `{ human_oversight, disclosure_required }`; `disclosure_required` is the flattened alias for `creative_manifest.provenance.disclosure.required`. |

`feature_ids` filters `results[]`; `audit_observations[]` may still appear when the submitted provenance itself is audit-worthy. `OVERSIGHT_DISCLOSURE_CARVEOUT_CLAIMED` fires when `human_oversight` is `edited` or `directed` and `disclosure.required` is `false`; verifier observations such as `observed_value` and `confidence` are optional audit context.

### Error response

```json theme={null}
{
  "errors": [
    {
      "code": "CREATIVE_INACCESSIBLE",
      "message": "Could not retrieve creative assets for evaluation"
    }
  ]
}
```

## Async evaluation

Some evaluations (e.g., sandboxed malware scanning) take time. The agent returns `status: "working"` and delivers results via webhook when complete. This uses the standard [async task pattern](/docs/building/implementation/async-operations) — no custom status values needed.

## Orchestrator logic

The orchestrator applies feature requirements on the client side, the same way property list feature requirements work:

```javascript theme={null}
const result = await agent.getCreativeFeatures({
  creative_manifest: manifest
});

if (result.errors) {
  // Handle error - reject or retry
  return;
}

// Apply security requirements
const threats = result.results.filter(
  f => ['auto_redirect', 'credential_harvest', 'cloaking'].includes(f.feature_id)
    && f.value === true
);
if (threats.length > 0) {
  // Reject - security threat detected
  return;
}

// Apply quality requirements
const quality = result.results.find(f => f.feature_id === 'brand_consistency');
if (quality && quality.value < 80) {
  // Reject - below quality threshold
  return;
}

for (const observation of result.audit_observations ?? []) {
  if (observation.severity === 'audit-worthy') {
    // Retain or route for review; do not reject solely on this signal.
    recordAuditObservation(observation);
  }
}
```

## Relationship to property governance

Creative governance follows the same pattern as property governance:

| Concept                   | Property governance                     | Creative governance                                |
| ------------------------- | --------------------------------------- | -------------------------------------------------- |
| **What's evaluated**      | Properties (websites, apps)             | Creatives (manifests)                              |
| **Feature declarations**  | `governance.property_features`          | `governance.creative_features`                     |
| **Evaluation task**       | Property list filters                   | `get_creative_features`                            |
| **Feature values**        | `property-feature-value` schema         | Same fields (value, confidence, expires\_at, etc.) |
| **Detailed intelligence** | Behind `detail_url` / `methodology_url` | Behind `detail_url` / `methodology_url`            |
