The 30-second rule
Any AdCP task can return one of these statuses. The server chooses based on what it knows about the work involved:working is not async. It’s a progress signal the server sends out-of-band (via MCP status notifications or SSE) while it continues processing. The caller holds the connection and receives the result when it’s ready — no polling, no webhooks. Think of it as “this is taking a moment, but I’m on it.”
submitted is async. The operation is blocked on something outside the server’s control — publisher approval, human review, third-party processing. The caller should configure a webhook and move on.
:::tip Webhooks for submitted operations
Webhooks are the recommended approach for submitted operations — they work with any transport (MCP, A2A, REST) and handle operations that outlive a single session. See Push Notifications.
Polling via the AdCP task polling surface works as a simpler alternative or backup. In 3.x, that surface is legacy tasks/get, with optional get_task_status when the seller advertises the alias. See the polling pattern below.
Transport-native tasks are not the AdCP lifecycle. MCP Tasks or A2A task updates may carry or stream an AdCP response, but the durable task state is the AdCP payload: task_id, status, webhook payloads, and AdCP polling/reconciliation. See MCP Guide.
:::
Operation examples
Synchronous (instant)
May need human input
May go async (submitted)
These operations integrate with external systems or require human approval.
Timeout Configuration
Set reasonable timeouts based on status:working uses a connection timeout (how long to hold open), not a poll interval. The server sends progress out-of-band and delivers the result on the same connection. submitted uses a webhook delivery window — if you’re also polling as backup, use a 30-second interval.
Human-in-the-Loop Workflows
Design Principles
- Optional by default - Approvals are configured per implementation
- Clear messaging - Users understand what they’re approving
- Timeout gracefully - Don’t block forever on human input
- Audit trail - Track who approved what when
Approval Patterns
Common Approval Triggers
- Budget thresholds: Campaigns over $100K
- New advertisers: First-time buyers
- Policy-sensitive content: Certain industries or topics
- Manual inventory: Premium placements requiring publisher approval
Progress Tracking
Progress Updates
Long-running operations may provide progress information:Displaying Progress
Protocol-Agnostic Patterns
These patterns work with both MCP and A2A.Product Discovery with Clarification
Campaign Creation with Approval
Polling for submitted Operations
Polling is a backup for submitted operations when webhooks aren’t configured or as a fallback. Don’t poll for working — the server delivers the result on the open connection.
Asynchronous-First Design
Store State Persistently
Don’t rely on in-memory state for async operations:Handle Restarts Gracefully
Resume tracking after orchestrator restarts:Best Practices
- Design async first - Assume any operation could take time
- Persist state - Don’t rely on in-memory tracking
- Handle restarts - Resume tracking on startup
- Implement timeouts - Don’t wait forever
- Show progress - Keep users informed
- Support cancellation - Let users cancel long operations
- Audit trail - Log all status transitions
Next Steps
- Webhooks: See Webhooks for push notifications instead of polling
- Task Lifecycle: See Task Lifecycle for status handling details
- Orchestrator Design: See Orchestrator Design for production patterns