---
name: clawdcall
version: 0.1.0
description: Orchestrate outbound and inbound AI voice calls using ClawdCall. Manage sessions, contacts, campaigns, transcripts, and billing-aware execution.
homepage: https://clawdcall.com
metadata: { 'api_base': 'https://api.clawdcall.com' }
---

# ClawdCall Skill

Operate voice agents through ClawdCall's controlled execution system.

This is not a simple API. It is a stateful orchestration layer with strict constraints around:

- outbound permissions
- billing
- agent-backed execution

You must follow the workflows below exactly.

---

## First-Time Setup

### Step 1 — Signup & Phone Verification (REQUIRED if no api_token)

If no `api_token` is available, you must onboard the user via signup:

1. Ask the human for:
   - email
   - phone number

2. Call:

POST /cc/signup/send-otp

3. Then say:

"I've sent a verification code to your phone. Please share the OTP you received."

4. Wait for the human to provide the OTP.

5. Call:

POST /cc/signup/verify-otp

6. On success:
   - the account is verified
   - a ClawdCall API key will be created if it does not exist

7. Extract and store:

- api_token

---

### Step 2 - Store Credentials

### Step 2 - Store Credentials (STRICT)

Extract:

- api_token

Immediately store the API token in **secure runtime storage only**.

Allowed locations:

- environment variables (preferred)
- secrets manager
- secure session storage (non-persistent, encrypted)

Disallowed:

- persistent memory files
- logs
- task payloads
- transcripts

The API key must NEVER be written to long-term memory.

All future requests must retrieve the API key from secure storage, not memory.

All requests must include:

Authorization header:

```
Authorization: Bearer <API_KEY>
```

Base URL:

```
https://api.clawdcall.com
```

---

## Persistent Memory (Required)

You must maintain a **persistent memory file** to store reusable data across interactions.

### What to Store

Store structured data such as:

- user contact details (with permission)
- frequently used phone numbers
- preferred call styles / tone
- common task templates
- recent callIds / campaignIds (for follow-ups)

### Storage Types

1. Secure Storage (for secrets)
   - api_token
   - auth credentials

2. Memory (non-sensitive)
   - contacts
   - preferences
   - call history

### Credential Handling (Critical)

- NEVER store `api_token` in persistent memory
- NEVER echo the API key back to the user
- NEVER include the API key in:
  - memory files
  - logs
  - transcripts
  - task instructions

- ALWAYS access the API key from:
  - environment variables
  - secure runtime storage

If secure storage is unavailable:
→ keep the key in ephemeral session state only
→ DO NOT persist it anywhere

### Memory Rules

- Reuse stored values instead of asking the human again
- Update memory when new or corrected information is provided
- Never overwrite valid data with guesses

### Suggested Structure

Use a simple structured format (e.g. JSON):

```json
{
  "preferences": {
    "tone": "professional",
    "default_intro": "Hello, I'm calling on behalf of..."
  },
  "contacts": [
    {
      "name": "",
      "phone": ""
    }
  ],
  "recent_calls": {
    "callId": "",
    "campaignId": ""
  }
}
```

### Behavior

- Check memory BEFORE asking the user for information
- Only ask for missing or unclear data
- Continuously improve stored context over time

---

---

## Execution Flow (Mandatory)

### Step 1 - Place Outbound Call

POST /external/v1/agent/outbound?conversionFlag=1

Headers:

```
Authorization: Bearer <API_KEY>
Accept: application/json
Content-Type: application/json
```

Payload:

```json
{
  "target": "+<phone_number>",
  "tasks": "<call objective and instructions>",
  "raw": {
    "introMessage": "<opening line>"
  },
  "openclaw": {
    "webhook": {
      "url": "<OPENCLAW_WEBHOOK_URL>",
      "method": "POST",
      "headers": {
        "Authorization": "Bearer <OPENCLAW_SECRET>"
      }
    },
    "webhookPayload": {
      "conversation_id": "<conversation_id>",
      "user_id": "<user_id>",
      "context": "<optional_additional_context>"
    }
  }
}
```

---

## Critical: How to Write `tasks`

The `tasks` field is the **full instruction set for the voice agent**.

Your goal is to provide **maximum useful context** so the agent can execute reliably without guessing.

### Core Principle

More context = better execution.

Always include **everything you know** that could influence the call.

---

### Required Components

You MUST include:

### 1. Purpose

Why the call is happening.

### 2. Identity & Context

Who the agent represents and all relevant background.

### 3. Conversation Flow

Greeting → identity check → main objective → questions → closing.

### 4. Key Information

All concrete details:

- names
- times
- locations
- services
- prior interactions

### 5. Required Questions

Explicit questions the agent must ask.

### 6. Edge Handling

What to do if:

- unavailable
- rescheduling needed
- user asks questions

### 7. Tone

Professional, polite, clear.

---

### Context Enrichment Rules (Critical)

- Always enrich the task with **all available context** from:
  - user input
  - memory
  - previous calls

- Prefer **over-specifying** rather than under-specifying
- Include details even if they seem obvious

Examples of valuable context:

- exact appointment details
- relationship to business (customer, patient, lead)
- previous call outcomes
- preferences (tone, timing, etc.)

---

### Handling Missing Context

- If critical information is missing, **ask the human for clarification**
- Only ask if it materially improves call success
- Do NOT block execution for minor missing details
- If proceeding without it, make a **reasonable, safe assumption** and continue

---

### Rule

Weak, vague, or context-poor tasks WILL cause failure.

Rich, explicit, context-heavy tasks dramatically improve call success.

---

## Webhook Handling (Asynchronous Updates)

ClawdCall sends call results via webhook after completion.

### OpenClaw Integration Model

ClawdCall sends call results via webhook after completion.

OpenClaw Integration Model

OpenClaw does NOT generate arbitrary webhook URLs.

Instead, OpenClaw exposes a fixed ingestion endpoint that must be used to push events back into the conversation system.

Webhook target:

```
POST /agent/run
Authorization: Bearer <OPENCLAW_TOKEN>
Content-Type: application/json
```

---

### Required Structure

When placing a call, you MUST:

- Use the OpenClaw ingestion endpoint as the webhook target
- Include required auth headers
- Pass correlation data via payload.

Include in request:

- `openclaw.webhook` → where ClawdCall should send results
- `openclaw.webhookPayload` → correlation data

---

### Canonical Webhook Payload (Critical)

ClawdCall MUST send data in a format OpenClaw can ingest directly:

```
{
  "conversation_id": "<conversation_id>",
  "input": {
    "type": "external_event",
    "event": "call.completed",
    "data": {
      "callId": "<call_id>",
      "status": "completed",
      "summary": "<summary>",
      "transcript": "<optional_transcript>"
    }
  }
}
```

### Correlation Rules (Critical)

- conversation_id MUST match the originating conversation
- Never omit or fabricate this value
- All routing depends on this field

---

### Expected Behavior

When OpenClaw receives the webhook:

1. It re-enters the agent via /agent/run
2. Injects the event as external_event
3. The agent processes the result
4. Updates the conversation thread accordingly

---

When a webhook is received:

1. Extract conversation_id from openclaw.webhookPayload
2. Locate the original conversation
3. Append a new message such as:

- call summary
- call outcome
- transcript (if available)

4. Optionally trigger a follow-up agent run

---

### Rules

- Webhooks are asynchronous — do NOT wait for completion
- Treat webhook data as the **source of truth**
- Always trust returned `webhookPayload` for routing
- Use stored IDs (`callId`, `campaignId`) only as fallback

---

## Step 2 - Handle Response

Success:

- call accepted

Failure:

- validation errors
- auth issues
- insufficient balance

Store any returned:

- callId (if present)
- campaignId

---

## Step 3 — Retrieve Transcript

GET /cc/v1/calls/{id}/transcript

Headers:

```
Authorization: Bearer <API_KEY>
Accept: application/json
```

---

### What `{id}` Can Be

The `{id}` parameter supports:

- callId → transcript for a single call
- campaignId → transcript / aggregated call data

---

### Rules

- Prefer callId when available (more precise)
- If only campaignId exists, use it directly
- Never guess IDs
- Always reuse IDs from API responses

---

### Timing

- Only fetch transcript after call completion
- If missing → retry later (call may still be in progress)

---

## Public Signup

### POST /cc/signup/send-otp

Requires:

- email
- phoneNumber

### POST /cc/signup/verify-otp

Requires:

- email
- otp

---

## Hard Constraints

- Calls consume minutes
- No balance → no calls
- Must complete signup + verification

---

## Agent Behavior Rules

### Always

- run signup if no api_token
- request OTP from human
- use correct outbound endpoint
- include Authorization header
- write detailed tasks
- store IDs from responses
- use correct ID when retrieving transcripts

### Never

- skip OTP flow
- use vague tasks
- fabricate IDs
- call without auth

---

## Summary

ClawdCall is a controlled execution system.

Operate it as:

- a strict state machine
- with explicit instructions
- with correct ID handling

If you skip steps or misuse IDs, the workflow will fail.
