Heppu APIv2.heppu.ai/api

Create and change workers

The older /v1 agent endpoints. Key only, no role check.

List

GET/api/v1/agents
typevoice | chat
Filter by type.
statusstring
Filter by status, exact match.
limitint
No upper bound. Be reasonable.default 50
offsetint
default 0

Response is data.agents[] with id, name, type, status, model, instructions, tools[], config, createdAt, updatedAt, plus phoneNumbers on voice workers. tools[] items are { id, name, description }.

pagination.total here is the page size, not the collection size. hasMore is agents.length === limit. Page until it's false.

Create

POST/api/v1/agents
namestringrequired
typevoice | chatrequired
Can't change later.
modelstring
gpt-realtime-2.1 for voice, gpt-5.6-terra for chat.default per type
instructionsstring
The system prompt.default ""
configobject
Free-form. Voice settings, goal, webhooks live here.default {}
toolIdsstring[]
Unknown ids are dropped silently.
curl -X POST https://v2.heppu.ai/api/v1/agents \
  -H "x-api-key: hep_..." -H "Content-Type: application/json" \
  -d '{"name":"Support chat","type":"chat","instructions":"You help with orders."}'

201 with id, name, type, model, instructions, status, config, createdAt. Status is always active on create.

Read one

GET/api/v1/agents/{agentId}

Same fields as list, but tools[] items also carry category and config. 404 if the id isn't yours.

Update

PATCH/api/v1/agents/{agentId}

Send only what changes. Every field optional: name, status, model, instructions, config, toolIds. An empty toolIds: [] removes all tools. Changing instructions creates a prompt version, so the dashboard history stays intact.

{ "data": { "id": "…", "updated": true }, "meta": { "message": "Agent updated successfully", "timestamp": "…" } }

Deactivate

DELETE/api/v1/agents/{agentId}

Soft. Sets status to inactive. Conversations and history stay. Response says deleted: true for historical reasons. Flip it back with a PATCH { "status": "active" }.

On this page