Skip to content

feat: Standardize webhook payload #168

Merged
youbek merged 8 commits intoadcontextprotocol:mainfrom
youbek:fix/webhook-payload
Nov 3, 2025
Merged

feat: Standardize webhook payload #168
youbek merged 8 commits intoadcontextprotocol:mainfrom
youbek:fix/webhook-payload

Conversation

@youbek
Copy link
Copy Markdown
Contributor

@youbek youbek commented Oct 31, 2025

Summary

Task-specific fields are no longer merged at the top level in webhook POSTs. Webhooks now deliver a flat protocol envelope and place task data under result.

Motivation

  • Align webhook structure with the adcp/client behavior, which already expects task data to be nested under a result field.
  • Eliminate ambiguity and field collisions in webhook payloads.
  • Make webhook envelope consistent with other protocol wrappers.
  • Provide a stable, protocol-focused top-level with a single result container.

What changed

  • Schema: static/schemas/v1/core/webhook-payload.json
    • Added: operation_id (required), timestamp? (ISO 8601)
    • Kept: context_id?, task_id?, task_type (required), status (required), message?
    • Added: result? (any), error? (string)
    • Removed: domain, created_at, updated_at, completed_at, progress
    • Updated examples and notes to nest task data under result
  • Registry: static/schemas/v1/index.json
    • Clarified description: protocol fields top-level, task payload under result
  • Docs (examples and guidance updated to use result):
    • docs/protocols/task-management.mdx
    • docs/protocols/core-concepts.mdx
    • docs/protocols/envelope-examples.mdx
    • docs/media-buy/task-reference/create_media_buy.mdx
    • docs/media-buy/task-reference/update_media_buy.mdx
    • docs/media-buy/task-reference/sync_creatives.mdx

Breaking changes

  • If you use adcp/client, this change is not breaking (client already maps task data to result).
  • If you consume webhook JSON directly, this is a breaking change: task data is now under result.
  • error is now a string (only when status = failed).
  • domain, created_at, updated_at, completed_at, progress removed from webhook payload.

Migration guide

  • Webhook consumers:
    • Read task data from response.result (e.g., response.result.media_buy_id).
    • Read error text from response.error (string) and/or response.message.
  • Webhook producers:
    • Do not merge task fields at the root; put all task data under result.
    • Keep protocol fields only at the top level as listed below.

New payload shape (canonical)

{
  "operation_id": "op_123",
  "context_id": "ctx_abc",
  "task_id": "task_456",
  "task_type": "create_media_buy",
  "status": "completed",
  "message": "Media buy created successfully",
  "timestamp": "2025-01-22T10:30:00Z",
  "result": {
    "media_buy_id": "mb_12345",
    "buyer_ref": "nike_q1_campaign_2024",
    "packages": [{ "package_id": "pkg_001" }]
  },
  "error": "optional string when status=failed"
}

Before vs After (compact)

  • Before: task fields at root (e.g., media_buy_id, packages)
  • After: task fields inside result (e.g., result.media_buy_id, result.packages)

@youbek youbek changed the title feat: update webhook payload types and documentation feat: webhook payload: move task data under result; standardize envelope fields Oct 31, 2025
@youbek youbek changed the title feat: webhook payload: move task data under result; standardize envelope fields feat: webhook payload - move task data under result; standardize envelope fields Oct 31, 2025
@youbek youbek marked this pull request as ready for review October 31, 2025 18:22
@youbek youbek changed the title feat: webhook payload - move task data under result; standardize envelope fields feat: Standardize webhook payload Oct 31, 2025
@youbek youbek requested a review from bokelley November 1, 2025 10:28
@youbek youbek force-pushed the fix/webhook-payload branch from 5b0edde to 2428dea Compare November 3, 2025 07:52
@youbek youbek merged commit 7d70f05 into adcontextprotocol:main Nov 3, 2025
4 checks passed
bokelley added a commit that referenced this pull request Mar 31, 2026
Display endpoints (team members list and engagement dashboard) used
membership_tier directly without inferring from subscription data when
null. This caused orgs with null membership_tier but active subscriptions
to see incorrect seat limits (e.g., 0 community seats instead of 5).

Extracts resolveMembershipTier() helper to eliminate duplication across
canAddSeat, members list, and engagement dashboard endpoints.

Resolves escalation #168 (Propulso community seats showing 0).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Mar 31, 2026
Display endpoints (team members list and engagement dashboard) used
membership_tier directly without inferring from subscription data when
null. This caused orgs with null membership_tier but active subscriptions
to see incorrect seat limits (e.g., 0 community seats instead of 5).

Extracts resolveMembershipTier() helper to eliminate duplication across
canAddSeat, members list, and engagement dashboard endpoints.

Resolves escalation #168 (Propulso community seats showing 0).

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants