{
  "openapi": "3.0.3",
  "info": {
    "title": "hiSocial Voice Broadcast API",
    "version": "1.0.0",
    "description": "REST API to place WhatsApp voice calls from your own number, run bulk voice campaigns, manage contacts and pull delivery reports.\n\nGet an API key from **My Account → Developer API** at https://app.hisocial.in/account. Rate limit: 60 requests/min per key. Full guide: https://app.hisocial.in/api-docs.html",
    "contact": {
      "name": "hiSocial",
      "url": "https://app.hisocial.in/api-docs.html"
    }
  },
  "servers": [
    {
      "url": "https://vapi.hisocial.in/api",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Account"
    },
    {
      "name": "Voice calls"
    },
    {
      "name": "Campaigns"
    },
    {
      "name": "Contacts"
    },
    {
      "name": "Reports"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Send your API key as: Authorization: Bearer hs_live_..."
      },
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Alternative: X-API-Key: hs_live_..."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing, invalid or revoked API key.",
        "content": {
          "application/json": {
            "example": {
              "message": "Invalid or revoked API key."
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded (60/min). See Retry-After header.",
        "content": {
          "application/json": {
            "example": {
              "message": "Rate limit exceeded — max 60 requests per minute per key."
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found or not owned by your account.",
        "content": {
          "application/json": {
            "example": {
              "message": "Not found."
            }
          }
        }
      },
      "BadRequest": {
        "description": "A required field is missing or invalid.",
        "content": {
          "application/json": {
            "example": {
              "message": "Enter a phone number."
            }
          }
        }
      }
    },
    "schemas": {
      "Device": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 12
          },
          "name": {
            "type": "string",
            "example": "Sales line"
          },
          "session_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "example": "connected"
          },
          "live": {
            "type": "string",
            "example": "open"
          }
        }
      },
      "Campaign": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 31
          },
          "name": {
            "type": "string",
            "example": "Diwali offer"
          },
          "voice_type": {
            "type": "string",
            "example": "tts"
          },
          "status": {
            "type": "string",
            "example": "running"
          },
          "group_id": {
            "type": "integer",
            "example": 7
          },
          "device_id": {
            "type": "integer",
            "example": 12
          }
        }
      },
      "Group": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 7
          },
          "name": {
            "type": "string",
            "example": "Delhi leads"
          },
          "description": {
            "type": "string"
          },
          "contactCount": {
            "type": "integer",
            "example": 1240
          }
        }
      },
      "Contact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 5501
          },
          "name": {
            "type": "string",
            "example": "Rahul"
          },
          "phone": {
            "type": "string",
            "example": "919812345678"
          }
        }
      },
      "Call": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 88213
          },
          "phone_number": {
            "type": "string",
            "example": "919812345678"
          },
          "status": {
            "type": "string",
            "example": "completed"
          },
          "duration_seconds": {
            "type": "integer",
            "example": 42
          },
          "campaign_name": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "example": "2026-09-20 11:04:00"
          }
        }
      }
    }
  },
  "paths": {
    "/v1/credits": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Credit balance",
        "description": "Returns your voice-credit balance.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "credits": 4820
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/devices": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "List devices",
        "description": "Your connected WhatsApp devices.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "devices": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Device"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/call": {
      "post": {
        "tags": [
          "Voice calls"
        ],
        "summary": "Place a call",
        "description": "Place one voice call. Returns dialId & callId; the call runs asynchronously.",
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "example": {
                  "dialId": "f3a9c1e2-…",
                  "callId": 88213
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "deviceId": 12,
                "phone": "919812345678",
                "mode": "tts",
                "ttsText": "Namaste! Aapka order ship ho gaya.",
                "language": "hi-IN"
              }
            }
          }
        }
      }
    },
    "/v1/call/{dialId}/status": {
      "get": {
        "tags": [
          "Voice calls"
        ],
        "summary": "Call status",
        "description": "Is a placed call still active?",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "active": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "dialId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "dialId from Place a call",
            "example": "f3a9c1e2-…"
          }
        ]
      }
    },
    "/v1/call/{dialId}/hangup": {
      "post": {
        "tags": [
          "Voice calls"
        ],
        "summary": "Hang up",
        "description": "End an in-progress call immediately.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "ok": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "dialId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "dialId from Place a call",
            "example": "f3a9c1e2-…"
          }
        ]
      }
    },
    "/v1/campaigns": {
      "get": {
        "tags": [
          "Campaigns"
        ],
        "summary": "List campaigns",
        "description": "All your campaigns, newest first.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaigns": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Campaign"
                      }
                    },
                    "voiceReady": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Create campaign",
        "description": "Create a bulk voice campaign (draft). Start it to begin dialing.",
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaign": {
                      "$ref": "#/components/schemas/Campaign"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "Diwali offer",
                "deviceId": 12,
                "groupId": 7,
                "voiceType": "tts",
                "ttsText": "Diwali par 20% off!",
                "ttsLanguage": "hi-IN",
                "delayBetweenCalls": 8
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{id}/start": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Start campaign",
        "description": "Begin dialing the campaign's contact group.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "message": "Campaign started"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Campaign id",
            "example": "31"
          }
        ]
      }
    },
    "/v1/campaigns/{id}/stop": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Stop campaign",
        "description": "Stop a running campaign.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "message": "Campaign stopped"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Campaign id",
            "example": "31"
          }
        ]
      }
    },
    "/v1/contact-groups": {
      "get": {
        "tags": [
          "Contacts"
        ],
        "summary": "List contact groups",
        "description": "Your contact groups with a live count.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "groups": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Group"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "tags": [
          "Contacts"
        ],
        "summary": "Create group",
        "description": "Create a contact group.",
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "group": {
                      "$ref": "#/components/schemas/Group"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "Mumbai leads",
                "description": "Q3 imports"
              }
            }
          }
        }
      }
    },
    "/v1/contact-groups/{groupId}/contacts": {
      "get": {
        "tags": [
          "Contacts"
        ],
        "summary": "Group contacts",
        "description": "All contacts in a group.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "group": {
                      "$ref": "#/components/schemas/Group"
                    },
                    "contacts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Group id",
            "example": "7"
          }
        ]
      }
    },
    "/v1/reports/summary": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Report summary",
        "description": "Aggregated call stats with optional date range.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "range": {
                    "from": "2026-09-01",
                    "to": "2026-09-30"
                  },
                  "total": 1740,
                  "completed": 1215,
                  "creditsUsed": 1215,
                  "creditsRefunded": 525,
                  "totalDurationSeconds": 38210,
                  "byStatus": [
                    {
                      "status": "completed",
                      "count": 1215
                    },
                    {
                      "status": "no_answer",
                      "count": 340
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Start date YYYY-MM-DD",
            "example": "2026-09-01"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "End date YYYY-MM-DD",
            "example": "2026-09-30"
          }
        ]
      }
    },
    "/v1/calls": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Call list",
        "description": "Your most recent calls (up to 500).",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "calls": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Call"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/calls/{id}": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Single call",
        "description": "Full detail for one call incl. transcription & replies.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "call": {
                    "id": 88213,
                    "status": "completed",
                    "duration_seconds": 42,
                    "transcription": "Agent: Namaste…",
                    "replies": [
                      {
                        "body": "Yes, interested",
                        "wa_timestamp": "…"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Call id",
            "example": "88213"
          }
        ]
      }
    },
    "/v1/calls/export": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Export calls (Excel)",
        "description": "Download all calls as an Excel .xlsx file.",
        "responses": {
          "200": {
            "description": "Excel file",
            "content": {
              "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/audio": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Push audio (mp3 link)",
        "description": "Import a public mp3/audio link into your account; returns a local audioUrl for use in an audio campaign. Max 25 MB.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "url": "https://cdn.example.com/promo.mp3"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Imported",
            "content": {
              "application/json": {
                "example": {
                  "audioUrl": "/uploads/voice_8f2c….mp3",
                  "bytes": 184320,
                  "contentType": "audio/mpeg"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/campaigns/{id}/duplicate": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Duplicate campaign",
        "description": "Duplicate a campaign as a fresh draft (same settings, no call history).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "31"
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "example": {
                  "campaign": {
                    "id": 53,
                    "name": "Diwali offer (copy)",
                    "status": "draft"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/campaigns/{id}/analytics": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Campaign analytics",
        "description": "Delivery & credit analytics for one campaign.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "31"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "total": 1740,
                  "completed": 1215,
                  "answerRate": 70,
                  "creditsUsed": 1215,
                  "creditsRefunded": 525,
                  "avgDurationSeconds": 31,
                  "byStatus": [
                    {
                      "status": "completed",
                      "count": 1215
                    }
                  ],
                  "byHour": [
                    {
                      "hour": 11,
                      "total": 300,
                      "completed": 240
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  }
}