Checking your session…

Quickstart — Create, Configure, Go Live

The fastest way to understand the platform is to build an assistant end-to-end. The script below creates an assistant for a fictional heating company, teaches it from the company website, and takes it live — the same five-step journey from the welcome page, in about a minute of API calls.

That's a live assistant with a web address. From here you'd give it a phone number (Go Live), connect a calendar (Bookings), and watch the conversations arrive (See What's Happening).

The one concept to internalise before you write real integration code: editing an app changes a draft; taking it live makes those changes real to your callers. Change the prompt, the voice, the branding — nothing your callers experience changes until you take the assistant live again. The rest of this chapter covers the app endpoints in detail.

TOKEN="your_api_token_here"

# 1. Create the app
APP=$(curl -s -X POST https://api.everycallhandled.com/api/v1/apps \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "HVAC Receptionist",
    "attributes": {
      "voiceChatPrompt": "You are the AI receptionist for ABC HVAC. Office hours: Mon-Fri 8am-5pm. Always confirm callback number.",
      "voice": "shimmer",
      "voiceChatEnabled": "true",
      "primaryColor": "#1E3A5F"
    }
  }')
APP_ID=$(echo $APP | jq -r .id)
echo "Created app: $APP_ID"

# 2. Teach it from the company website
JOB=$(curl -s -X POST https://api.everycallhandled.com/api/v1/apps/$APP_ID/knowledge \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "type": "url", "content": "https://abchvac.com/services" }')
JOB_ID=$(echo $JOB | jq -r .jobId)

# Poll until ingestion completes
while true; do
  STATUS=$(curl -s https://api.everycallhandled.com/api/v1/apps/$APP_ID/knowledge/jobs/$JOB_ID \
    -H "Authorization: Bearer $TOKEN" | jq -r .status)
  echo "Knowledge ingest: $STATUS"
  [ "$STATUS" = "completed" ] && break
  [ "$STATUS" = "failed" ] && exit 1
  sleep 3
done

# 3. Take it live
curl -X POST https://api.everycallhandled.com/api/v1/apps/$APP_ID/publish \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "subdomain": "abc-hvac", "userEmail": "owner@abchvac.com" }'

# 4. Verify the live app
curl https://api.everycallhandled.com/api/v1/apps/$APP_ID \
  -H "Authorization: Bearer $TOKEN" | jq '.publishedAppUrl, .attributes.creditBalance'
Sign in to run this against your account.

An app is one assistant: its instructions, voice, knowledge, branding and (once live) its phone number and web address. Most businesses start with one; you can run many.

Requires create_app.

Request:

All attributes are optional at creation — you can set everything later with an update. The full attribute reference is in Make It Yours.

Response (200):

Save the id — you'll need it for all subsequent operations. (Published state and createdByUserId are returned by GET /apps/{id}, not by create.)

Errors:

  • 409 PHONE_NUMBER_IN_USE if attributes.twilioPhoneNumber is already used by another of your apps.
POST/api/v1/appscreate_app
curl -X POST https://api.everycallhandled.com/api/v1/apps \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Customer Support Bot",
    "description": "AI assistant for customer support",
    "attributes": {
      "assistantName": "Support Assistant",
      "welcomeMessage": "Hello! How can I help you today?",
      "primaryColor": "#4F46E5",
      "textColor": "#FFFFFF",
      "voice": "nova",
      "voiceChatPrompt": "You are a helpful customer support assistant."
    }
  }'
Sign in to run this against your account.
JSON
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organisationId": "org-abc123",
  "name": "Customer Support Bot",
  "description": "AI assistant for customer support",
  "attributes": { /* echoed back, normalised */ },
  "chatId": "...",
  "createdAt": "2026-05-10T10:30:00Z",
  "updatedAt": "2026-05-10T10:30:00Z"
}

Requires view_settings.

Query params:

  • publishedtrue, false, or all. If omitted, only published apps are returned (pass all to include drafts).
  • limit (default 50, max 200), offset (pagination)

Response (200):

The response is filtered to your account: you see your own apps and those of any customer accounts beneath yours (see For Partners). Credit balances shown for live assistants are always current.

GET/api/v1/apps?published=all&limit=50&offset=0view_settings
JSON
{
  "apps": [ /* array of app objects (same shape as GET /apps/{id}) */ ],
  "isAdmin": false,
  "pagination": { "total": 17, "limit": 50, "offset": 0, "hasMore": false, "nextOffset": null }
}

Available to any signed-in member of the account that owns the app.

Response (200):

hasPendingPublish is true when the app has draft changes that aren't live yet; pendingPublishAttrIds lists which attributes are waiting. Use these to drive an "Apply your changes" prompt in your own UI.

Errors:

  • 404 APP_NOT_FOUND — the app doesn't exist OR your token can't access it (deliberately the same error to avoid existence leaks).
GET/api/v1/apps/{appId}
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.
JSON
{
  "id": "550e8400-...",
  "name": "Customer Support Bot",
  "description": "...",
  "attributes": { /* full attribute set; balances and usage totals are always current live values */ },
  "createdByUserId": "...",
  "isPublished": true,
  "publishedAppUrl": "https://support.app.everycallhandled.com",
  "subdomain": "support",
  "hasPendingPublish": false,
  "pendingPublishAttrIds": [],
  "createdAt": "...",
  "updatedAt": "..."
}

Requires edit_settings.

PATCH semantics — only fields you supply are changed. Updates are draft changes: take the assistant live again to apply them (see Go Live).

PATCH/api/v1/apps/{appId}edit_settings
curl -X PATCH https://api.everycallhandled.com/api/v1/apps/$APP_ID \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Renamed app",
    "attributes": {
      "voiceChatPrompt": "Updated prompt...",
      "voice": "ballad"
    }
  }'
Sign in to run this against your account.

Requires edit_settings. Permanently removes the app together with its knowledge, conversations and billing history. If the app was live, its site is taken down too. This cannot be undone.

DELETE/api/v1/apps/{appId}edit_settings
curl -X DELETE 'https://api.everycallhandled.com/api/v1/apps/{appId}' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Copy-only. DELETE is destructive — run it from your own terminal with the sample above, not from the docs.

Requires clone_app.

The duplicate inherits the prompt, tools, voice configuration and billing mode. It does not inherit the phone number, live state or credit balance. Duplicating an app is the safe way to experiment with big changes without touching the assistant your callers are using.


POST/api/v1/apps/{appId}/cloneclone_app
curl -X POST https://api.everycallhandled.com/api/v1/apps/$APP_ID/clone \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{ "name": "Copy of My App" }'
Sign in to run this against your account.