atteq API
  • Guides
  • Recipes
  • Cookbook
  • API Reference
Book an appointment without double-bookingSync a lead to the client's systemPush every call to a webhookGreet callers by nameQuote from a price list
powered by Zudoku
Recipes

Push every call to a webhook

Requirement

"After every call, push the transcript to our webhook."

Pieces

  • Connection: the webhook's key, provider http_key.
  • One tool per action: an HTTP tool that posts to the webhook.
  • Post hook: the tool attached as post_hook_tool_ids on the agent draft, then published.

The shape to avoid

Instructions in the prompt telling the model to "send the transcript at the end". The model does not run after the last word, and a tool it could call mid-conversation is one it may forget to call. A post hook runs after the conversation whether or not anybody asked, and its failures land in the interaction's record where they can be found.

Steps

Ids from an earlier step are written as {{step_N.field}}; the test that runs this page substitutes them.

A hook is called with no arguments from the model. What the webhook receives is what a human fixed on the instance (fixed_parameters) and nothing else: the platform's own ids never leave it. To be told which conversation ended, fix a parameter of your choosing — here conversation_id — to $ref:conversation.id; it is resolved when the hook runs and arrives in the payload as the conversation's id. The transcript itself is not in the request; the webhook reads that id from the payload and fetches the transcript with get_trace, and the interaction's end reason and duration with get_interaction.

  1. The webhook's key.

    create_connection

    Code
    { "provider": "http_key", "account_label": "Call-ended webhook", "scopes": [], "grant_secret": "{\"header\":\"X-Webhook-Key\",\"prefix\":\"\",\"value\":\"whk_replace_me\"}", "granted_via": "pasted" }
  2. The tool. fixed_parameters travel with every call; the model never sees them and, in a hook, there is no model to. The webhook receives {"event": "conversation_ended", "conversation_id": "<the id>"}.

    create_tool

    Code
    { "name": "notify_call_ended", "description": "Tell the client's system that a conversation ended.", "source": "builtin", "config": {"endpoint": "https://crm.example.com/hooks/call-ended", "method": "POST"}, "input_schema": {"type": "object", "properties": {}}, "fixed_parameters": { "event": "conversation_ended", "conversation_id": "$ref:conversation.id" }, "connection_id": "{{step_1.id}}" }
  3. An agent publishes only with an AI profile; one LLM setting makes one.

    create_llm_settings

    Code
    {"name": "fast", "provider": "openai", "model": "gpt-4o-mini"}
  4. The profile.

    create_profile

    Code
    {"name": "default", "text": {"llm_settings_id": "{{step_3.id}}"}}
  5. The agent.

    create_agent

    Code
    {"name": "Support line"}
  6. Its draft: the version to edit and the graph to fill.

    get_draft (agent_id = {{step_5.id}})

    Code
    {}
  7. A root node.

    add_node (graph_id = {{step_6.graph_id}})

    Code
    {"instructions": "You answer support questions briefly and hand off to a person when asked."}
  8. Named as the root.

    set_root (graph_id = {{step_6.graph_id}}, node_id = {{step_7.id}})

    Code
    {}
  9. The hook is a property of the draft, next to the profile.

    edit_draft (version_id = {{step_6.id}})

    Code
    {"ai_profile_id": "{{step_4.id}}", "post_hook_tool_ids": ["{{step_2.id}}"]}
  10. Published: the hook runs after every conversation from here on.

    publish_version (version_id = {{step_6.id}})

    Code
    {}

What the agent sees

Nothing. The tool is in the post slot, not on a node, so the model is never offered it; it runs once, after the conversation, and every attempt is a tool call in the interaction's trace.

Variations

  • Several steps, or a branch: the same work as an automation. Put the webhook tool in a flow and create an automation with trigger_kind: "interaction_ended"; its run starts with interaction_id, agent_id, channel, direction, end_reason, started_at, ended_at, duration_seconds, contact_spoke and usage, all readable as $ref:trigger.<key>:

    Code
    { "name": "Push ended conversations", "trigger_kind": "interaction_ended", "trigger_config": {"agent_id": "<the agent's id, or omit for every agent>"}, "flow_id": "<the flow's id>", "min_interval_seconds": 300 }
  • Only calls that ended one way: trigger_config.end_reasons on that automation lists the end reasons that count.

  • Before the conversation instead of after: the same tool in pre_hook_tool_ids; its output is injected as context for the first word.

Last modified on November 4, 2026
Sync a lead to the client's systemGreet callers by name
On this page
  • Requirement
  • Pieces
  • The shape to avoid
  • Steps
  • What the agent sees
  • Variations
JSON
JSON
JSON
JSON
JSON
JSON
JSON
JSON
JSON
JSON
JSON