{
  "openapi": "3.0.1",
  "info": {
    "title": "Replify Outbound Phone API",
    "version": "1.0.0",
    "description": "Schedule immediate outbound phone calls for a specific assistant.\n\n**Authentication**\nSee the [API overview](/api-reference/overview) for API keys (`x-api-key`) and required headers. This endpoint requires `Content-Type: application/json`.\n\n**Migrating from the legacy API?**\nIf you use the [legacy Outbound Phone Calling API](/api-documentation/outbound-phone-calling-api-legacy), switch to this API by **July 1, 2026**. Your account manager can help with endpoint and testing changes."
  },
  "servers": [
    {
      "url": "https://api.heylibby.com/api/v1",
      "description": "Production"
    }
  ],
  "security": [{ "api_key": [] }],
  "paths": {
    "/outbound/call": {
      "post": {
        "operationId": "initiate-outbound-call",
        "summary": "Initiate outbound call",
        "description": "Schedule a single outbound call for a specific assistant (`agentId`). The call is queued after validation and placed shortly.\n\n**Required headers:** `x-api-key`, `Content-Type: application/json`.\n\n**Required fields**\n- `agentId` — assistant that places and handles the call, can be found in the URL after selecting that assistant.\n- `contact.phoneNumber` — callee number in **E.164** format (e.g. `+15551234567`).\n- **Messaging** — send **both** `introMessage` and `voicemailMessage`, **or** send `callInstructions` alone. You cannot send only one of `introMessage` / `voicemailMessage`.\n\n**Optional fields**\n- `contact.firstName`, `contact.lastName`, `contact.email`; trimmed and used for assistant context.\n- `metadata` — custom key/value pairs (strings, numbers, or booleans) to give the assistant context.\n\n**Assistant requirements**\nThe assistant must exist, belong to your organization (from the API key), be `active`, and have phone enabled and fully configured.",
        "tags": ["Outbound Calling"],
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "enum": ["application/json"]
            },
            "description": "Must be `application/json`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/OutboundCallRequest" },
              "examples": {
                "IntroAndVoicemail": {
                  "summary": "Intro and voicemail messages",
                  "description": "Provide both messages when you want explicit scripts for a human answer and for voicemail.",
                  "value": {
                    "agentId": "your-agent-uuid",
                    "contact": {
                      "phoneNumber": "+15551234567",
                      "firstName": "Jane",
                      "lastName": "Doe",
                      "email": "jane@example.com"
                    },
                    "metadata": {
                      "formLocation": "Ballard",
                      "formGoals": "get in shape",
                      "utmSource": "facebook"
                    },
                    "introMessage": "Hi Jane, this is Libby calling from Acme Fitness, calling you back about your membership inquiry...",
                    "voicemailMessage": "Hi Jane, sorry we missed you. This is Libby from Acme Fitness. Call us back to learn about our May promotion..."
                  }
                },
                "CallInstructions": {
                  "summary": "Call instructions only",
                  "description": "Use when you want the assistant to generate behavior from instructions instead of fixed intro/voicemail scripts.",
                  "value": {
                    "agentId": "your-agent-uuid",
                    "contact": {
                      "phoneNumber": "+15551234567"
                    },
                    "callInstructions": "Follow up about their membership inquiry. Be friendly and brief."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Call accepted and queued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OutboundCallSuccessResponse"
                },
                "examples": {
                  "Queued": {
                    "summary": "Call scheduled",
                    "value": {
                      "success": true,
                      "message": "Your call has been scheduled and will be placed shortly."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — missing/invalid fields, incomplete messaging pair, unsupported campaign mode, or agent phone not active.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OutboundCallErrorResponse"
                },
                "examples": {
                  "MissingAgentId": {
                    "summary": "Missing agentId",
                    "value": { "error": "agentId is required" }
                  },
                  "InvalidPhone": {
                    "summary": "Invalid contact.phoneNumber",
                    "value": {
                      "error": "contact.phoneNumber must be a valid E.164 phone number"
                    }
                  },
                  "IncompleteMessaging": {
                    "summary": "Only one of intro/voicemail",
                    "value": {
                      "error": "introMessage and voicemailMessage must both be provided, or use callInstructions instead"
                    }
                  },
                  "AgentPhoneInactive": {
                    "summary": "Agent phone not active",
                    "value": { "error": "Agent phone status is not active" }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Agent not in your organization (from API key `orgId`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OutboundCallErrorResponse"
                },
                "examples": {
                  "AgentNotInOrg": {
                    "summary": "Agent not in organization",
                    "value": {
                      "error": "Agent does not belong to your organization"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OutboundCallErrorResponse"
                },
                "examples": {
                  "AgentNotFound": {
                    "summary": "Agent not found",
                    "value": { "error": "Agent not found" }
                  }
                }
              }
            }
          }
        },
        "security": [{ "api_key": [] }]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "api_key": {
        "type": "apiKey",
        "name": "x-api-key",
        "in": "header",
        "description": "API key secret from API Key Management. API Gateway validates the key and forwards the request to the outbound service."
      }
    },
    "schemas": {
      "OutboundCallRequest": {
        "type": "object",
        "required": ["agentId", "contact"],
        "properties": {
          "agentId": {
            "type": "string",
            "format": "uuid",
            "description": "Agent that places and handles the call. Required."
          },
          "contact": {
            "$ref": "#/components/schemas/OutboundCallContact"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                { "type": "string" },
                { "type": "number" },
                { "type": "boolean" }
              ]
            },
            "description": "Optional key/value context (e.g. form or UTM fields). Values may be strings, numbers, or booleans."
          },
          "introMessage": {
            "type": "string",
            "description": "Message spoken when a human answers. Must be sent together with `voicemailMessage`, unless you use `callInstructions` instead."
          },
          "voicemailMessage": {
            "type": "string",
            "description": "Message left when voicemail is detected. Must be sent together with `introMessage`, unless you use `callInstructions` instead."
          },
          "callInstructions": {
            "type": "string",
            "description": "Instructions for the call when you are not providing `introMessage` and `voicemailMessage`. Use this option alone; do not send only one of the intro/voicemail pair."
          }
        }
      },
      "OutboundCallContact": {
        "type": "object",
        "required": ["phoneNumber"],
        "properties": {
          "phoneNumber": {
            "type": "string",
            "description": "Callee number in E.164 format (e.g. `+15551234567`).",
            "example": "+15551234567"
          },
          "firstName": {
            "type": "string",
            "description": "Callee first name (trimmed). Used for agent context."
          },
          "lastName": {
            "type": "string",
            "description": "Callee last name (trimmed). Used for agent context."
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Callee email. Used for agent context."
          }
        }
      },
      "OutboundCallSuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether the call was accepted and queued.",
            "example": true
          },
          "message": {
            "type": "string",
            "description": "Human-readable confirmation.",
            "example": "Your call has been scheduled and will be placed shortly."
          }
        }
      },
      "OutboundCallErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable error message."
          }
        }
      }
    }
  }
}
